Skip to content

Commit a4e97d1

Browse files
committed
[KeyInstr] Add Atom Group waterline to LLVMContext
The waterline is managed through DILocation creation, LLVMContext::incNextAtomGroup, and LLVMContext::updateAtomGroupWaterline. Add unittest.
1 parent 42fddab commit a4e97d1

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,14 @@ class LLVMContext {
335335
StringRef getDefaultTargetFeatures();
336336
void setDefaultTargetFeatures(StringRef Features);
337337

338+
/// Key Instructions: update the highest number atom group emitted for any
339+
/// function.
340+
void updateAtomGroupWaterline(uint64_t G);
341+
342+
/// Key Instructions: get the next free atom group number and increment
343+
/// the global tracker.
344+
uint64_t incNextAtomGroup();
345+
338346
private:
339347
// Module needs access to the add/removeModule methods.
340348
friend class Module;

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
7474
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
7575
assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits");
7676
#endif
77+
if (AtomRank)
78+
C.updateAtomGroupWaterline(AtomGroup + 1);
79+
7780
assert((MDs.size() == 1 || MDs.size() == 2) &&
7881
"Expected a scope and optional inlined-at");
7982
// Set line and column.

llvm/lib/IR/LLVMContext.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,11 @@ StringRef LLVMContext::getDefaultTargetFeatures() {
377377
void LLVMContext::setDefaultTargetFeatures(StringRef Features) {
378378
pImpl->DefaultTargetFeatures = Features;
379379
}
380+
381+
void LLVMContext::updateAtomGroupWaterline(uint64_t V) {
382+
pImpl->NextAtomGroup = std::max(pImpl->NextAtomGroup, V);
383+
}
384+
385+
uint64_t LLVMContext::incNextAtomGroup() {
386+
return pImpl->NextAtomGroup++;
387+
}

llvm/lib/IR/LLVMContextImpl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,6 +1858,16 @@ class LLVMContextImpl {
18581858

18591859
std::string DefaultTargetCPU;
18601860
std::string DefaultTargetFeatures;
1861+
1862+
/// The next available source atom group number. The front end is responsible
1863+
/// for assigning source atom numbers, but certain optimisations need to
1864+
/// assign new group numbers to a set of instructions. Most often code
1865+
/// duplication optimisations like loop unroll. Tracking a global maximum
1866+
/// value means we can know (cheaply) we're never using a group number that's
1867+
/// already used within this function.
1868+
///
1869+
/// Start a 1 because 0 means the source location isn't part of an atom group.
1870+
uint64_t NextAtomGroup = 1;
18611871
};
18621872

18631873
} // end namespace llvm

llvm/unittests/IR/MetadataTest.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "../lib/IR/LLVMContextImpl.h"
910
#include "llvm/IR/Metadata.h"
1011
#include "llvm/ADT/DenseMap.h"
1112
#include "llvm/ADT/STLExtras.h"
@@ -1568,6 +1569,43 @@ TEST_F(DILocationTest, discriminatorSpecialCases) {
15681569
EXPECT_EQ(std::nullopt, L4->cloneByMultiplyingDuplicationFactor(0x1000));
15691570
}
15701571

1572+
TEST_F(DILocationTest, KeyInstructions) {
1573+
Context.pImpl->NextAtomGroup = 1;
1574+
1575+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 1u);
1576+
DILocation *A1 = DILocation::get(Context, 1, 0, getSubprogram(), nullptr, false, 1, 2);
1577+
// The group is only applied to the DILocation if the build has opted into
1578+
// the additional DILocation fields needed for the feature.
1579+
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
1580+
EXPECT_EQ(A1->getAtomGroup(), 1u);
1581+
EXPECT_EQ(A1->getAtomRank(), 2u);
1582+
#else
1583+
EXPECT_EQ(A1->getAtomGroup(), 0u);
1584+
EXPECT_EQ(A1->getAtomRank(), 0u);
1585+
#endif
1586+
1587+
// Group number 1 has been "used" so next available is 2.
1588+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 2u);
1589+
1590+
// Set a group number higher than current + 1, then check the waterline.
1591+
DILocation::get(Context, 2, 0, getSubprogram(), nullptr, false, 5, 1);
1592+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u);
1593+
1594+
// The waterline should be unchanged (group <= next).
1595+
DILocation::get(Context, 3, 0, getSubprogram(), nullptr, false, 4, 1);
1596+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u);
1597+
DILocation::get(Context, 3, 0, getSubprogram(), nullptr, false, 5, 1);
1598+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 6u);
1599+
1600+
// Check the waterline gets incremented by 1.
1601+
EXPECT_EQ(Context.incNextAtomGroup(), 6u);
1602+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 7u);
1603+
1604+
Context.updateAtomGroupWaterline(8);
1605+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 8u);
1606+
Context.updateAtomGroupWaterline(7);
1607+
EXPECT_EQ(Context.pImpl->NextAtomGroup, 8u);
1608+
}
15711609

15721610
typedef MetadataTest GenericDINodeTest;
15731611

0 commit comments

Comments
 (0)