[PATCH] D87146: [analyzer] Implement shared semantics checks for XNU functions in PthreadLockChecker
ASDenysPetrov updated this revision to Diff 290131. ASDenysPetrov added a comment. Fixed some missed conditions. Added more tests. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87146/new/ https://reviews.llvm.org/D87146 Files: clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h clang/test/Analysis/pthreadlock.c Index: clang/test/Analysis/pthreadlock.c === --- clang/test/Analysis/pthreadlock.c +++ clang/test/Analysis/pthreadlock.c @@ -242,6 +242,16 @@ pthread_mutex_destroy(&local_mtx); } +void ok32(void) { + if (lck_rw_try_lock_exclusive(&rw) != 0) // no-warning +lck_rw_unlock_exclusive(&rw); // no-warning +} + +void ok33(void) { + if (lck_rw_try_lock_shared(&rw) != 0) // no-warning +lck_rw_lock_shared(&rw);// no-warning +} + void bad1(void) { @@ -502,14 +512,47 @@ } void bad32(void) { + pthread_mutex_lock(pmtx); + fake_system_function(); + pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} +} + +void bad33(void) { lck_rw_lock_shared(&rw); - lck_rw_unlock_exclusive(&rw); // FIXME: warn - should be shared? + lck_rw_lock_shared(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad34(void) { lck_rw_lock_exclusive(&rw); - lck_rw_unlock_shared(&rw); // FIXME: warn - should be exclusive? + lck_rw_lock_exclusive(&rw); // expected-warning{{This lock has already been acquired}} } -void bad33(void) { - pthread_mutex_lock(pmtx); - fake_system_function(); - pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} +void bad35(void) { + lck_rw_lock_exclusive(&rw); + lck_rw_lock_shared(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad36(void) { + lck_rw_lock_shared(&rw); + lck_rw_lock_exclusive(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad37(void) { + lck_rw_lock_exclusive(&rw); + lck_rw_unlock_shared(&rw); // expected-warning{{This lock has been acquired exclusively, but shared unlock used}} +} + +void bad38(void) { + lck_rw_lock_shared(&rw); + lck_rw_unlock_exclusive(&rw); // expected-warning{{This lock has been acquired as shared, but exclusive unlock used}} +} + +void bad39(void) { + if (lck_rw_try_lock_exclusive(&rw) != 0) // no-warning +lck_rw_unlock_shared(&rw); // expected-warning{{This lock has been acquired exclusively, but shared unlock used}} +} + +void bad40(void) { + if (lck_rw_try_lock_shared(&rw) != 0) // no-warning +lck_rw_unlock_exclusive(&rw); // expected-warning{{This lock has been acquired as shared, but exclusive unlock used}} } Index: clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h === --- clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h +++ clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h @@ -19,6 +19,7 @@ void *foo; } lck_rw_t; +typedef pthread_mutex_t lck_mtx_t; typedef pthread_mutex_t lck_mtx_t; extern void fake_system_function(); @@ -34,6 +35,8 @@ extern void lck_mtx_lock(lck_mtx_t *); extern void lck_mtx_unlock(lck_mtx_t *); extern boolean_t lck_mtx_try_lock(lck_mtx_t *); +extern boolean_t lck_rw_try_lock_shared(lck_rw_t *lck); +extern boolean_t lck_rw_try_lock_exclusive(lck_rw_t *lck); extern void lck_mtx_destroy(lck_mtx_t *lck, lck_grp_t *grp); extern void lck_rw_lock_exclusive(lck_rw_t *lck); Index: clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp === --- clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -33,7 +33,9 @@ enum Kind { Destroyed, Locked, +SharedLocked, Unlocked, +SharedUnlocked, UntouchedAndPossiblyDestroyed, UnlockedAndPossiblyDestroyed } K; @@ -43,7 +45,9 @@ public: static LockState getLocked() { return LockState(Locked); } + static LockState getSharedLocked() { return LockState(SharedLocked); } static LockState getUnlocked() { return LockState(Unlocked); } + static LockState getSharedUnlocked() { return LockState(SharedUnlocked); } static LockState getDestroyed() { return LockState(Destroyed); } static LockState getUntouchedAndPossiblyDestroyed() { return LockState(UntouchedAndPossiblyDestroyed); @@ -55,7 +59,11 @@ bool operator==(const LockState &X) const { return K == X.K; } bool isLocked() const { return K == Locked; } + bool isSharedLocked() const { return K == SharedLocked; } + bool isAnyLocked() const { return isLocked() || isSharedLocked(); } bool isUnlocked() const { return K == Unlocked; } + bool isSharedUnlocked() const { return K == SharedUnlocked; } + bool isAnyUnlocked() const { return isUnlocked() || i
[PATCH] D87146: [analyzer] Implement shared semantics checks for XNU functions in PthreadLockChecker
ASDenysPetrov updated this revision to Diff 290133. ASDenysPetrov added a comment. Minor fixes. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87146/new/ https://reviews.llvm.org/D87146 Files: clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h clang/test/Analysis/pthreadlock.c Index: clang/test/Analysis/pthreadlock.c === --- clang/test/Analysis/pthreadlock.c +++ clang/test/Analysis/pthreadlock.c @@ -242,6 +242,16 @@ pthread_mutex_destroy(&local_mtx); } +void ok32(void) { + if (lck_rw_try_lock_exclusive(&rw) != 0) // no-warning +lck_rw_unlock_exclusive(&rw); // no-warning +} + +void ok33(void) { + if (lck_rw_try_lock_shared(&rw) != 0) // no-warning +lck_rw_lock_shared(&rw);// no-warning +} + void bad1(void) { @@ -502,14 +512,47 @@ } void bad32(void) { + pthread_mutex_lock(pmtx); + fake_system_function(); + pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} +} + +void bad33(void) { lck_rw_lock_shared(&rw); - lck_rw_unlock_exclusive(&rw); // FIXME: warn - should be shared? + lck_rw_lock_shared(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad34(void) { lck_rw_lock_exclusive(&rw); - lck_rw_unlock_shared(&rw); // FIXME: warn - should be exclusive? + lck_rw_lock_exclusive(&rw); // expected-warning{{This lock has already been acquired}} } -void bad33(void) { - pthread_mutex_lock(pmtx); - fake_system_function(); - pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} +void bad35(void) { + lck_rw_lock_exclusive(&rw); + lck_rw_lock_shared(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad36(void) { + lck_rw_lock_shared(&rw); + lck_rw_lock_exclusive(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad37(void) { + lck_rw_lock_exclusive(&rw); + lck_rw_unlock_shared(&rw); // expected-warning{{This lock has been acquired exclusively, but shared unlock used}} +} + +void bad38(void) { + lck_rw_lock_shared(&rw); + lck_rw_unlock_exclusive(&rw); // expected-warning{{This lock has been acquired as shared, but exclusive unlock used}} +} + +void bad39(void) { + if (lck_rw_try_lock_exclusive(&rw) != 0) // no-warning +lck_rw_unlock_shared(&rw); // expected-warning{{This lock has been acquired exclusively, but shared unlock used}} +} + +void bad40(void) { + if (lck_rw_try_lock_shared(&rw) != 0) // no-warning +lck_rw_unlock_exclusive(&rw); // expected-warning{{This lock has been acquired as shared, but exclusive unlock used}} } Index: clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h === --- clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h +++ clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h @@ -34,6 +34,8 @@ extern void lck_mtx_lock(lck_mtx_t *); extern void lck_mtx_unlock(lck_mtx_t *); extern boolean_t lck_mtx_try_lock(lck_mtx_t *); +extern boolean_t lck_rw_try_lock_shared(lck_rw_t *); +extern boolean_t lck_rw_try_lock_exclusive(lck_rw_t *); extern void lck_mtx_destroy(lck_mtx_t *lck, lck_grp_t *grp); extern void lck_rw_lock_exclusive(lck_rw_t *lck); Index: clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp === --- clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -33,7 +33,9 @@ enum Kind { Destroyed, Locked, +SharedLocked, Unlocked, +SharedUnlocked, UntouchedAndPossiblyDestroyed, UnlockedAndPossiblyDestroyed } K; @@ -43,7 +45,9 @@ public: static LockState getLocked() { return LockState(Locked); } + static LockState getSharedLocked() { return LockState(SharedLocked); } static LockState getUnlocked() { return LockState(Unlocked); } + static LockState getSharedUnlocked() { return LockState(SharedUnlocked); } static LockState getDestroyed() { return LockState(Destroyed); } static LockState getUntouchedAndPossiblyDestroyed() { return LockState(UntouchedAndPossiblyDestroyed); @@ -55,7 +59,11 @@ bool operator==(const LockState &X) const { return K == X.K; } bool isLocked() const { return K == Locked; } + bool isSharedLocked() const { return K == SharedLocked; } + bool isAnyLocked() const { return isLocked() || isSharedLocked(); } bool isUnlocked() const { return K == Unlocked; } + bool isSharedUnlocked() const { return K == SharedUnlocked; } + bool isAnyUnlocked() const { return isUnlocked() || isSharedUnlocked(); } bool isDestroyed() const { return K == Destroyed; } bool isUntouchedAndPossiblyDestroyed() const { return K == UntouchedAndPossiblyDestroyed; @@ -99,7 +107,7 @@
[PATCH] D87146: [analyzer] Implement shared semantics checks for XNU functions in PthreadLockChecker
ASDenysPetrov updated this revision to Diff 290134. ASDenysPetrov added a comment. Test fix. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87146/new/ https://reviews.llvm.org/D87146 Files: clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h clang/test/Analysis/pthreadlock.c Index: clang/test/Analysis/pthreadlock.c === --- clang/test/Analysis/pthreadlock.c +++ clang/test/Analysis/pthreadlock.c @@ -242,6 +242,16 @@ pthread_mutex_destroy(&local_mtx); } +void ok32(void) { + if (lck_rw_try_lock_exclusive(&rw) != 0) // no-warning +lck_rw_unlock_exclusive(&rw); // no-warning +} + +void ok33(void) { + if (lck_rw_try_lock_shared(&rw) != 0) // no-warning +lck_rw_unlock_shared(&rw); // no-warning +} + void bad1(void) { @@ -502,14 +512,47 @@ } void bad32(void) { + pthread_mutex_lock(pmtx); + fake_system_function(); + pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} +} + +void bad33(void) { lck_rw_lock_shared(&rw); - lck_rw_unlock_exclusive(&rw); // FIXME: warn - should be shared? + lck_rw_lock_shared(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad34(void) { lck_rw_lock_exclusive(&rw); - lck_rw_unlock_shared(&rw); // FIXME: warn - should be exclusive? + lck_rw_lock_exclusive(&rw); // expected-warning{{This lock has already been acquired}} } -void bad33(void) { - pthread_mutex_lock(pmtx); - fake_system_function(); - pthread_mutex_lock(pmtx); // expected-warning{{This lock has already been acquired}} +void bad35(void) { + lck_rw_lock_exclusive(&rw); + lck_rw_lock_shared(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad36(void) { + lck_rw_lock_shared(&rw); + lck_rw_lock_exclusive(&rw); // expected-warning{{This lock has already been acquired}} +} + +void bad37(void) { + lck_rw_lock_exclusive(&rw); + lck_rw_unlock_shared(&rw); // expected-warning{{This lock has been acquired exclusively, but shared unlock used}} +} + +void bad38(void) { + lck_rw_lock_shared(&rw); + lck_rw_unlock_exclusive(&rw); // expected-warning{{This lock has been acquired as shared, but exclusive unlock used}} +} + +void bad39(void) { + if (lck_rw_try_lock_exclusive(&rw) != 0) // no-warning +lck_rw_unlock_shared(&rw); // expected-warning{{This lock has been acquired exclusively, but shared unlock used}} +} + +void bad40(void) { + if (lck_rw_try_lock_shared(&rw) != 0) // no-warning +lck_rw_unlock_exclusive(&rw); // expected-warning{{This lock has been acquired as shared, but exclusive unlock used}} } Index: clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h === --- clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h +++ clang/test/Analysis/Inputs/system-header-simulator-for-pthread-lock.h @@ -34,6 +34,8 @@ extern void lck_mtx_lock(lck_mtx_t *); extern void lck_mtx_unlock(lck_mtx_t *); extern boolean_t lck_mtx_try_lock(lck_mtx_t *); +extern boolean_t lck_rw_try_lock_shared(lck_rw_t *); +extern boolean_t lck_rw_try_lock_exclusive(lck_rw_t *); extern void lck_mtx_destroy(lck_mtx_t *lck, lck_grp_t *grp); extern void lck_rw_lock_exclusive(lck_rw_t *lck); Index: clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp === --- clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -33,7 +33,9 @@ enum Kind { Destroyed, Locked, +SharedLocked, Unlocked, +SharedUnlocked, UntouchedAndPossiblyDestroyed, UnlockedAndPossiblyDestroyed } K; @@ -43,7 +45,9 @@ public: static LockState getLocked() { return LockState(Locked); } + static LockState getSharedLocked() { return LockState(SharedLocked); } static LockState getUnlocked() { return LockState(Unlocked); } + static LockState getSharedUnlocked() { return LockState(SharedUnlocked); } static LockState getDestroyed() { return LockState(Destroyed); } static LockState getUntouchedAndPossiblyDestroyed() { return LockState(UntouchedAndPossiblyDestroyed); @@ -55,7 +59,11 @@ bool operator==(const LockState &X) const { return K == X.K; } bool isLocked() const { return K == Locked; } + bool isSharedLocked() const { return K == SharedLocked; } + bool isAnyLocked() const { return isLocked() || isSharedLocked(); } bool isUnlocked() const { return K == Unlocked; } + bool isSharedUnlocked() const { return K == SharedUnlocked; } + bool isAnyUnlocked() const { return isUnlocked() || isSharedUnlocked(); } bool isDestroyed() const { return K == Destroyed; } bool isUntouchedAndPossiblyDestroyed() const { return K == UntouchedAndPossiblyDestroyed; @@ -99,7 +107,7 @@ {{
[clang] 4d0312c - Add proper move ctor/move assign to APValue. NFCI.
Author: Benjamin Kramer Date: 2020-09-06T13:02:11+02:00 New Revision: 4d0312c8e05be5353c6c29b31036647dceca3ce5 URL: https://github.com/llvm/llvm-project/commit/4d0312c8e05be5353c6c29b31036647dceca3ce5 DIFF: https://github.com/llvm/llvm-project/commit/4d0312c8e05be5353c6c29b31036647dceca3ce5.diff LOG: Add proper move ctor/move assign to APValue. NFCI. Swapping 64 bytes to make a move isn't cheap. Added: Modified: clang/include/clang/AST/APValue.h clang/lib/AST/APValue.cpp Removed: diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 87e4bd7f84c1..5103cfa8604e 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -304,7 +304,7 @@ class APValue { MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); } APValue(const APValue &RHS); - APValue(APValue &&RHS) : Kind(None) { swap(RHS); } + APValue(APValue &&RHS); APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr = false) : Kind(None) { @@ -339,6 +339,9 @@ class APValue { return Result; } + APValue &operator=(const APValue &RHS); + APValue &operator=(APValue &&RHS); + ~APValue() { if (Kind != None && Kind != Indeterminate) DestroyDataAndMakeUninit(); @@ -591,12 +594,6 @@ class APValue { ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr; } - /// Assign by swapping from a copy of the RHS. - APValue &operator=(APValue RHS) { -swap(RHS); -return *this; - } - private: void DestroyDataAndMakeUninit(); void MakeInt() { diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 2a8834b4db0c..08ae0ff3c67d 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -304,6 +304,25 @@ APValue::APValue(const APValue &RHS) : Kind(None) { } } +APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) { + RHS.Kind = None; +} + +APValue &APValue::operator=(const APValue &RHS) { + if (this != &RHS) +*this = APValue(RHS); + return *this; +} + +APValue &APValue::operator=(APValue &&RHS) { + if (Kind != None && Kind != Indeterminate) +DestroyDataAndMakeUninit(); + Kind = RHS.Kind; + Data = RHS.Data; + RHS.Kind = None; + return *this; +} + void APValue::DestroyDataAndMakeUninit() { if (Kind == Int) ((APSInt*)(char*)Data.buffer)->~APSInt(); @@ -372,10 +391,7 @@ bool APValue::needsCleanup() const { void APValue::swap(APValue &RHS) { std::swap(Kind, RHS.Kind); - char TmpData[DataSize]; - memcpy(TmpData, Data.buffer, DataSize); - memcpy(Data.buffer, RHS.Data.buffer, DataSize); - memcpy(RHS.Data.buffer, TmpData, DataSize); + std::swap(Data, RHS.Data); } static double GetApproxValue(const llvm::APFloat &F) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D85984: [analyzer] Add a new checker alpha.cplusplus.CPlusPlus11Lock
ASDenysPetrov updated this revision to Diff 290135. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D85984/new/ https://reviews.llvm.org/D85984 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp clang/test/Analysis/Checkers/CPlusPlus11LockChecker.cpp Index: clang/test/Analysis/Checkers/CPlusPlus11LockChecker.cpp === --- /dev/null +++ clang/test/Analysis/Checkers/CPlusPlus11LockChecker.cpp @@ -0,0 +1, @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.CPlusPlus11Lock -verify %s + +namespace std { + +namespace chrono { +using duration = int; +using time_point = int; +} // namespace chrono + +struct mutex { + void lock(); + bool try_lock(); + void unlock(); +}; + +struct timed_mutex { + void lock(); + bool try_lock(); + bool try_lock_for(std::chrono::duration); + bool try_lock_until(std::chrono::time_point); + void unlock(); +}; + +struct recursive_mutex { + void lock(); + bool try_lock(); + void unlock(); +}; + +struct recursive_timed_mutex { + void lock(); + bool try_lock(); + bool try_lock_for(std::chrono::duration); + bool try_lock_until(std::chrono::time_point); + void unlock(); +}; + +struct shared_mutex { + void lock(); + bool try_lock(); + void unlock(); + void lock_shared(); + bool try_lock_shared(); + void unlock_shared(); +}; + +struct shared_timed_mutex { + void lock(); + bool try_lock(); + bool try_lock_for(std::chrono::duration); + bool try_lock_until(std::chrono::time_point); + void unlock(); + void lock_shared(); + bool try_lock_shared(); + bool try_lock_shared_for(std::chrono::duration); + bool try_lock_shared_until(std::chrono::time_point); + void unlock_shared(); +}; + +template +struct lock_guard { + T &t; + lock_guard(T &m) : t(m) { +t.lock(); + } + ~lock_guard() { +t.unlock(); + } +}; + +template +struct shared_lock { + T &t; + shared_lock(T &m) : t(m) { +t.lock_shared(); + } + ~shared_lock() { +t.unlock_shared(); + } +}; +} // namespace std + +std::mutex m1; +std::mutex m2; + +// mutex ok + +void m_ok1() { + m1.lock(); // no-warning +} + +void m_ok2() { + m1.unlock(); // no-warning +} + +void m_ok3() { + m1.lock(); // no-warning + m1.unlock(); // no-warning +} + +void m_ok4() { + m1.lock(); // no-warning + m1.unlock(); // no-warning + m1.lock(); // no-warning + m1.unlock(); // no-warning +} + +void m_ok5() { + m1.lock(); // no-warning + m1.unlock(); // no-warning + m2.lock(); // no-warning + m2.unlock(); // no-warning +} + +void m_ok6(void) { + m1.lock(); // no-warning + m2.lock(); // no-warning + m2.unlock(); // no-warning + m1.unlock(); // no-warning +} + +void m_ok7(void) { + if (m1.try_lock()) // no-warning +m1.unlock(); // no-warning +} + +void m_ok8(void) { + m1.unlock(); // no-warning + if (m1.try_lock()) // no-warning +m1.unlock(); // no-warning +} + +void m_ok9(void) { + if (!m1.try_lock()) // no-warning +m1.lock();// no-warning + m1.unlock();// no-warning +} + +void m_ok10() { + std::lock_guard gl(m1); // no-warning +} + +// mutex bad + +void m_bad1() { + m1.lock(); // no-warning + m1.lock(); // expected-warning{{This lock has already been acquired}} +} + +void m_bad2() { + m1.lock(); // no-warning + m1.unlock(); // no-warning + m1.unlock(); // expected-warning {{This lock has already been unlocked}} +} + +void m_bad3() { + m1.lock(); // no-warning + m2.lock(); // no-warning + m1.unlock(); // expected-warning {{This was not the most recently acquired lock. Possible lock order reversal}} + m2.unlock(); // no-warning +} + +void m_bad5() { + while (true) +m1.unlock(); // expected-warning {{This lock has already been unlocked}} +} + +void m_bad6() { + while (true) +m1.lock(); // expected-warning{{This lock has already been acquired}} +} + +void m_bad7() { + if (m1.try_lock()) // no-warning +m1.lock(); // expected-warning{{This lock has already been acquired}} +} + +std::timed_mutex tm1; +std::timed_mutex tm2; + +// timed_mutex ok + +void tm_ok1() { + tm1.lock(); // no-warning +} + +void tm_ok2() { + tm1.unlock(); // no-warning +} + +void tm_ok3() { + tm1.lock(); // no-warning + tm1.unlock(); // no-warning +} + +void tm_ok4() { + tm1.lock(); // no-warning + tm1.unlock(); // no-warning + tm1.lock(); // no-warning + tm1.unlock(); // no-warning +} + +void tm_ok5() { + tm1.lock(); // no-warning + tm1.unlock(); // no-warning + tm2.lock(); // no-warning + tm2.unlock(); // no-warning +} + +void tm_ok6(void) { + tm1.lock(); // no-warning + tm2.lock(); // no-warning + tm2.unlock(); // no-warning + tm1.unlock(); // no-warning +} + +void tm_ok7(void) { + if (tm1.try_lock()) // no-warning +tm1.unlock(); // no-warning +} + +void tm_ok8(void) { + tm1.unlock(); // no-warning + if (tm1.try_lock()) // no-warning +t
[clang] 667e800 - [ARM] Remove -O3 from mve intrinsic tests. NFC
Author: David Green Date: 2020-09-06T13:19:55+01:00 New Revision: 667e800bb3a8c1bdda0cabad7549c766b3424064 URL: https://github.com/llvm/llvm-project/commit/667e800bb3a8c1bdda0cabad7549c766b3424064 DIFF: https://github.com/llvm/llvm-project/commit/667e800bb3a8c1bdda0cabad7549c766b3424064.diff LOG: [ARM] Remove -O3 from mve intrinsic tests. NFC Added: Modified: clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c clang/test/CodeGen/arm-mve-intrinsics/vminaq.c clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c clang/test/CodeGen/arm-mve-intrinsics/vminq.c Removed: diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c index 03ab37474ba0..a656657b6619 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O3 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s #include @@ -9,8 +9,8 @@ // CHECK-NEXT:[[TMP0:%.*]] = icmp slt <16 x i8> [[B:%.*]], zeroinitializer // CHECK-NEXT:[[TMP1:%.*]] = sub <16 x i8> zeroinitializer, [[B]] // CHECK-NEXT:[[TMP2:%.*]] = select <16 x i1> [[TMP0]], <16 x i8> [[TMP1]], <16 x i8> [[B]] -// CHECK-NEXT:[[TMP3:%.*]] = icmp ugt <16 x i8> [[TMP2]], [[A:%.*]] -// CHECK-NEXT:[[TMP4:%.*]] = select <16 x i1> [[TMP3]], <16 x i8> [[TMP2]], <16 x i8> [[A]] +// CHECK-NEXT:[[TMP3:%.*]] = icmp uge <16 x i8> [[A:%.*]], [[TMP2]] +// CHECK-NEXT:[[TMP4:%.*]] = select <16 x i1> [[TMP3]], <16 x i8> [[A]], <16 x i8> [[TMP2]] // CHECK-NEXT:ret <16 x i8> [[TMP4]] // uint8x16_t test_vmaxaq_s8(uint8x16_t a, int8x16_t b) @@ -27,8 +27,8 @@ uint8x16_t test_vmaxaq_s8(uint8x16_t a, int8x16_t b) // CHECK-NEXT:[[TMP0:%.*]] = icmp slt <8 x i16> [[B:%.*]], zeroinitializer // CHECK-NEXT:[[TMP1:%.*]] = sub <8 x i16> zeroinitializer, [[B]] // CHECK-NEXT:[[TMP2:%.*]] = select <8 x i1> [[TMP0]], <8 x i16> [[TMP1]], <8 x i16> [[B]] -// CHECK-NEXT:[[TMP3:%.*]] = icmp ugt <8 x i16> [[TMP2]], [[A:%.*]] -// CHECK-NEXT:[[TMP4:%.*]] = select <8 x i1> [[TMP3]], <8 x i16> [[TMP2]], <8 x i16> [[A]] +// CHECK-NEXT:[[TMP3:%.*]] = icmp uge <8 x i16> [[A:%.*]], [[TMP2]] +// CHECK-NEXT:[[TMP4:%.*]] = select <8 x i1> [[TMP3]], <8 x i16> [[A]], <8 x i16> [[TMP2]] // CHECK-NEXT:ret <8 x i16> [[TMP4]] // uint16x8_t test_vmaxaq_s16(uint16x8_t a, int16x8_t b) @@ -45,8 +45,8 @@ uint16x8_t test_vmaxaq_s16(uint16x8_t a, int16x8_t b) // CHECK-NEXT:[[TMP0:%.*]] = icmp slt <4 x i32> [[B:%.*]], zeroinitializer // CHECK-NEXT:[[TMP1:%.*]] = sub <4 x i32> zeroinitializer, [[B]] // CHECK-NEXT:[[TMP2:%.*]] = select <4 x i1> [[TMP0]], <4 x i32> [[TMP1]], <4 x i32> [[B]] -// CHECK-NEXT:[[TMP3:%.*]] = icmp ugt <4 x i32> [[TMP2]], [[A:%.*]] -// CHECK-NEXT:[[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[TMP2]], <4 x i32> [[A]] +// CHECK-NEXT:[[TMP3:%.*]] = icmp uge <4 x i32> [[A:%.*]], [[TMP2]] +// CHECK-NEXT:[[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i32> [[A]], <4 x i32> [[TMP2]] // CHECK-NEXT:ret <4 x i32> [[TMP4]] // uint32x4_t test_vmaxaq_s32(uint32x4_t a, int32x4_t b) @@ -61,8 +61,8 @@ uint32x4_t test_vmaxaq_s32(uint32x4_t a, int32x4_t b) // CHECK-LABEL: @test_vmaxaq_m_s8( // CHECK-NEXT: entry: // CHECK-NEXT:[[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 -// CHECK-NEXT:[[TMP1:%.*]] = tail call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) -// CHECK-NEXT:[[TMP2:%.*]] = tail call <16 x i8> @llvm.arm.mve.vmaxa.predicated.v16i8.v16i1(<16 x i8> [[A:%.*]], <16 x i8> [[B:%.*]], <16 x i1> [[TMP1]]) +// CHECK-NEXT:[[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) +// CHECK-NEXT:[[TMP2:%.*]] = call <16 x i8> @llvm.arm.mve.vmaxa.predicated.v16i8.v
[PATCH] D87201: [clang-format] Add a option for the position of Java static import
bc-lee updated this revision to Diff 290137. bc-lee added a comment. Add missing initializer. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87201/new/ https://reviews.llvm.org/D87201 Files: clang/docs/ClangFormatStyleOptions.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/unittests/Format/SortImportsTestJava.cpp Index: clang/unittests/Format/SortImportsTestJava.cpp === --- clang/unittests/Format/SortImportsTestJava.cpp +++ clang/unittests/Format/SortImportsTestJava.cpp @@ -250,6 +250,30 @@ "import org.c;\n")); } +TEST_F(SortImportsTestJava, FormatJavaStaticImportAfterImport) { + FmtStyle.JavaStaticImportAfterImport = true; + + EXPECT_EQ("import com.test.b;\n" +"import com.test.c;\n" +"\n" +"import org.b;\n" +"\n" +"import com.b;\n" +"\n" +"import static com.test.a;\n" +"\n" +"import static org.a;\n" +"\n" +"import static com.a;\n", +sort("import static com.test.a;\n" + "import static org.a;\n" + "import static com.a;\n" + "import com.test.b;\n" + "import org.b;\n" + "import com.b;\n" + "import com.test.c;\n")); +} + TEST_F(SortImportsTestJava, DeduplicateImports) { EXPECT_EQ("import org.a;\n", sort("import org.a;\n" "import org.a;\n")); Index: clang/lib/Format/Format.cpp === --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -543,6 +543,8 @@ IO.mapOptional("JavaImportGroups", Style.JavaImportGroups); IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes); IO.mapOptional("JavaScriptWrapImports", Style.JavaScriptWrapImports); +IO.mapOptional("JavaStaticImportAfterImport", + Style.JavaStaticImportAfterImport); IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks", Style.KeepEmptyLinesAtTheStartOfBlocks); IO.mapOptional("MacroBlockBegin", Style.MacroBlockBegin); @@ -899,6 +901,7 @@ LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None; LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; LLVMStyle.JavaScriptWrapImports = true; + LLVMStyle.JavaStaticImportAfterImport = false; LLVMStyle.TabWidth = 8; LLVMStyle.MaxEmptyLinesToKeep = 1; LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true; @@ -2310,12 +2313,15 @@ JavaImportGroups.push_back( findJavaImportGroup(Style, Imports[i].Identifier)); } + bool StaticImportAfterNormalImport = Style.JavaStaticImportAfterImport; llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) { // Negating IsStatic to push static imports above non-static imports. -return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI], - Imports[LHSI].Identifier) < - std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI], - Imports[RHSI].Identifier); +return std::make_tuple(!Imports[LHSI].IsStatic ^ + StaticImportAfterNormalImport, + JavaImportGroups[LHSI], Imports[LHSI].Identifier) < + std::make_tuple(!Imports[RHSI].IsStatic ^ + StaticImportAfterNormalImport, + JavaImportGroups[RHSI], Imports[RHSI].Identifier); }); // Deduplicate imports. Index: clang/include/clang/Format/Format.h === --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -1671,6 +1671,10 @@ bool JavaScriptWrapImports; // clang-format on + /// If true, clang-format will put Java Static imports after all non-static + /// imports. + bool JavaStaticImportAfterImport; + /// If true, the empty line at the start of blocks is kept. /// \code ///true: false: @@ -2391,6 +2395,7 @@ JavaImportGroups == R.JavaImportGroups && JavaScriptQuotes == R.JavaScriptQuotes && JavaScriptWrapImports == R.JavaScriptWrapImports && + JavaStaticImportAfterImport == R.JavaStaticImportAfterImport && KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && MacroBlockBegin == R.MacroBlockBegin && Index: clang/docs/ClangFormatStyleOptions.rst === --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -2021,6 +2021,20 @@ false: import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js" +**JavaStaticImpor
[PATCH] D87163: [DSE] Switch to MemorySSA-backed DSE by default.
fhahn updated this revision to Diff 290140. fhahn added a comment. Adjust limit in description, thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87163/new/ https://reviews.llvm.org/D87163 Files: clang/test/CodeGen/thinlto-distributed-newpm.ll clang/test/CodeGenObjC/exceptions.m llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/test/Analysis/BasicAA/modref.ll llvm/test/CodeGen/AMDGPU/opt-pipeline.ll llvm/test/Other/new-pm-defaults.ll llvm/test/Other/new-pm-lto-defaults.ll llvm/test/Other/new-pm-thinlto-defaults.ll llvm/test/Other/opt-O2-pipeline.ll llvm/test/Other/opt-O3-pipeline-enable-matrix.ll llvm/test/Other/opt-O3-pipeline.ll llvm/test/Other/opt-Os-pipeline.ll llvm/test/Transforms/Coroutines/ArgAddr.ll llvm/test/Transforms/Coroutines/coro-retcon.ll llvm/test/Transforms/DeadStoreElimination/MSSA/2011-03-25-DSEMiscompile.ll llvm/test/Transforms/DeadStoreElimination/MSSA/2011-09-06-EndOfFunction.ll llvm/test/Transforms/DeadStoreElimination/MSSA/2011-09-06-MemCpy.ll llvm/test/Transforms/DeadStoreElimination/MSSA/2016-07-17-UseAfterFree.ll llvm/test/Transforms/DeadStoreElimination/MSSA/OverwriteStoreBegin.ll llvm/test/Transforms/DeadStoreElimination/MSSA/OverwriteStoreEnd.ll llvm/test/Transforms/DeadStoreElimination/MSSA/PartialStore.ll llvm/test/Transforms/DeadStoreElimination/MSSA/PartialStore2.ll llvm/test/Transforms/DeadStoreElimination/MSSA/X86/gather-null-pointer.ll llvm/test/Transforms/DeadStoreElimination/MSSA/atomic-overlapping.ll llvm/test/Transforms/DeadStoreElimination/MSSA/atomic-todo.ll llvm/test/Transforms/DeadStoreElimination/MSSA/atomic.ll llvm/test/Transforms/DeadStoreElimination/MSSA/calloc-store.ll llvm/test/Transforms/DeadStoreElimination/MSSA/combined-partial-overwrites.ll llvm/test/Transforms/DeadStoreElimination/MSSA/const-pointers.ll llvm/test/Transforms/DeadStoreElimination/MSSA/crash.ll llvm/test/Transforms/DeadStoreElimination/MSSA/cs-cs-aliasing.ll llvm/test/Transforms/DeadStoreElimination/MSSA/debug-counter.ll llvm/test/Transforms/DeadStoreElimination/MSSA/debuginfo.ll llvm/test/Transforms/DeadStoreElimination/MSSA/dominate.ll llvm/test/Transforms/DeadStoreElimination/MSSA/fence-todo.ll llvm/test/Transforms/DeadStoreElimination/MSSA/fence.ll llvm/test/Transforms/DeadStoreElimination/MSSA/free.ll llvm/test/Transforms/DeadStoreElimination/MSSA/inst-limits.ll llvm/test/Transforms/DeadStoreElimination/MSSA/int_sideeffect.ll llvm/test/Transforms/DeadStoreElimination/MSSA/invariant.start.ll llvm/test/Transforms/DeadStoreElimination/MSSA/launder.invariant.group.ll llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll llvm/test/Transforms/DeadStoreElimination/MSSA/lifetime.ll llvm/test/Transforms/DeadStoreElimination/MSSA/mda-with-dbg-values.ll llvm/test/Transforms/DeadStoreElimination/MSSA/memcpy-complete-overwrite.ll llvm/test/Transforms/DeadStoreElimination/MSSA/memintrinsics.ll llvm/test/Transforms/DeadStoreElimination/MSSA/memoryssa-scan-limit.ll llvm/test/Transforms/DeadStoreElimination/MSSA/memset-and-memcpy.ll llvm/test/Transforms/DeadStoreElimination/MSSA/memset-missing-debugloc.ll llvm/test/Transforms/DeadStoreElimination/MSSA/memset-unknown-sizes.ll llvm/test/Transforms/DeadStoreElimination/MSSA/merge-stores-big-endian.ll llvm/test/Transforms/DeadStoreElimination/MSSA/merge-stores.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-captures.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-exceptions.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-loops.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-malloc-free.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memintrinsics.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-memoryphis.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath-throwing.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-multipath.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-overlap.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-partial.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-simple.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-throwing.ll llvm/test/Transforms/DeadStoreElimination/MSSA/multiblock-unreachable.ll llvm/test/Transforms/DeadStoreElimination/MSSA/no-targetdata.ll llvm/test/Transforms/DeadStoreElimination/MSSA/noop-stores.ll llvm/test/Transforms/DeadStoreElimination/MSSA/operand-bundles.ll llvm/test/Transforms/DeadStoreElimination/MSSA/overlap.ll llvm/test/Transforms/DeadStoreElimination/MSSA/pr11390.ll llvm/test/Transforms/DeadStoreElimination/MSSA/pr47285-not-overwritten-on-all-exit-paths.ll llvm/test/Transforms/DeadStoreElimination/MSSA/simple-preservation.ll llvm/test/Transforms/DeadStoreElimination/MSSA/simple-todo.ll llvm/test/Transforms/DeadStoreElimination/MS
[PATCH] D87163: [DSE] Switch to MemorySSA-backed DSE by default.
fhahn added inline comments. Comment at: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp:115 cl::desc("The number of memory instructions to scan for " "dead store elimination (default = 100)")); static cl::opt MemorySSAUpwardsStepLimit( xbolva00 wrote: > Default 150? Yes indeed, fixed! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87163/new/ https://reviews.llvm.org/D87163 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bbb3baf - Thread safety analysis: Improve documentation for scoped capabilities
Author: Aaron Puchert Date: 2020-09-06T20:37:42+02:00 New Revision: bbb3baf6205c54231257f64fd18661a13a5c97ee URL: https://github.com/llvm/llvm-project/commit/bbb3baf6205c54231257f64fd18661a13a5c97ee DIFF: https://github.com/llvm/llvm-project/commit/bbb3baf6205c54231257f64fd18661a13a5c97ee.diff LOG: Thread safety analysis: Improve documentation for scoped capabilities They are for more powerful than the current documentation implies, this adds * adopting a lock, * deferring a lock, * manually unlocking the scoped capability, * relocking the scoped capability, possibly in a different mode, * try-relocking the scoped capability. Also there is now a generic explanation how attributes on scoped capabilities work. There has been confusion in the past about how to annotate them (see e.g. PR33504), hopefully this clears things up. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D87066 Added: Modified: clang/docs/ThreadSafetyAnalysis.rst Removed: diff --git a/clang/docs/ThreadSafetyAnalysis.rst b/clang/docs/ThreadSafetyAnalysis.rst index e6ce0e04e70a..e4a3342c02bd 100644 --- a/clang/docs/ThreadSafetyAnalysis.rst +++ b/clang/docs/ThreadSafetyAnalysis.rst @@ -402,6 +402,13 @@ the destructor. Such classes require special handling because the constructor and destructor refer to the capability via diff erent names; see the ``MutexLocker`` class in :ref:`mutexheader`, below. +Scoped capabilities are treated as capabilities that are implicitly acquired +on construction and released on destruction. They are associated with +the set of (regular) capabilities named in thread safety attributes on the +constructor. Acquire-type attributes on other member functions are treated as +applying to that set of associated capabilities, while ``RELEASE`` implies that +a function releases all associated capabilities in whatever mode they're held. + TRY_ACQUIRE(, ...), TRY_ACQUIRE_SHARED(, ...) - @@ -886,19 +893,78 @@ implementation. const Mutex& operator!() const { return *this; } }; + // Tag types for selecting a constructor. + struct adopt_lock_t {} inline constexpr adopt_lock = {}; + struct defer_lock_t {} inline constexpr defer_lock = {}; + struct shared_lock_t {} inline constexpr shared_lock = {}; // MutexLocker is an RAII class that acquires a mutex in its constructor, and // releases it in its destructor. class SCOPED_CAPABILITY MutexLocker { private: Mutex* mut; +bool locked; public: -MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) { +// Acquire mu, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu), locked(true) { mu->Lock(); } + +// Assume mu is held, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, adopt_lock_t) REQUIRES(mu) : mut(mu), locked(true) {} + +// Acquire mu in shared mode, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, shared_lock_t) ACQUIRE_SHARED(mu) : mut(mu), locked(true) { + mu->ReaderLock(); +} + +// Assume mu is held in shared mode, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, adopt_lock_t, shared_lock_t) REQUIRES_SHARED(mu) + : mut(mu), locked(true) {} + +// Assume mu is not held, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, defer_lock_t) EXCLUDES(mu) : mut(mu), locked(false) {} + +// Release *this and all associated mutexes, if they are still held. +// There is no warning if the scope was already unlocked before. ~MutexLocker() RELEASE() { + if (locked) +mut->GenericUnlock(); +} + +// Acquire all associated mutexes exclusively. +void Lock() ACQUIRE() { + mut->Lock(); + locked = true; +} + +// Try to acquire all associated mutexes exclusively. +bool TryLock() TRY_ACQUIRE(true) { + return locked = mut->TryLock(); +} + +// Acquire all associated mutexes in shared mode. +void ReaderLock() ACQUIRE_SHARED() { + mut->ReaderLock(); + locked = true; +} + +// Try to acquire all associated mutexes in shared mode. +bool ReaderTryLock() TRY_ACQUIRE_SHARED(true) { + return locked = mut->ReaderTryLock(); +} + +// Release all associated mutexes. Warn on double unlock. +void Unlock() RELEASE() { mut->Unlock(); + locked = false; +} + +// Release all associated mutexes. Warn on double unlock. +void ReaderUnlock() RELEASE() { + mut->ReaderUnlock(); + locked = false; } }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D87066: Thread safety analysis: Improve documentation for scoped capabilities
This revision was automatically updated to reflect the committed changes. Closed by commit rGbbb3baf6205c: Thread safety analysis: Improve documentation for scoped capabilities (authored by aaronpuchert). Changed prior to commit: https://reviews.llvm.org/D87066?vs=289826&id=290145#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87066/new/ https://reviews.llvm.org/D87066 Files: clang/docs/ThreadSafetyAnalysis.rst Index: clang/docs/ThreadSafetyAnalysis.rst === --- clang/docs/ThreadSafetyAnalysis.rst +++ clang/docs/ThreadSafetyAnalysis.rst @@ -402,6 +402,13 @@ and destructor refer to the capability via different names; see the ``MutexLocker`` class in :ref:`mutexheader`, below. +Scoped capabilities are treated as capabilities that are implicitly acquired +on construction and released on destruction. They are associated with +the set of (regular) capabilities named in thread safety attributes on the +constructor. Acquire-type attributes on other member functions are treated as +applying to that set of associated capabilities, while ``RELEASE`` implies that +a function releases all associated capabilities in whatever mode they're held. + TRY_ACQUIRE(, ...), TRY_ACQUIRE_SHARED(, ...) - @@ -886,19 +893,78 @@ const Mutex& operator!() const { return *this; } }; + // Tag types for selecting a constructor. + struct adopt_lock_t {} inline constexpr adopt_lock = {}; + struct defer_lock_t {} inline constexpr defer_lock = {}; + struct shared_lock_t {} inline constexpr shared_lock = {}; // MutexLocker is an RAII class that acquires a mutex in its constructor, and // releases it in its destructor. class SCOPED_CAPABILITY MutexLocker { private: Mutex* mut; +bool locked; public: -MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) { +// Acquire mu, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu), locked(true) { mu->Lock(); } + +// Assume mu is held, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, adopt_lock_t) REQUIRES(mu) : mut(mu), locked(true) {} + +// Acquire mu in shared mode, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, shared_lock_t) ACQUIRE_SHARED(mu) : mut(mu), locked(true) { + mu->ReaderLock(); +} + +// Assume mu is held in shared mode, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, adopt_lock_t, shared_lock_t) REQUIRES_SHARED(mu) + : mut(mu), locked(true) {} + +// Assume mu is not held, implicitly acquire *this and associate it with mu. +MutexLocker(Mutex *mu, defer_lock_t) EXCLUDES(mu) : mut(mu), locked(false) {} + +// Release *this and all associated mutexes, if they are still held. +// There is no warning if the scope was already unlocked before. ~MutexLocker() RELEASE() { + if (locked) +mut->GenericUnlock(); +} + +// Acquire all associated mutexes exclusively. +void Lock() ACQUIRE() { + mut->Lock(); + locked = true; +} + +// Try to acquire all associated mutexes exclusively. +bool TryLock() TRY_ACQUIRE(true) { + return locked = mut->TryLock(); +} + +// Acquire all associated mutexes in shared mode. +void ReaderLock() ACQUIRE_SHARED() { + mut->ReaderLock(); + locked = true; +} + +// Try to acquire all associated mutexes in shared mode. +bool ReaderTryLock() TRY_ACQUIRE_SHARED(true) { + return locked = mut->ReaderTryLock(); +} + +// Release all associated mutexes. Warn on double unlock. +void Unlock() RELEASE() { mut->Unlock(); + locked = false; +} + +// Release all associated mutexes. Warn on double unlock. +void ReaderUnlock() RELEASE() { + mut->ReaderUnlock(); + locked = false; } }; Index: clang/docs/ThreadSafetyAnalysis.rst === --- clang/docs/ThreadSafetyAnalysis.rst +++ clang/docs/ThreadSafetyAnalysis.rst @@ -402,6 +402,13 @@ and destructor refer to the capability via different names; see the ``MutexLocker`` class in :ref:`mutexheader`, below. +Scoped capabilities are treated as capabilities that are implicitly acquired +on construction and released on destruction. They are associated with +the set of (regular) capabilities named in thread safety attributes on the +constructor. Acquire-type attributes on other member functions are treated as +applying to that set of associated capabilities, while ``RELEASE`` implies that +a function releases all associated capabilities in whatever mode they're held. + TRY_ACQUIRE(, ...), TRY_ACQUIRE_SHARED(, ...) - @@ -886,19 +893,78 @@ const Mutex& operator!(
[PATCH] D87064: Thread safety analysis: Test and document release_generic_capability
This revision was automatically updated to reflect the committed changes. Closed by commit rGcc6713a2c35e: Thread safety analysis: Test and document release_generic_capability (authored by aaronpuchert). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87064/new/ https://reviews.llvm.org/D87064 Files: clang/docs/ThreadSafetyAnalysis.rst clang/test/SemaCXX/thread-safety-annotations.h Index: clang/test/SemaCXX/thread-safety-annotations.h === --- clang/test/SemaCXX/thread-safety-annotations.h +++ clang/test/SemaCXX/thread-safety-annotations.h @@ -6,6 +6,7 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_capability(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((acquire_capability(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((acquire_shared_capability(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((release_generic_capability(__VA_ARGS__))) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_capability(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_shared_capability(__VA_ARGS__))) #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((requires_capability(__VA_ARGS__))) @@ -16,6 +17,7 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__))) @@ -23,7 +25,6 @@ #endif // Lock semantics only -#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) #define GUARDED_VAR __attribute__((guarded_var)) #define PT_GUARDED_VAR __attribute__((pt_guarded_var)) Index: clang/docs/ThreadSafetyAnalysis.rst === --- clang/docs/ThreadSafetyAnalysis.rst +++ clang/docs/ThreadSafetyAnalysis.rst @@ -209,21 +209,21 @@ } -ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...) - +ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...) +-- *Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``, ``UNLOCK_FUNCTION`` -``ACQUIRE`` is an attribute on functions or methods, which -declares that the function acquires a capability, but does not release it. The -caller must not hold the given capability on entry, and it will hold the -capability on exit. ``ACQUIRE_SHARED`` is similar. +``ACQUIRE`` and ``ACQUIRE_SHARED`` are attributes on functions or methods +declaring that the function acquires a capability, but does not release it. +The given capability must not be held on entry, and will be held on exit +(exclusively for ``ACQUIRE``, shared for ``ACQUIRE_SHARED``). -``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given -capability. The caller must hold the capability on entry, and will no longer -hold it on exit. It does not matter whether the given capability is shared or -exclusive. +``RELEASE``, ``RELEASE_SHARED``, and ``RELEASE_GENERIC`` declare that the +function releases the given capability. The capability must be held on entry +(exclusively for ``RELEASE``, shared for ``RELEASE_SHARED``, exclusively or +shared for ``RELEASE_GENERIC``), and will no longer be held on exit. .. code-block:: c++ @@ -820,6 +820,9 @@ #define RELEASE_SHARED(...) \ THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) + #define RELEASE_GENERIC(...) \ +THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__)) + #define TRY_ACQUIRE(...) \ THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) @@ -864,6 +867,9 @@ // Release/unlock a shared mutex. void ReaderUnlock() RELEASE_SHARED(); +// Generic unlock, can unlock exclusive and shared mutexes. +void GenericUnlock() RELEASE_GENERIC(); + // Try to acquire the mutex. Returns true on success, and false on failure. bool TryLock() TRY_ACQUIRE(true); Index: clang/test/SemaCXX/thread-safety-annotations.h === --- clang/test/SemaCXX/thread-safety-annotations.h +++ clang/test/SemaCXX/thread-safety-annota
[clang] cc6713a - Thread safety analysis: Test and document release_generic_capability
Author: Aaron Puchert Date: 2020-09-06T20:37:41+02:00 New Revision: cc6713a2c35edf17cfb567284cc76b374308e5e4 URL: https://github.com/llvm/llvm-project/commit/cc6713a2c35edf17cfb567284cc76b374308e5e4 DIFF: https://github.com/llvm/llvm-project/commit/cc6713a2c35edf17cfb567284cc76b374308e5e4.diff LOG: Thread safety analysis: Test and document release_generic_capability The old locking attributes had a generic release, but as it turns out the capability-based attributes have it as well. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D87064 Added: Modified: clang/docs/ThreadSafetyAnalysis.rst clang/test/SemaCXX/thread-safety-annotations.h Removed: diff --git a/clang/docs/ThreadSafetyAnalysis.rst b/clang/docs/ThreadSafetyAnalysis.rst index b8d7d24275b9..e6ce0e04e70a 100644 --- a/clang/docs/ThreadSafetyAnalysis.rst +++ b/clang/docs/ThreadSafetyAnalysis.rst @@ -209,21 +209,21 @@ must be held on entry to the function, *and must still be held on exit*. } -ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...) - +ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...), RELEASE_GENERIC(...) +-- *Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``, ``UNLOCK_FUNCTION`` -``ACQUIRE`` is an attribute on functions or methods, which -declares that the function acquires a capability, but does not release it. The -caller must not hold the given capability on entry, and it will hold the -capability on exit. ``ACQUIRE_SHARED`` is similar. +``ACQUIRE`` and ``ACQUIRE_SHARED`` are attributes on functions or methods +declaring that the function acquires a capability, but does not release it. +The given capability must not be held on entry, and will be held on exit +(exclusively for ``ACQUIRE``, shared for ``ACQUIRE_SHARED``). -``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given -capability. The caller must hold the capability on entry, and will no longer -hold it on exit. It does not matter whether the given capability is shared or -exclusive. +``RELEASE``, ``RELEASE_SHARED``, and ``RELEASE_GENERIC`` declare that the +function releases the given capability. The capability must be held on entry +(exclusively for ``RELEASE``, shared for ``RELEASE_SHARED``, exclusively or +shared for ``RELEASE_GENERIC``), and will no longer be held on exit. .. code-block:: c++ @@ -820,6 +820,9 @@ implementation. #define RELEASE_SHARED(...) \ THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) + #define RELEASE_GENERIC(...) \ +THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__)) + #define TRY_ACQUIRE(...) \ THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) @@ -864,6 +867,9 @@ implementation. // Release/unlock a shared mutex. void ReaderUnlock() RELEASE_SHARED(); +// Generic unlock, can unlock exclusive and shared mutexes. +void GenericUnlock() RELEASE_GENERIC(); + // Try to acquire the mutex. Returns true on success, and false on failure. bool TryLock() TRY_ACQUIRE(true); diff --git a/clang/test/SemaCXX/thread-safety-annotations.h b/clang/test/SemaCXX/thread-safety-annotations.h index 7755a1b328e7..d89bcf8ff470 100644 --- a/clang/test/SemaCXX/thread-safety-annotations.h +++ b/clang/test/SemaCXX/thread-safety-annotations.h @@ -6,6 +6,7 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_capability(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((acquire_capability(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((acquire_shared_capability(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((release_generic_capability(__VA_ARGS__))) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_capability(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_shared_capability(__VA_ARGS__))) #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((requires_capability(__VA_ARGS__))) @@ -16,6 +17,7 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__))) #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__))) #define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__
[clang] efa57f9 - [PowerPC] Implement Vector Expand Mask builtins in LLVM/Clang
Author: Amy Kwan Date: 2020-09-06T17:13:21-05:00 New Revision: efa57f9a7adb11a14b4e0d930f49070c769fa6ac URL: https://github.com/llvm/llvm-project/commit/efa57f9a7adb11a14b4e0d930f49070c769fa6ac DIFF: https://github.com/llvm/llvm-project/commit/efa57f9a7adb11a14b4e0d930f49070c769fa6ac.diff LOG: [PowerPC] Implement Vector Expand Mask builtins in LLVM/Clang This patch implements the vec_expandm function prototypes in altivec.h in order to utilize the vector expand with mask instructions introduced in Power10. Differential Revision: https://reviews.llvm.org/D82727 Added: Modified: clang/include/clang/Basic/BuiltinsPPC.def clang/lib/Headers/altivec.h clang/test/CodeGen/builtins-ppc-p10vector.c llvm/include/llvm/IR/IntrinsicsPowerPC.td llvm/lib/Target/PowerPC/PPCInstrPrefix.td llvm/test/CodeGen/PowerPC/p10-vector-mask-ops.ll Removed: diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 57ef39980c9b..89dd03075b28 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -322,6 +322,13 @@ BUILTIN(__builtin_altivec_vmulhuw, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vmulhsd, "V2LLiV2LLiV2LLi", "") BUILTIN(__builtin_altivec_vmulhud, "V2ULLiV2ULLiV2ULLi", "") +// P10 Vector Expand with Mask built-ins. +BUILTIN(__builtin_altivec_vexpandbm, "V16UcV16Uc", "") +BUILTIN(__builtin_altivec_vexpandhm, "V8UsV8Us", "") +BUILTIN(__builtin_altivec_vexpandwm, "V4UiV4Ui", "") +BUILTIN(__builtin_altivec_vexpanddm, "V2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vexpandqm, "V1ULLLiV1ULLLi", "") + // P10 Vector Parallel Bits built-ins. BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "") diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index a7c4fd23ef19..22744adefbef 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -17041,6 +17041,33 @@ vec_extractm(vector unsigned __int128 __a) { return __builtin_altivec_vextractqm(__a); } +/* vec_expandm */ + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_expandm(vector unsigned char __a) { + return __builtin_altivec_vexpandbm(__a); +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_expandm(vector unsigned short __a) { + return __builtin_altivec_vexpandhm(__a); +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_expandm(vector unsigned int __a) { + return __builtin_altivec_vexpandwm(__a); +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_expandm(vector unsigned long long __a) { + return __builtin_altivec_vexpanddm(__a); +} + +static __inline__ vector unsigned __int128 __ATTRS_o_ai +vec_expandm(vector unsigned __int128 __a) { + return __builtin_altivec_vexpandqm(__a); +} + /* vec_pdep */ static __inline__ vector unsigned long long __ATTRS_o_ai diff --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c index c850ebd1c70f..ad63d646196c 100644 --- a/clang/test/CodeGen/builtins-ppc-p10vector.c +++ b/clang/test/CodeGen/builtins-ppc-p10vector.c @@ -201,6 +201,36 @@ vector unsigned long long test_vcfuged(void) { return vec_cfuge(vulla, vullb); } +vector unsigned char test_vec_expandm_uc(void) { + // CHECK: @llvm.ppc.altivec.vexpandbm(<16 x i8> %{{.+}}) + // CHECK-NEXT: ret <16 x i8> + return vec_expandm(vuca); +} + +vector unsigned short test_vec_expandm_us(void) { + // CHECK: @llvm.ppc.altivec.vexpandhm(<8 x i16> %{{.+}}) + // CHECK-NEXT: ret <8 x i16> + return vec_expandm(vusa); +} + +vector unsigned int test_vec_expandm_ui(void) { + // CHECK: @llvm.ppc.altivec.vexpandwm(<4 x i32> %{{.+}}) + // CHECK-NEXT: ret <4 x i32> + return vec_expandm(vuia); +} + +vector unsigned long long test_vec_expandm_ull(void) { + // CHECK: @llvm.ppc.altivec.vexpanddm(<2 x i64> %{{.+}}) + // CHECK-NEXT: ret <2 x i64> + return vec_expandm(vulla); +} + +vector unsigned __int128 test_vec_expandm_u128(void) { + // CHECK: @llvm.ppc.altivec.vexpandqm(<1 x i128> %{{.+}}) + // CHECK-NEXT: ret <1 x i128> + return vec_expandm(vui128a); +} + unsigned long long test_vgnb_1(void) { // CHECK: @llvm.ppc.altivec.vgnb(<1 x i128> %{{.+}}, i32 2) // CHECK-NEXT: ret i64 diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index 4ead968a1975..73a49ec77f8b 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -455,6 +455,18 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_altivec_vextractqm : GCCBuiltin<"__builtin_altivec_vextractqm">, Intrinsic<[llvm_i32_ty], [llvm_v1i128_ty], [IntrNoMem]>; + // P10 Vector Expand with Mask + def int_ppc_altivec_vexpandbm : GCCBuiltin<"__builtin_altivec_vexpan
[PATCH] D82727: [PowerPC] Implement Vector Expand Mask builtins in LLVM/Clang
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGefa57f9a7adb: [PowerPC] Implement Vector Expand Mask builtins in LLVM/Clang (authored by amyk). Changed prior to commit: https://reviews.llvm.org/D82727?vs=287434&id=290152#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D82727/new/ https://reviews.llvm.org/D82727 Files: clang/include/clang/Basic/BuiltinsPPC.def clang/lib/Headers/altivec.h clang/test/CodeGen/builtins-ppc-p10vector.c llvm/include/llvm/IR/IntrinsicsPowerPC.td llvm/lib/Target/PowerPC/PPCInstrPrefix.td llvm/test/CodeGen/PowerPC/p10-vector-mask-ops.ll Index: llvm/test/CodeGen/PowerPC/p10-vector-mask-ops.ll === --- llvm/test/CodeGen/PowerPC/p10-vector-mask-ops.ll +++ llvm/test/CodeGen/PowerPC/p10-vector-mask-ops.ll @@ -64,3 +64,59 @@ %ext = tail call i32 @llvm.ppc.altivec.vextractqm(<1 x i128> %a) ret i32 %ext } + +declare <16 x i8> @llvm.ppc.altivec.vexpandbm(<16 x i8>) +declare <8 x i16> @llvm.ppc.altivec.vexpandhm(<8 x i16>) +declare <4 x i32> @llvm.ppc.altivec.vexpandwm(<4 x i32>) +declare <2 x i64> @llvm.ppc.altivec.vexpanddm(<2 x i64>) +declare <1 x i128> @llvm.ppc.altivec.vexpandqm(<1 x i128>) + +define <16 x i8> @test_vexpandbm(<16 x i8> %a) { +; CHECK-LABEL: test_vexpandbm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:vexpandbm v2, v2 +; CHECK-NEXT:blr +entry: + %exp = tail call <16 x i8> @llvm.ppc.altivec.vexpandbm(<16 x i8> %a) + ret <16 x i8> %exp +} + +define <8 x i16> @test_vexpandhm(<8 x i16> %a) { +; CHECK-LABEL: test_vexpandhm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:vexpandhm v2, v2 +; CHECK-NEXT:blr +entry: + %exp = tail call <8 x i16> @llvm.ppc.altivec.vexpandhm(<8 x i16> %a) + ret <8 x i16> %exp +} + +define <4 x i32> @test_vexpandwm(<4 x i32> %a) { +; CHECK-LABEL: test_vexpandwm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:vexpandwm v2, v2 +; CHECK-NEXT:blr +entry: + %exp = tail call <4 x i32> @llvm.ppc.altivec.vexpandwm(<4 x i32> %a) + ret <4 x i32> %exp +} + +define <2 x i64> @test_vexpanddm(<2 x i64> %a) { +; CHECK-LABEL: test_vexpanddm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:vexpanddm v2, v2 +; CHECK-NEXT:blr +entry: + %exp = tail call <2 x i64> @llvm.ppc.altivec.vexpanddm(<2 x i64> %a) + ret <2 x i64> %exp +} + +define <1 x i128> @test_vexpandqm(<1 x i128> %a) { +; CHECK-LABEL: test_vexpandqm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT:vexpandqm v2, v2 +; CHECK-NEXT:blr +entry: + %exp = tail call <1 x i128> @llvm.ppc.altivec.vexpandqm(<1 x i128> %a) + ret <1 x i128> %exp +} Index: llvm/lib/Target/PowerPC/PPCInstrPrefix.td === --- llvm/lib/Target/PowerPC/PPCInstrPrefix.td +++ llvm/lib/Target/PowerPC/PPCInstrPrefix.td @@ -1003,19 +1003,24 @@ (int_ppc_altivec_vextractqm v1i128:$vB))]>; def VEXPANDBM : VXForm_RD5_XO5_RS5<1602, 0, (outs vrrc:$vD), (ins vrrc:$vB), "vexpandbm $vD, $vB", IIC_VecGeneral, - []>; + [(set v16i8:$vD, (int_ppc_altivec_vexpandbm + v16i8:$vB))]>; def VEXPANDHM : VXForm_RD5_XO5_RS5<1602, 1, (outs vrrc:$vD), (ins vrrc:$vB), "vexpandhm $vD, $vB", IIC_VecGeneral, - []>; + [(set v8i16:$vD, (int_ppc_altivec_vexpandhm + v8i16:$vB))]>; def VEXPANDWM : VXForm_RD5_XO5_RS5<1602, 2, (outs vrrc:$vD), (ins vrrc:$vB), "vexpandwm $vD, $vB", IIC_VecGeneral, - []>; + [(set v4i32:$vD, (int_ppc_altivec_vexpandwm + v4i32:$vB))]>; def VEXPANDDM : VXForm_RD5_XO5_RS5<1602, 3, (outs vrrc:$vD), (ins vrrc:$vB), "vexpanddm $vD, $vB", IIC_VecGeneral, - []>; + [(set v2i64:$vD, (int_ppc_altivec_vexpanddm + v2i64:$vB))]>; def VEXPANDQM : VXForm_RD5_XO5_RS5<1602, 4, (outs vrrc:$vD), (ins vrrc:$vB), "vexpandqm $vD, $vB", IIC_VecGeneral, - []>; + [(set v1i128:$vD, (int_ppc_altivec_vexpandqm + v1i128:$vB))]>; def MTVSRBM : VXForm_RD5_XO5_RS5<1602, 16, (outs vrrc:$vD), (ins g8rc:$rB), "mtvsrbm $vD, $rB", IIC_VecGeneral, []>; Index: llvm/include/llvm/IR/IntrinsicsPowerPC.td
[PATCH] D82727: [PowerPC] Implement Vector Expand Mask builtins in LLVM/Clang
hubert.reinterpretcast added inline comments. Comment at: llvm/lib/Target/PowerPC/PPCInstrPrefix.td:1006 "vexpandbm $vD, $vB", IIC_VecGeneral, - []>; + [(set v16i8:$vD, (int_ppc_altivec_vexpandbm + v16i8:$vB))]>; The commit added "physical" tab characters instead of spaces here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D82727/new/ https://reviews.llvm.org/D82727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D87216: [NewPM] Support --print-before/after in NPM
aeubanks created this revision. Herald added subscribers: llvm-commits, cfe-commits, dexonsmith, steven_wu, hiraditya, mgorny. Herald added projects: clang, LLVM. aeubanks requested review of this revision. This changes --print-before/after to be a list of strings rather than legacy passes. (this also has the effect of not showing the entire list of passes in --help-hidden after --print-before/after, which IMO is great for making it less verbose). Currently PrintIRInstrumentation passes the class name rather than pass name to llvm::shouldPrintBeforePass(), meaning llvm::shouldPrintBeforePass() never functions as intended. There is no easy way of converting class names to pass names outside of within an instance of PassBuilder. When constructing a PassBuilder, StandardInstrumentation is needed, so we can't pass PassBuilder to the constructor of StandardInstrumentation. So this patch hackily adds a translatePassNamesToClassNames() method to StandardInstrumentation which takes a PassBuilder and asks it to convert the names passed to --print-before/after to class names, so that later it can match class names passed via PassInstrumentation. The other approach is to pass the pass name into StandardInstrumentation callbacks. This would require storing the pass name somewhere alongside the pass, which doesn't seem feasible since the PassBuilder allows directly adding passes to pass managers without using the pass name. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D87216 Files: clang/lib/CodeGen/BackendUtil.cpp llvm/include/llvm/IR/PrintPasses.h llvm/include/llvm/Passes/PassBuilder.h llvm/include/llvm/Passes/StandardInstrumentations.h llvm/lib/IR/CMakeLists.txt llvm/lib/IR/LegacyPassManager.cpp llvm/lib/IR/PrintPasses.cpp llvm/lib/LTO/LTOBackend.cpp llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/StandardInstrumentations.cpp llvm/test/CodeGen/Generic/print-after.ll llvm/test/Other/loop-pass-printer.ll llvm/test/Other/print-before-after.ll llvm/tools/opt/NewPMDriver.cpp llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn Index: llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn === --- llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn +++ llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -59,6 +59,7 @@ "PassManager.cpp", "PassRegistry.cpp", "PassTimingInfo.cpp", +"PrintPasses.cpp", "ProfileSummary.cpp", "SafepointIRVerifier.cpp", "Statepoint.cpp", Index: llvm/tools/opt/NewPMDriver.cpp === --- llvm/tools/opt/NewPMDriver.cpp +++ llvm/tools/opt/NewPMDriver.cpp @@ -272,6 +272,7 @@ PTO.LoopUnrolling = !DisableLoopUnrolling; PTO.Coroutines = Coroutines; PassBuilder PB(TM, PTO, P, &PIC); + SI.translatePassNamesToClassNames(PB); registerEPCallbacks(PB, VerifyEachPass, DebugPM); // Load requested pass plugins and let them register pass builder callbacks Index: llvm/test/Other/print-before-after.ll === --- /dev/null +++ llvm/test/Other/print-before-after.ll @@ -0,0 +1,33 @@ +; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-before=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-after=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-function' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-function' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE + +; NONE-NOT: @foo +; NONE-NOT: @bar + +; ONCE: @foo +; ONCE: @bar +; ONCE-NOT: @foo +; ONCE-NOT: @bar + +; TWICE: @foo +; TWICE: @bar +; TWICE: @foo +; TWICE: @bar +; TWICE-NOT: @foo +; TWICE-NOT: @bar + +define void @foo() { + ret void +} + +define void @bar() { + ret void +} Index: llvm/test/Other/loop-pass-printer.ll === --- llvm
[PATCH] D87216: [NewPM] Support --print-before/after in NPM
aeubanks updated this revision to Diff 290159. aeubanks added a comment. remove some includes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87216/new/ https://reviews.llvm.org/D87216 Files: clang/lib/CodeGen/BackendUtil.cpp llvm/include/llvm/IR/PrintPasses.h llvm/include/llvm/Passes/PassBuilder.h llvm/include/llvm/Passes/StandardInstrumentations.h llvm/lib/IR/CMakeLists.txt llvm/lib/IR/LegacyPassManager.cpp llvm/lib/IR/PrintPasses.cpp llvm/lib/LTO/LTOBackend.cpp llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/StandardInstrumentations.cpp llvm/test/CodeGen/Generic/print-after.ll llvm/test/Other/loop-pass-printer.ll llvm/test/Other/print-before-after.ll llvm/tools/opt/NewPMDriver.cpp llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn Index: llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn === --- llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn +++ llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -59,6 +59,7 @@ "PassManager.cpp", "PassRegistry.cpp", "PassTimingInfo.cpp", +"PrintPasses.cpp", "ProfileSummary.cpp", "SafepointIRVerifier.cpp", "Statepoint.cpp", Index: llvm/tools/opt/NewPMDriver.cpp === --- llvm/tools/opt/NewPMDriver.cpp +++ llvm/tools/opt/NewPMDriver.cpp @@ -272,6 +272,7 @@ PTO.LoopUnrolling = !DisableLoopUnrolling; PTO.Coroutines = Coroutines; PassBuilder PB(TM, PTO, P, &PIC); + SI.translatePassNamesToClassNames(PB); registerEPCallbacks(PB, VerifyEachPass, DebugPM); // Load requested pass plugins and let them register pass builder callbacks Index: llvm/test/Other/print-before-after.ll === --- /dev/null +++ llvm/test/Other/print-before-after.ll @@ -0,0 +1,33 @@ +; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-before=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-after=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-function' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-function' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE +; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE + +; NONE-NOT: @foo +; NONE-NOT: @bar + +; ONCE: @foo +; ONCE: @bar +; ONCE-NOT: @foo +; ONCE-NOT: @bar + +; TWICE: @foo +; TWICE: @bar +; TWICE: @foo +; TWICE: @bar +; TWICE-NOT: @foo +; TWICE-NOT: @bar + +define void @foo() { + ret void +} + +define void @bar() { + ret void +} Index: llvm/test/Other/loop-pass-printer.ll === --- llvm/test/Other/loop-pass-printer.ll +++ llvm/test/Other/loop-pass-printer.ll @@ -1,23 +1,23 @@ ; This test checks -print-after/before on loop passes ; Besides of the loop itself it should be dumping loop pre-header and exits. ; -; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \ +; RUN: opt < %s 2>&1 -disable-output \ ; RUN: -loop-deletion -print-before=loop-deletion \ ; RUN: | FileCheck %s -check-prefix=DEL ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -passes='loop(loop-deletion)' -print-before-all \ +; RUN: -passes='loop(loop-deletion)' -print-before=loop-deletion \ ; RUN: | FileCheck %s -check-prefix=DEL ; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \ ; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=bar \ ; RUN: | FileCheck %s -check-prefix=BAR -check-prefix=BAR-OLD ; RUN: opt < %s 2>&1 -disable-output \ -; RUN: -passes='require,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=bar \ +; RUN: -passes='require,loop(loop-unroll-full)' -print-after=loop-unroll-full -filter-print-funcs=bar \ ; RUN: | FileCheck %s -check-prefix=BAR ; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \ ; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=foo -print-module-s
[PATCH] D87218: [builtins] Inline __paritysi2 into __paritydi2 and inline __paritydi2 into __parityti2.
craig.topper created this revision. craig.topper added reviewers: scanon, MaskRay, efriedma. Herald added a project: Sanitizers. Herald added a subscriber: Sanitizers. craig.topper requested review of this revision. No point in making __parityti2 go through 2 calls to get to __paritysi2. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D87218 Files: compiler-rt/lib/builtins/paritydi2.c compiler-rt/lib/builtins/parityti2.c Index: compiler-rt/lib/builtins/parityti2.c === --- compiler-rt/lib/builtins/parityti2.c +++ compiler-rt/lib/builtins/parityti2.c @@ -18,8 +18,14 @@ COMPILER_RT_ABI int __parityti2(ti_int a) { twords x; + dwords x2; x.all = a; - return __paritydi2(x.s.high ^ x.s.low); + x2.all = x.s.high ^ x.s.low; + su_int x3 = x2.s.high ^ x2.s.low; + x3 ^= x3 >> 16; + x3 ^= x3 >> 8; + x3 ^= x3 >> 4; + return (0x6996 >> (x3 & 0xF)) & 1; } #endif // CRT_HAS_128BIT Index: compiler-rt/lib/builtins/paritydi2.c === --- compiler-rt/lib/builtins/paritydi2.c +++ compiler-rt/lib/builtins/paritydi2.c @@ -17,5 +17,9 @@ COMPILER_RT_ABI int __paritydi2(di_int a) { dwords x; x.all = a; - return __paritysi2(x.s.high ^ x.s.low); + su_int x2 = x.s.high ^ x.s.low; + x2 ^= x2 >> 16; + x2 ^= x2 >> 8; + x2 ^= x2 >> 4; + return (0x6996 >> (x2 & 0xF)) & 1; } Index: compiler-rt/lib/builtins/parityti2.c === --- compiler-rt/lib/builtins/parityti2.c +++ compiler-rt/lib/builtins/parityti2.c @@ -18,8 +18,14 @@ COMPILER_RT_ABI int __parityti2(ti_int a) { twords x; + dwords x2; x.all = a; - return __paritydi2(x.s.high ^ x.s.low); + x2.all = x.s.high ^ x.s.low; + su_int x3 = x2.s.high ^ x2.s.low; + x3 ^= x3 >> 16; + x3 ^= x3 >> 8; + x3 ^= x3 >> 4; + return (0x6996 >> (x3 & 0xF)) & 1; } #endif // CRT_HAS_128BIT Index: compiler-rt/lib/builtins/paritydi2.c === --- compiler-rt/lib/builtins/paritydi2.c +++ compiler-rt/lib/builtins/paritydi2.c @@ -17,5 +17,9 @@ COMPILER_RT_ABI int __paritydi2(di_int a) { dwords x; x.all = a; - return __paritysi2(x.s.high ^ x.s.low); + su_int x2 = x.s.high ^ x.s.low; + x2 ^= x2 >> 16; + x2 ^= x2 >> 8; + x2 ^= x2 >> 4; + return (0x6996 >> (x2 & 0xF)) & 1; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
LLVM buildmaster will be updated and restarted soon
Hello everyone, LLVM buildmaster will be updated and restarted in the nearest hour. Thanks Galina ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D87225: [clangd] When finding refs for a template specialization, do not return refs to other specializations
nridge created this revision. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous. Herald added a project: clang. nridge requested review of this revision. Herald added subscribers: MaskRay, ilya-biryukov. Fixes https://github.com/clangd/clangd/issues/515 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D87225 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp === --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1570,7 +1570,7 @@ R"cpp( template - class [[Foo]] {}; + class Foo {}; void func([[Fo^o]]); )cpp", R"cpp(// Not touching any identifiers. @@ -1582,6 +1582,13 @@ f.[[^~]]Foo(); } )cpp", + R"cpp(// Temlate specialization +template class Vector {}; +using [[^X]] = [[Vector]]; +[[X]] x1; +[[Vector]] x2; +Vector y; + )cpp", }; for (const char *Test : Tests) { Annotations T(Test); Index: clang-tools-extra/clangd/XRefs.cpp === --- clang-tools-extra/clangd/XRefs.cpp +++ clang-tools-extra/clangd/XRefs.cpp @@ -767,7 +767,12 @@ index::IndexDataConsumer::ASTNodeInfo ASTNode) override { assert(D->isCanonicalDecl() && "expect D to be a canonical declaration"); const SourceManager &SM = AST.getSourceManager(); -if (!CanonicalTargets.count(D) || !isInsideMainFile(Loc, SM)) +// For references to template specializations, `D` will contain the +// template and `ASTNode.OrigD` the specialization. We want to find +// references to specializations, to check `ASTNode.OrigD` as well. +bool ReferencesCanonicalTarget = +CanonicalTargets.count(D) || CanonicalTargets.count(ASTNode.OrigD); +if (!ReferencesCanonicalTarget || !isInsideMainFile(Loc, SM)) return true; const auto &TB = AST.getTokens(); Loc = SM.getFileLoc(Loc); @@ -1142,7 +1147,7 @@ // We also show references to the targets of using-decls, so we include // DeclRelation::Underlying. -DeclRelationSet Relations = DeclRelation::TemplatePattern | +DeclRelationSet Relations = DeclRelation::TemplateInstantiation | DeclRelation::Alias | DeclRelation::Underlying; auto Decls = getDeclAtPosition(AST, *CurLoc, Relations); Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp === --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1570,7 +1570,7 @@ R"cpp( template - class [[Foo]] {}; + class Foo {}; void func([[Fo^o]]); )cpp", R"cpp(// Not touching any identifiers. @@ -1582,6 +1582,13 @@ f.[[^~]]Foo(); } )cpp", + R"cpp(// Temlate specialization +template class Vector {}; +using [[^X]] = [[Vector]]; +[[X]] x1; +[[Vector]] x2; +Vector y; + )cpp", }; for (const char *Test : Tests) { Annotations T(Test); Index: clang-tools-extra/clangd/XRefs.cpp === --- clang-tools-extra/clangd/XRefs.cpp +++ clang-tools-extra/clangd/XRefs.cpp @@ -767,7 +767,12 @@ index::IndexDataConsumer::ASTNodeInfo ASTNode) override { assert(D->isCanonicalDecl() && "expect D to be a canonical declaration"); const SourceManager &SM = AST.getSourceManager(); -if (!CanonicalTargets.count(D) || !isInsideMainFile(Loc, SM)) +// For references to template specializations, `D` will contain the +// template and `ASTNode.OrigD` the specialization. We want to find +// references to specializations, to check `ASTNode.OrigD` as well. +bool ReferencesCanonicalTarget = +CanonicalTargets.count(D) || CanonicalTargets.count(ASTNode.OrigD); +if (!ReferencesCanonicalTarget || !isInsideMainFile(Loc, SM)) return true; const auto &TB = AST.getTokens(); Loc = SM.getFileLoc(Loc); @@ -1142,7 +1147,7 @@ // We also show references to the targets of using-decls, so we include // DeclRelation::Underlying. -DeclRelationSet Relations = DeclRelation::TemplatePattern | +DeclRelationSet Relations = DeclRelation::TemplateInstantiation | DeclRelation::Alias | DeclRelation::Underlying; auto Decls = getDeclAtPosition(AST, *CurLoc, Relations); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D87080: [AST] Reduce the size of TemplateArgumentLocInfo.
hokein updated this revision to Diff 290187. hokein marked 2 inline comments as done. hokein added a comment. address review comments: - use PointerUnion - keep the TemplateArgumentLocInfo trivial, allocate from allocator, no deallocation. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87080/new/ https://reviews.llvm.org/D87080 Files: clang/include/clang/AST/TemplateBase.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Sema/SemaTemplateVariadic.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp Index: clang/lib/Serialization/ASTReader.cpp === --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -7103,15 +7103,15 @@ NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc(); SourceLocation TemplateNameLoc = readSourceLocation(); -return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, - SourceLocation()); +return TemplateArgumentLocInfo(getASTContext(), QualifierLoc, + TemplateNameLoc, SourceLocation()); } case TemplateArgument::TemplateExpansion: { NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc(); SourceLocation TemplateNameLoc = readSourceLocation(); SourceLocation EllipsisLoc = readSourceLocation(); -return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, - EllipsisLoc); +return TemplateArgumentLocInfo(getASTContext(), QualifierLoc, + TemplateNameLoc, EllipsisLoc); } case TemplateArgument::Null: case TemplateArgument::Integral: Index: clang/lib/Sema/TreeTransform.h === --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -3545,12 +3545,12 @@ } case TemplateArgument::Template: - return TemplateArgumentLoc(TemplateArgument( - Pattern.getArgument().getAsTemplate(), - NumExpansions), - Pattern.getTemplateQualifierLoc(), - Pattern.getTemplateNameLoc(), - EllipsisLoc); + return TemplateArgumentLoc( + SemaRef.Context, + TemplateArgument(Pattern.getArgument().getAsTemplate(), + NumExpansions), + Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(), + EllipsisLoc); case TemplateArgument::Null: case TemplateArgument::Integral: @@ -4288,8 +4288,8 @@ if (Template.isNull()) return true; -Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc, - Input.getTemplateNameLoc()); +Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template), + QualifierLoc, Input.getTemplateNameLoc()); return false; } Index: clang/lib/Sema/SemaTemplateVariadic.cpp === --- clang/lib/Sema/SemaTemplateVariadic.cpp +++ clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1095,7 +1095,7 @@ case TemplateArgument::TemplateExpansion: Ellipsis = OrigLoc.getTemplateEllipsisLoc(); NumExpansions = Argument.getNumTemplateExpansions(); -return TemplateArgumentLoc(Argument.getPackExpansionPattern(), +return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), OrigLoc.getTemplateQualifierLoc(), OrigLoc.getTemplateNameLoc()); Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp === --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2886,7 +2886,7 @@ if (!TName.isNull()) Param->setDefaultArgument( SemaRef.Context, - TemplateArgumentLoc(TemplateArgument(TName), + TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName), D->getDefaultArgument().getTemplateQualifierLoc(), D->getDefaultArgument().getTemplateNameLoc())); } Index: clang/lib/Sema/SemaTemplateDeduction.cpp === --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2670,11 +2670,11 @@ Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); if (Arg.getKind() == TemplateArgument::Template) -return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Co
[PATCH] D87080: [AST] Reduce the size of TemplateArgumentLocInfo.
hokein updated this revision to Diff 290188. hokein added a comment. format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87080/new/ https://reviews.llvm.org/D87080 Files: clang/include/clang/AST/TemplateBase.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Sema/SemaTemplateVariadic.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp Index: clang/lib/Serialization/ASTReader.cpp === --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -7103,15 +7103,15 @@ NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc(); SourceLocation TemplateNameLoc = readSourceLocation(); -return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, - SourceLocation()); +return TemplateArgumentLocInfo(getASTContext(), QualifierLoc, + TemplateNameLoc, SourceLocation()); } case TemplateArgument::TemplateExpansion: { NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc(); SourceLocation TemplateNameLoc = readSourceLocation(); SourceLocation EllipsisLoc = readSourceLocation(); -return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, - EllipsisLoc); +return TemplateArgumentLocInfo(getASTContext(), QualifierLoc, + TemplateNameLoc, EllipsisLoc); } case TemplateArgument::Null: case TemplateArgument::Integral: Index: clang/lib/Sema/TreeTransform.h === --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -3545,12 +3545,12 @@ } case TemplateArgument::Template: - return TemplateArgumentLoc(TemplateArgument( - Pattern.getArgument().getAsTemplate(), - NumExpansions), - Pattern.getTemplateQualifierLoc(), - Pattern.getTemplateNameLoc(), - EllipsisLoc); + return TemplateArgumentLoc( + SemaRef.Context, + TemplateArgument(Pattern.getArgument().getAsTemplate(), + NumExpansions), + Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(), + EllipsisLoc); case TemplateArgument::Null: case TemplateArgument::Integral: @@ -4288,8 +4288,8 @@ if (Template.isNull()) return true; -Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc, - Input.getTemplateNameLoc()); +Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template), + QualifierLoc, Input.getTemplateNameLoc()); return false; } Index: clang/lib/Sema/SemaTemplateVariadic.cpp === --- clang/lib/Sema/SemaTemplateVariadic.cpp +++ clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1095,7 +1095,7 @@ case TemplateArgument::TemplateExpansion: Ellipsis = OrigLoc.getTemplateEllipsisLoc(); NumExpansions = Argument.getNumTemplateExpansions(); -return TemplateArgumentLoc(Argument.getPackExpansionPattern(), +return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), OrigLoc.getTemplateQualifierLoc(), OrigLoc.getTemplateNameLoc()); Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp === --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2886,7 +2886,7 @@ if (!TName.isNull()) Param->setDefaultArgument( SemaRef.Context, - TemplateArgumentLoc(TemplateArgument(TName), + TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName), D->getDefaultArgument().getTemplateQualifierLoc(), D->getDefaultArgument().getTemplateNameLoc())); } Index: clang/lib/Sema/SemaTemplateDeduction.cpp === --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2670,11 +2670,11 @@ Builder.MakeTrivial(Context, QTN->getQualifier(), Loc); if (Arg.getKind() == TemplateArgument::Template) -return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(Context), - Loc); +return TemplateArgumentLoc(Context, Arg, + Builder.getWithLocInContext(Co