Skip to content

Commit fb45fc6

Browse files
bors[bot]vext01
andauthored
51: Gate our changes to the `.llvmbbaddrmap` section. r=ltratt a=vext01 Co-authored-by: Edd Barrett <[email protected]>
2 parents 42490d3 + c75eec9 commit fb45fc6

File tree

3 files changed

+137
-136
lines changed

3 files changed

+137
-136
lines changed

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

+128-120
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ static cl::opt<bool>
134134
"optimisations and transformations have run."));
135135

136136
extern bool YkAllocLLVMBBAddrMapSection;
137+
extern bool YkExtendedLLVMBBAddrMapSection;
137138

138139
const char DWARFGroupName[] = "dwarf";
139140
const char DWARFGroupDescription[] = "DWARF Emission";
@@ -1438,141 +1439,147 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
14381439
emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
14391440
OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
14401441
PrevMBBEndSymbol = MBB.getEndSymbol();
1441-
// Find BBs corresponding with this MBB as described above.
1442-
const BasicBlock *CorrBB = MBB.getBasicBlock();
1443-
std::vector<const BasicBlock *> CorrBBs;
1444-
while (CorrBB != nullptr) {
1445-
CorrBBs.push_back(CorrBB);
1446-
const Instruction *Term = CorrBB->getTerminator();
1447-
assert(Term != nullptr);
1448-
if ((isa<BranchInst>(Term)) &&
1449-
(!(dyn_cast<const BranchInst>(Term))->isConditional())) {
1450-
CorrBB = CorrBB->getUniqueSuccessor();
1451-
assert(CorrBB != nullptr);
1452-
if (MergedBBs.count(CorrBB) == 0) {
1442+
1443+
if (YkExtendedLLVMBBAddrMapSection) {
1444+
// Find BBs corresponding with this MBB as described above.
1445+
const BasicBlock *CorrBB = MBB.getBasicBlock();
1446+
std::vector<const BasicBlock *> CorrBBs;
1447+
while (CorrBB != nullptr) {
1448+
CorrBBs.push_back(CorrBB);
1449+
const Instruction *Term = CorrBB->getTerminator();
1450+
assert(Term != nullptr);
1451+
if ((isa<BranchInst>(Term)) &&
1452+
(!(dyn_cast<const BranchInst>(Term))->isConditional())) {
1453+
CorrBB = CorrBB->getUniqueSuccessor();
1454+
assert(CorrBB != nullptr);
1455+
if (MergedBBs.count(CorrBB) == 0) {
1456+
CorrBB = nullptr;
1457+
}
1458+
} else {
14531459
CorrBB = nullptr;
14541460
}
1455-
} else {
1456-
CorrBB = nullptr;
14571461
}
1458-
}
1459-
// Emit the number of corresponding BasicBlocks.
1460-
OutStreamer->emitULEB128IntValue(CorrBBs.size());
1461-
// Emit the corresponding block indices.
1462-
for (auto CorrBB : CorrBBs) {
1463-
size_t I = 0;
1464-
bool Found = false;
1465-
for (auto It = F.begin(); It != F.end(); It++) {
1466-
const BasicBlock *BB = &*It;
1467-
if (BB == CorrBB) {
1468-
Found = true;
1469-
break;
1462+
// Emit the number of corresponding BasicBlocks.
1463+
OutStreamer->emitULEB128IntValue(CorrBBs.size());
1464+
// Emit the corresponding block indices.
1465+
for (auto CorrBB : CorrBBs) {
1466+
size_t I = 0;
1467+
bool Found = false;
1468+
for (auto It = F.begin(); It != F.end(); It++) {
1469+
const BasicBlock *BB = &*It;
1470+
if (BB == CorrBB) {
1471+
Found = true;
1472+
break;
1473+
}
1474+
I++;
14701475
}
1471-
I++;
1476+
if (!Found)
1477+
OutContext.reportError(SMLoc(), "Couldn't find the block's index");
1478+
OutStreamer->emitULEB128IntValue(I);
14721479
}
1473-
if (!Found)
1474-
OutContext.reportError(SMLoc(), "Couldn't find the block's index");
1475-
OutStreamer->emitULEB128IntValue(I);
1476-
}
14771480

1478-
// Emit call marker table for the Yk JIT.
1479-
//
1480-
// The table is a size header, followed by call instruction addresses.
1481-
//
1482-
// YKOPT: to save space, instead of using absolute symbol addresses, compute
1483-
// the distance from the start of the block and use uleb128 encoding.
1484-
const size_t NumCalls = YkCallMarkerSyms[&MBB].size();
1485-
OutStreamer->emitULEB128IntValue(NumCalls);
1486-
for (auto Tup : YkCallMarkerSyms[&MBB]) {
1487-
// Emit address of the call instruction.
1488-
OutStreamer->emitSymbolValue(std::get<0>(Tup), getPointerSize());
1489-
// Emit address of target if known, or 0.
1490-
MCSymbol *Target = std::get<1>(Tup);
1491-
if (Target)
1492-
OutStreamer->emitSymbolValue(Target, getPointerSize());
1493-
else
1494-
OutStreamer->emitIntValue(0, getPointerSize());
1495-
}
1481+
// Emit call marker table for the Yk JIT.
1482+
//
1483+
// The table is a size header, followed by call instruction addresses.
1484+
//
1485+
// YKOPT: to save space, instead of using absolute symbol addresses,
1486+
// compute the distance from the start of the block and use uleb128
1487+
// encoding.
1488+
const size_t NumCalls = YkCallMarkerSyms[&MBB].size();
1489+
OutStreamer->emitULEB128IntValue(NumCalls);
1490+
for (auto Tup : YkCallMarkerSyms[&MBB]) {
1491+
// Emit address of the call instruction.
1492+
OutStreamer->emitSymbolValue(std::get<0>(Tup), getPointerSize());
1493+
// Emit address of target if known, or 0.
1494+
MCSymbol *Target = std::get<1>(Tup);
1495+
if (Target)
1496+
OutStreamer->emitSymbolValue(Target, getPointerSize());
1497+
else
1498+
OutStreamer->emitIntValue(0, getPointerSize());
1499+
}
14961500

1497-
// Emit successor information.
1498-
//
1499-
// Each codegenned block gets a record indicating any statically known
1500-
// successors. The record starts with a `SuccessorKind` byte:
1501-
enum SuccessorKind {
1502-
// One successor.
1503-
Unconditional = 0,
1504-
// Choice of two successors.
1505-
Conditional = 1,
1506-
// A control flow edge known only at runtime, e.g. a return or an indirect
1507-
// branch.
1508-
Dynamic = 2,
1509-
};
1510-
1511-
// Then depending of the `SuccessorKind` there is a payload describing the
1512-
// successors:
1513-
//
1514-
// `Unconditional`: [target-address: u64]
1515-
// `Conditional`: [taken-address: u64, not-taken-address: u64]
1516-
// `Dynamic`: [] (i.e. nothing, because nothing is statically known)
1517-
1518-
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
1519-
SmallVector<MachineOperand> Conds;
1520-
1521-
if (!TI->analyzeBranch(const_cast<MachineBasicBlock &>(MBB), TBB, FBB,
1522-
Conds)) {
1523-
// The block ends with a branch or a fall-thru.
1524-
if (!TBB && !FBB) {
1525-
// Both null: block has no terminator and either falls through or
1526-
// diverges.
1527-
OutStreamer->emitInt8(Unconditional);
1528-
MachineBasicBlock *ThruBB = findFallthruBlock(&MBB);
1529-
if (ThruBB) {
1530-
OutStreamer->emitSymbolValue(BBSym(ThruBB, FunctionSymbol),
1531-
getPointerSize());
1532-
} else {
1533-
OutStreamer->emitInt64(0); // Divergent.
1534-
}
1535-
} else if (TBB && !FBB) {
1536-
// Only FBB null: block either ends with an unconditional branch or a
1537-
// conditional branch whose false arm falls through or diverges.
1538-
if (Conds.empty()) {
1539-
// No conditions: unconditional branch.
1501+
// Emit successor information.
1502+
//
1503+
// Each codegenned block gets a record indicating any statically known
1504+
// successors. The record starts with a `SuccessorKind` byte:
1505+
enum SuccessorKind {
1506+
// One successor.
1507+
Unconditional = 0,
1508+
// Choice of two successors.
1509+
Conditional = 1,
1510+
// A control flow edge known only at runtime, e.g. a return or an
1511+
// indirect
1512+
// branch.
1513+
Dynamic = 2,
1514+
};
1515+
1516+
// Then depending of the `SuccessorKind` there is a payload describing the
1517+
// successors:
1518+
//
1519+
// `Unconditional`: [target-address: u64]
1520+
// `Conditional`: [taken-address: u64, not-taken-address: u64]
1521+
// `Dynamic`: [] (i.e. nothing, because nothing is statically known)
1522+
1523+
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
1524+
SmallVector<MachineOperand> Conds;
1525+
1526+
if (!TI->analyzeBranch(const_cast<MachineBasicBlock &>(MBB), TBB, FBB,
1527+
Conds)) {
1528+
// The block ends with a branch or a fall-thru.
1529+
if (!TBB && !FBB) {
1530+
// Both null: block has no terminator and either falls through or
1531+
// diverges.
15401532
OutStreamer->emitInt8(Unconditional);
1541-
OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol),
1542-
getPointerSize());
1543-
} else {
1544-
// Has conditions: conditional branch followed by fallthru or
1545-
// divergence.
15461533
MachineBasicBlock *ThruBB = findFallthruBlock(&MBB);
1547-
OutStreamer->emitInt8(Conditional);
1548-
OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol),
1549-
getPointerSize());
15501534
if (ThruBB) {
15511535
OutStreamer->emitSymbolValue(BBSym(ThruBB, FunctionSymbol),
15521536
getPointerSize());
15531537
} else {
15541538
OutStreamer->emitInt64(0); // Divergent.
15551539
}
1540+
} else if (TBB && !FBB) {
1541+
// Only FBB null: block either ends with an unconditional branch or a
1542+
// conditional branch whose false arm falls through or diverges.
1543+
if (Conds.empty()) {
1544+
// No conditions: unconditional branch.
1545+
OutStreamer->emitInt8(Unconditional);
1546+
OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol),
1547+
getPointerSize());
1548+
} else {
1549+
// Has conditions: conditional branch followed by fallthru or
1550+
// divergence.
1551+
MachineBasicBlock *ThruBB = findFallthruBlock(&MBB);
1552+
OutStreamer->emitInt8(Conditional);
1553+
OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol),
1554+
getPointerSize());
1555+
if (ThruBB) {
1556+
OutStreamer->emitSymbolValue(BBSym(ThruBB, FunctionSymbol),
1557+
getPointerSize());
1558+
} else {
1559+
OutStreamer->emitInt64(0); // Divergent.
1560+
}
1561+
}
1562+
} else {
1563+
// Conditional branch followed by an unconditional branch.
1564+
assert(TBB && FBB);
1565+
OutStreamer->emitInt8(Conditional);
1566+
OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol),
1567+
getPointerSize());
1568+
OutStreamer->emitSymbolValue(BBSym(FBB, FunctionSymbol),
1569+
getPointerSize());
15561570
}
15571571
} else {
1558-
// Conditional branch followed by an unconditional branch.
1559-
assert(TBB && FBB);
1560-
OutStreamer->emitInt8(Conditional);
1561-
OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol),
1562-
getPointerSize());
1563-
OutStreamer->emitSymbolValue(BBSym(FBB, FunctionSymbol),
1564-
getPointerSize());
1565-
}
1566-
} else {
1567-
// Wasn't a branch or a fall-thru. Must be a different kind of terminator.
1568-
const MachineInstr *LastI = &*MBB.instr_rbegin();
1569-
if (LastI->isReturn() || LastI->isIndirectBranch()) {
1570-
OutStreamer->emitInt8(Dynamic);
1571-
} else {
1572-
std::string Msg = "unhandled block terminator in block: ";
1573-
raw_string_ostream OS(Msg);
1574-
LastI->print(OS);
1575-
OutContext.reportError(SMLoc(), Msg);
1572+
// Wasn't a branch or a fall-thru. Must be a different kind of
1573+
// terminator.
1574+
const MachineInstr *LastI = &*MBB.instr_rbegin();
1575+
if (LastI->isReturn() || LastI->isIndirectBranch()) {
1576+
OutStreamer->emitInt8(Dynamic);
1577+
} else {
1578+
std::string Msg = "unhandled block terminator in block: ";
1579+
raw_string_ostream OS(Msg);
1580+
LastI->print(OS);
1581+
OutContext.reportError(SMLoc(), Msg);
1582+
}
15761583
}
15771584
}
15781585
}
@@ -1697,7 +1704,8 @@ void AsmPrinter::emitFunctionBody() {
16971704
// Print a label for the basic block.
16981705
emitBasicBlockStart(MBB);
16991706

1700-
YkCallMarkerSyms.insert({&MBB, {}});
1707+
if (YkExtendedLLVMBBAddrMapSection)
1708+
YkCallMarkerSyms.insert({&MBB, {}});
17011709

17021710
DenseMap<StringRef, unsigned> MnemonicCounts;
17031711
for (auto &MI : MBB) {
@@ -1774,7 +1782,7 @@ void AsmPrinter::emitFunctionBody() {
17741782
break;
17751783
default:
17761784

1777-
if (YkAllocLLVMBBAddrMapSection && MI.isCall() &&
1785+
if (YkExtendedLLVMBBAddrMapSection && MI.isCall() &&
17781786
(MI.getOpcode() != TargetOpcode::STACKMAP) &&
17791787
(MI.getOpcode() != TargetOpcode::PATCHPOINT) &&
17801788
(MI.getOpcode() != TargetOpcode::STATEPOINT)) {

llvm/lib/Support/Yk.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ static cl::opt<bool, true> YkAllocLLVMBBAddrMapSectionParser(
1212
"yk-alloc-llvmbbaddrmap-section",
1313
cl::desc("Make the `.llvmbbaddrmap` section loadable"), cl::NotHidden,
1414
cl::location(YkAllocLLVMBBAddrMapSection));
15+
16+
bool YkExtendedLLVMBBAddrMapSection;
17+
static cl::opt<bool, true> YkExtendedLLVMBBAddrMapSectionParser(
18+
"yk-extended-llvmbbaddrmap-section",
19+
cl::desc("Use the extended Yk `.llvmbbaddrmap` section format"),
20+
cl::NotHidden, cl::location(YkExtendedLLVMBBAddrMapSection));

llvm/test/CodeGen/X86/basic-block-sections-labels.ll

+3-16
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,12 @@ declare i32 @__gxx_personality_v0(...)
5353
; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0
5454
; CHECK-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0
5555
; CHECK-NEXT: .byte 8
56-
; CHECK-NEXT: .byte 1
57-
; CHECK-NEXT: .byte 0
58-
; ...calls and successor info for Yk JIT...
59-
; CHECK: .uleb128 .LBB0_1-.LBB_END0_0
56+
; CHECK-NEXT: .uleb128 .LBB0_1-.LBB_END0_0
6057
; CHECK-NEXT: .uleb128 .LBB_END0_1-.LBB0_1
6158
; CHECK-NEXT: .byte 8
62-
; CHECK-NEXT: .byte 1
63-
; CHECK-NEXT: .byte 1
64-
; ...calls and successor info for Yk JIT...
65-
; CHECK: .uleb128 .LBB0_2-.LBB_END0_1
59+
; CHECK-NEXT: .uleb128 .LBB0_2-.LBB_END0_1
6660
; CHECK-NEXT: .uleb128 .LBB_END0_2-.LBB0_2
6761
; CHECK-NEXT: .byte 1
68-
; CHECK-NEXT: .byte 2
69-
; CHECK-NEXT: .byte 3
70-
; CHECK-NEXT: .byte 4
71-
; ...calls and successor info for Yk JIT...
72-
; CHECK: .uleb128 .LBB0_3-.LBB_END0_2
62+
; CHECK-NEXT: .uleb128 .LBB0_3-.LBB_END0_2
7363
; CHECK-NEXT: .uleb128 .LBB_END0_3-.LBB0_3
7464
; CHECK-NEXT: .byte 5
75-
; CHECK-NEXT: .byte 2
76-
; CHECK-NEXT: .byte 2
77-
; CHECK-NEXT: .byte 4

0 commit comments

Comments
 (0)