-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[KeyInstr] Add Atom Group waterline to LLVMContext #133478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-debuginfo Author: Orlando Cazalet-Hyams (OCHyams) ChangesThe waterline is managed through DILocation creation, Add unittest. Full diff: https://github.com/llvm/llvm-project/pull/133478.diff 5 Files Affected:
diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h
index bbd125fd38cf1..d3cdd31e0b12f 100644
--- a/llvm/include/llvm/IR/LLVMContext.h
+++ b/llvm/include/llvm/IR/LLVMContext.h
@@ -335,6 +335,14 @@ class LLVMContext {
StringRef getDefaultTargetFeatures();
void setDefaultTargetFeatures(StringRef Features);
+ /// Key Instructions: update the highest number atom group emitted for any
+ /// function.
+ void updateAtomGroupWaterline(uint64_t G);
+
+ /// Key Instructions: get the next free atom group number and increment
+ /// the global tracker.
+ uint64_t incNextAtomGroup();
+
private:
// Module needs access to the add/removeModule methods.
friend class Module;
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index f4f9fca38945c..aefda2f7be0b0 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -67,6 +67,9 @@ DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits");
#endif
+ if (AtomRank)
+ C.updateAtomGroupWaterline(AtomGroup + 1);
+
assert((MDs.size() == 1 || MDs.size() == 2) &&
"Expected a scope and optional inlined-at");
// Set line and column.
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index 447e5d92e0b99..4781085b30431 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -377,3 +377,11 @@ StringRef LLVMContext::getDefaultTargetFeatures() {
void LLVMContext::setDefaultTargetFeatures(StringRef Features) {
pImpl->DefaultTargetFeatures = Features;
}
+
+void LLVMContext::updateAtomGroupWaterline(uint64_t V) {
+ pImpl->NextAtomGroup = std::max(pImpl->NextAtomGroup, V);
+}
+
+uint64_t LLVMContext::incNextAtomGroup() {
+ return pImpl->NextAtomGroup++;
+}
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 99f0d8837de52..5a52d41834095 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1832,6 +1832,16 @@ class LLVMContextImpl {
std::string DefaultTargetCPU;
std::string DefaultTargetFeatures;
+
+ /// The next available source atom group number. The front end is responsible
+ /// for assigning source atom numbers, but certain optimisations need to
+ /// assign new group numbers to a set of instructions. Most often code
+ /// duplication optimisations like loop unroll. Tracking a global maximum
+ /// value means we can know (cheaply) we're never using a group number that's
+ /// already used within this function.
+ ///
+ /// Start a 1 because 0 means the source location isn't part of an atom group.
+ uint64_t NextAtomGroup = 1;
};
} // end namespace llvm
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 94cebb0406598..8a1c1f9d306c6 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "../lib/IR/LLVMContextImpl.h"
#include "llvm/IR/Metadata.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
@@ -1366,6 +1367,43 @@ TEST_F(DILocationTest, discriminatorSpecialCases) {
EXPECT_EQ(std::nullopt, L4->cloneByMultiplyingDuplicationFactor(0x1000));
}
+TEST_F(DILocationTest, KeyInstructions) {
+ Context.pImpl->NextAtomGroup = 1;
+
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 1u);
+ DILocation *A1 = DILocation::get(Context, 1, 0, getSubprogram(), nullptr, false, 1, 2);
+ // The group is only applied to the DILocation if the build has opted into
+ // the additional DILocation fields needed for the feature.
+#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
+ EXPECT_EQ(A1->getAtomGroup(), 1u);
+ EXPECT_EQ(A1->getAtomRank(), 2u);
+#else
+ EXPECT_EQ(A1->getAtomGroup(), 0u);
+ EXPECT_EQ(A1->getAtomRank(), 0u);
+#endif
+
+ // Group number 1 has been "used" so next available is 2.
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 2u);
+
+ // Set a group number higher than current + 1, then check the waterline.
+ DILocation::get(Context, 2, 0, getSubprogram(), nullptr, false, 5, 1);
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u);
+
+ // The waterline should be unchanged (group <= next).
+ DILocation::get(Context, 3, 0, getSubprogram(), nullptr, false, 4, 1);
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u);
+ DILocation::get(Context, 3, 0, getSubprogram(), nullptr, false, 5, 1);
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u);
+
+ // Check the waterline gets incremented by 1.
+ EXPECT_EQ(Context.incNextAtomGroup(), 6u);
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 7u);
+
+ Context.updateAtomGroupWaterline(8);
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 8u);
+ Context.updateAtomGroupWaterline(7);
+ EXPECT_EQ(Context.pImpl->NextAtomGroup, 8u);
+}
typedef MetadataTest GenericDINodeTest;
|
9c1e61e
to
c9c9826
Compare
70b9bbe
to
42fddab
Compare
The waterline is managed through DILocation creation, LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline. Add unittest.
47e9f41
to
93fa11d
Compare
Source location atoms are identified by a function-local number and the DILocation's InlinedAt field. The front end is responsible for assigning source atom numbers, but certain optimisations need to assign new atom numbers to some instructions. Most often code duplication optimisations like loop unroll. Tracking a global maximum value (waterline) means we can easily (cheaply) get new numbers that don't clash in any function. The waterline is managed through DILocation creation, LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline. Add unittest. RFC: https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
Source location atoms are identified by a function-local number and the DILocation's InlinedAt field. The front end is responsible for assigning source atom numbers, but certain optimisations need to assign new atom numbers to some instructions. Most often code duplication optimisations like loop unroll. Tracking a global maximum value (waterline) means we can easily (cheaply) get new numbers that don't clash in any function. The waterline is managed through DILocation creation, LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline. Add unittest. RFC: https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
Source location atoms are identified by a function-local number and the DILocation's InlinedAt field. The front end is responsible for assigning source atom numbers, but certain optimisations need to assign new atom numbers to some instructions. Most often code duplication optimisations like loop unroll. Tracking a global maximum value (waterline) means we can easily (cheaply) get new numbers that don't clash in any function. The waterline is managed through DILocation creation, LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline. Add unittest. RFC: https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
The waterline is managed through DILocation creation,
LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline.
Add unittest.