From c75eec9fa7a2110a1691bdb318b05e0ecf3bd44c Mon Sep 17 00:00:00 2001 From: Edd Barrett Date: Fri, 25 Nov 2022 15:02:04 +0000 Subject: [PATCH] Gate our extensions to the llvm block map. This allows us to use upstream's test unchanged. --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 248 +++++++++--------- llvm/lib/Support/Yk.cpp | 6 + .../X86/basic-block-sections-labels.ll | 19 +- 3 files changed, 137 insertions(+), 136 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 6c744d17b42b4f..271daca5a821ae 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -134,6 +134,7 @@ static cl::opt "optimisations and transformations have run.")); extern bool YkAllocLLVMBBAddrMapSection; +extern bool YkExtendedLLVMBBAddrMapSection; const char DWARFGroupName[] = "dwarf"; const char DWARFGroupDescription[] = "DWARF Emission"; @@ -1438,141 +1439,147 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol); OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB)); PrevMBBEndSymbol = MBB.getEndSymbol(); - // Find BBs corresponding with this MBB as described above. - const BasicBlock *CorrBB = MBB.getBasicBlock(); - std::vector CorrBBs; - while (CorrBB != nullptr) { - CorrBBs.push_back(CorrBB); - const Instruction *Term = CorrBB->getTerminator(); - assert(Term != nullptr); - if ((isa(Term)) && - (!(dyn_cast(Term))->isConditional())) { - CorrBB = CorrBB->getUniqueSuccessor(); - assert(CorrBB != nullptr); - if (MergedBBs.count(CorrBB) == 0) { + + if (YkExtendedLLVMBBAddrMapSection) { + // Find BBs corresponding with this MBB as described above. + const BasicBlock *CorrBB = MBB.getBasicBlock(); + std::vector CorrBBs; + while (CorrBB != nullptr) { + CorrBBs.push_back(CorrBB); + const Instruction *Term = CorrBB->getTerminator(); + assert(Term != nullptr); + if ((isa(Term)) && + (!(dyn_cast(Term))->isConditional())) { + CorrBB = CorrBB->getUniqueSuccessor(); + assert(CorrBB != nullptr); + if (MergedBBs.count(CorrBB) == 0) { + CorrBB = nullptr; + } + } else { CorrBB = nullptr; } - } else { - CorrBB = nullptr; } - } - // Emit the number of corresponding BasicBlocks. - OutStreamer->emitULEB128IntValue(CorrBBs.size()); - // Emit the corresponding block indices. - for (auto CorrBB : CorrBBs) { - size_t I = 0; - bool Found = false; - for (auto It = F.begin(); It != F.end(); It++) { - const BasicBlock *BB = &*It; - if (BB == CorrBB) { - Found = true; - break; + // Emit the number of corresponding BasicBlocks. + OutStreamer->emitULEB128IntValue(CorrBBs.size()); + // Emit the corresponding block indices. + for (auto CorrBB : CorrBBs) { + size_t I = 0; + bool Found = false; + for (auto It = F.begin(); It != F.end(); It++) { + const BasicBlock *BB = &*It; + if (BB == CorrBB) { + Found = true; + break; + } + I++; } - I++; + if (!Found) + OutContext.reportError(SMLoc(), "Couldn't find the block's index"); + OutStreamer->emitULEB128IntValue(I); } - if (!Found) - OutContext.reportError(SMLoc(), "Couldn't find the block's index"); - OutStreamer->emitULEB128IntValue(I); - } - // Emit call marker table for the Yk JIT. - // - // The table is a size header, followed by call instruction addresses. - // - // YKOPT: to save space, instead of using absolute symbol addresses, compute - // the distance from the start of the block and use uleb128 encoding. - const size_t NumCalls = YkCallMarkerSyms[&MBB].size(); - OutStreamer->emitULEB128IntValue(NumCalls); - for (auto Tup : YkCallMarkerSyms[&MBB]) { - // Emit address of the call instruction. - OutStreamer->emitSymbolValue(std::get<0>(Tup), getPointerSize()); - // Emit address of target if known, or 0. - MCSymbol *Target = std::get<1>(Tup); - if (Target) - OutStreamer->emitSymbolValue(Target, getPointerSize()); - else - OutStreamer->emitIntValue(0, getPointerSize()); - } + // Emit call marker table for the Yk JIT. + // + // The table is a size header, followed by call instruction addresses. + // + // YKOPT: to save space, instead of using absolute symbol addresses, + // compute the distance from the start of the block and use uleb128 + // encoding. + const size_t NumCalls = YkCallMarkerSyms[&MBB].size(); + OutStreamer->emitULEB128IntValue(NumCalls); + for (auto Tup : YkCallMarkerSyms[&MBB]) { + // Emit address of the call instruction. + OutStreamer->emitSymbolValue(std::get<0>(Tup), getPointerSize()); + // Emit address of target if known, or 0. + MCSymbol *Target = std::get<1>(Tup); + if (Target) + OutStreamer->emitSymbolValue(Target, getPointerSize()); + else + OutStreamer->emitIntValue(0, getPointerSize()); + } - // Emit successor information. - // - // Each codegenned block gets a record indicating any statically known - // successors. The record starts with a `SuccessorKind` byte: - enum SuccessorKind { - // One successor. - Unconditional = 0, - // Choice of two successors. - Conditional = 1, - // A control flow edge known only at runtime, e.g. a return or an indirect - // branch. - Dynamic = 2, - }; - - // Then depending of the `SuccessorKind` there is a payload describing the - // successors: - // - // `Unconditional`: [target-address: u64] - // `Conditional`: [taken-address: u64, not-taken-address: u64] - // `Dynamic`: [] (i.e. nothing, because nothing is statically known) - - MachineBasicBlock *TBB = nullptr, *FBB = nullptr; - SmallVector Conds; - - if (!TI->analyzeBranch(const_cast(MBB), TBB, FBB, - Conds)) { - // The block ends with a branch or a fall-thru. - if (!TBB && !FBB) { - // Both null: block has no terminator and either falls through or - // diverges. - OutStreamer->emitInt8(Unconditional); - MachineBasicBlock *ThruBB = findFallthruBlock(&MBB); - if (ThruBB) { - OutStreamer->emitSymbolValue(BBSym(ThruBB, FunctionSymbol), - getPointerSize()); - } else { - OutStreamer->emitInt64(0); // Divergent. - } - } else if (TBB && !FBB) { - // Only FBB null: block either ends with an unconditional branch or a - // conditional branch whose false arm falls through or diverges. - if (Conds.empty()) { - // No conditions: unconditional branch. + // Emit successor information. + // + // Each codegenned block gets a record indicating any statically known + // successors. The record starts with a `SuccessorKind` byte: + enum SuccessorKind { + // One successor. + Unconditional = 0, + // Choice of two successors. + Conditional = 1, + // A control flow edge known only at runtime, e.g. a return or an + // indirect + // branch. + Dynamic = 2, + }; + + // Then depending of the `SuccessorKind` there is a payload describing the + // successors: + // + // `Unconditional`: [target-address: u64] + // `Conditional`: [taken-address: u64, not-taken-address: u64] + // `Dynamic`: [] (i.e. nothing, because nothing is statically known) + + MachineBasicBlock *TBB = nullptr, *FBB = nullptr; + SmallVector Conds; + + if (!TI->analyzeBranch(const_cast(MBB), TBB, FBB, + Conds)) { + // The block ends with a branch or a fall-thru. + if (!TBB && !FBB) { + // Both null: block has no terminator and either falls through or + // diverges. OutStreamer->emitInt8(Unconditional); - OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol), - getPointerSize()); - } else { - // Has conditions: conditional branch followed by fallthru or - // divergence. MachineBasicBlock *ThruBB = findFallthruBlock(&MBB); - OutStreamer->emitInt8(Conditional); - OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol), - getPointerSize()); if (ThruBB) { OutStreamer->emitSymbolValue(BBSym(ThruBB, FunctionSymbol), getPointerSize()); } else { OutStreamer->emitInt64(0); // Divergent. } + } else if (TBB && !FBB) { + // Only FBB null: block either ends with an unconditional branch or a + // conditional branch whose false arm falls through or diverges. + if (Conds.empty()) { + // No conditions: unconditional branch. + OutStreamer->emitInt8(Unconditional); + OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol), + getPointerSize()); + } else { + // Has conditions: conditional branch followed by fallthru or + // divergence. + MachineBasicBlock *ThruBB = findFallthruBlock(&MBB); + OutStreamer->emitInt8(Conditional); + OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol), + getPointerSize()); + if (ThruBB) { + OutStreamer->emitSymbolValue(BBSym(ThruBB, FunctionSymbol), + getPointerSize()); + } else { + OutStreamer->emitInt64(0); // Divergent. + } + } + } else { + // Conditional branch followed by an unconditional branch. + assert(TBB && FBB); + OutStreamer->emitInt8(Conditional); + OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol), + getPointerSize()); + OutStreamer->emitSymbolValue(BBSym(FBB, FunctionSymbol), + getPointerSize()); } } else { - // Conditional branch followed by an unconditional branch. - assert(TBB && FBB); - OutStreamer->emitInt8(Conditional); - OutStreamer->emitSymbolValue(BBSym(TBB, FunctionSymbol), - getPointerSize()); - OutStreamer->emitSymbolValue(BBSym(FBB, FunctionSymbol), - getPointerSize()); - } - } else { - // Wasn't a branch or a fall-thru. Must be a different kind of terminator. - const MachineInstr *LastI = &*MBB.instr_rbegin(); - if (LastI->isReturn() || LastI->isIndirectBranch()) { - OutStreamer->emitInt8(Dynamic); - } else { - std::string Msg = "unhandled block terminator in block: "; - raw_string_ostream OS(Msg); - LastI->print(OS); - OutContext.reportError(SMLoc(), Msg); + // Wasn't a branch or a fall-thru. Must be a different kind of + // terminator. + const MachineInstr *LastI = &*MBB.instr_rbegin(); + if (LastI->isReturn() || LastI->isIndirectBranch()) { + OutStreamer->emitInt8(Dynamic); + } else { + std::string Msg = "unhandled block terminator in block: "; + raw_string_ostream OS(Msg); + LastI->print(OS); + OutContext.reportError(SMLoc(), Msg); + } } } } @@ -1697,7 +1704,8 @@ void AsmPrinter::emitFunctionBody() { // Print a label for the basic block. emitBasicBlockStart(MBB); - YkCallMarkerSyms.insert({&MBB, {}}); + if (YkExtendedLLVMBBAddrMapSection) + YkCallMarkerSyms.insert({&MBB, {}}); DenseMap MnemonicCounts; for (auto &MI : MBB) { @@ -1774,7 +1782,7 @@ void AsmPrinter::emitFunctionBody() { break; default: - if (YkAllocLLVMBBAddrMapSection && MI.isCall() && + if (YkExtendedLLVMBBAddrMapSection && MI.isCall() && (MI.getOpcode() != TargetOpcode::STACKMAP) && (MI.getOpcode() != TargetOpcode::PATCHPOINT) && (MI.getOpcode() != TargetOpcode::STATEPOINT)) { diff --git a/llvm/lib/Support/Yk.cpp b/llvm/lib/Support/Yk.cpp index 3f0e67b123c09a..3ee43cc04088df 100644 --- a/llvm/lib/Support/Yk.cpp +++ b/llvm/lib/Support/Yk.cpp @@ -12,3 +12,9 @@ static cl::opt YkAllocLLVMBBAddrMapSectionParser( "yk-alloc-llvmbbaddrmap-section", cl::desc("Make the `.llvmbbaddrmap` section loadable"), cl::NotHidden, cl::location(YkAllocLLVMBBAddrMapSection)); + +bool YkExtendedLLVMBBAddrMapSection; +static cl::opt YkExtendedLLVMBBAddrMapSectionParser( + "yk-extended-llvmbbaddrmap-section", + cl::desc("Use the extended Yk `.llvmbbaddrmap` section format"), + cl::NotHidden, cl::location(YkExtendedLLVMBBAddrMapSection)); diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll index 636b1ee9364b01..64be9010524915 100644 --- a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll @@ -53,25 +53,12 @@ declare i32 @__gxx_personality_v0(...) ; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 ; CHECK-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0 ; CHECK-NEXT: .byte 8 -; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 0 -; ...calls and successor info for Yk JIT... -; CHECK: .uleb128 .LBB0_1-.LBB_END0_0 +; CHECK-NEXT: .uleb128 .LBB0_1-.LBB_END0_0 ; CHECK-NEXT: .uleb128 .LBB_END0_1-.LBB0_1 ; CHECK-NEXT: .byte 8 -; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 1 -; ...calls and successor info for Yk JIT... -; CHECK: .uleb128 .LBB0_2-.LBB_END0_1 +; CHECK-NEXT: .uleb128 .LBB0_2-.LBB_END0_1 ; CHECK-NEXT: .uleb128 .LBB_END0_2-.LBB0_2 ; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 2 -; CHECK-NEXT: .byte 3 -; CHECK-NEXT: .byte 4 -; ...calls and successor info for Yk JIT... -; CHECK: .uleb128 .LBB0_3-.LBB_END0_2 +; CHECK-NEXT: .uleb128 .LBB0_3-.LBB_END0_2 ; CHECK-NEXT: .uleb128 .LBB_END0_3-.LBB0_3 ; CHECK-NEXT: .byte 5 -; CHECK-NEXT: .byte 2 -; CHECK-NEXT: .byte 2 -; CHECK-NEXT: .byte 4