diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -1028,11 +1028,10 @@ /// /// This is allocated on the function's allocator and so lives the life of /// the function. - MachineInstr::ExtraInfo * - createMIExtraInfo(ArrayRef MMOs, - MCSymbol *PreInstrSymbol = nullptr, - MCSymbol *PostInstrSymbol = nullptr, - MDNode *HeapAllocMarker = nullptr, uint32_t CFIType = 0); + MachineInstr::ExtraInfo *createMIExtraInfo( + ArrayRef MMOs, MCSymbol *PreInstrSymbol = nullptr, + MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr, + MDNode *PCSections = nullptr, uint32_t CFIType = 0); /// Allocate a string and populate it with the given external symbol name. const char *createExternalSymbolName(StringRef Name); diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -152,18 +152,20 @@ MCSymbol *PreInstrSymbol = nullptr, MCSymbol *PostInstrSymbol = nullptr, MDNode *HeapAllocMarker = nullptr, + MDNode *PCSections = nullptr, uint32_t CFIType = 0) { bool HasPreInstrSymbol = PreInstrSymbol != nullptr; bool HasPostInstrSymbol = PostInstrSymbol != nullptr; bool HasHeapAllocMarker = HeapAllocMarker != nullptr; bool HasCFIType = CFIType != 0; + bool HasPCSections = PCSections != nullptr; auto *Result = new (Allocator.Allocate( totalSizeToAlloc( MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol, - HasHeapAllocMarker, HasCFIType), + HasHeapAllocMarker + HasPCSections, HasCFIType), alignof(ExtraInfo))) ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol, - HasHeapAllocMarker, HasCFIType); + HasHeapAllocMarker, HasPCSections, HasCFIType); // Copy the actual data into the trailing objects. std::copy(MMOs.begin(), MMOs.end(), @@ -176,6 +178,9 @@ PostInstrSymbol; if (HasHeapAllocMarker) Result->getTrailingObjects()[0] = HeapAllocMarker; + if (HasPCSections) + Result->getTrailingObjects()[HasHeapAllocMarker] = + PCSections; if (HasCFIType) Result->getTrailingObjects()[0] = CFIType; @@ -200,6 +205,12 @@ return HasHeapAllocMarker ? getTrailingObjects()[0] : nullptr; } + MDNode *getPCSections() const { + return HasPCSections + ? getTrailingObjects()[HasHeapAllocMarker] + : nullptr; + } + uint32_t getCFIType() const { return HasCFIType ? getTrailingObjects()[0] : 0; } @@ -216,6 +227,7 @@ const bool HasPreInstrSymbol; const bool HasPostInstrSymbol; const bool HasHeapAllocMarker; + const bool HasPCSections; const bool HasCFIType; // Implement the `TrailingObjects` internal API. @@ -226,7 +238,7 @@ return HasPreInstrSymbol + HasPostInstrSymbol; } size_t numTrailingObjects(OverloadToken) const { - return HasHeapAllocMarker; + return HasHeapAllocMarker + HasPCSections; } size_t numTrailingObjects(OverloadToken) const { return HasCFIType; @@ -235,10 +247,11 @@ // Just a boring constructor to allow us to initialize the sizes. Always use // the `create` routine above. ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol, - bool HasHeapAllocMarker, bool HasCFIType) + bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType) : NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol), HasPostInstrSymbol(HasPostInstrSymbol), - HasHeapAllocMarker(HasHeapAllocMarker), HasCFIType(HasCFIType) {} + HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections), + HasCFIType(HasCFIType) {} }; /// Enumeration of the kinds of inline extra info available. It is important @@ -769,6 +782,16 @@ return nullptr; } + /// Helper to extract PCSections metadata target sections. + MDNode *getPCSections() const { + if (!Info) + return nullptr; + if (ExtraInfo *EI = Info.get()) + return EI->getPCSections(); + + return nullptr; + } + /// Helper to extract a CFI type hash if one has been added. uint32_t getCFIType() const { if (!Info) @@ -1810,6 +1833,10 @@ /// instruction is removed or duplicated. void setHeapAllocMarker(MachineFunction &MF, MDNode *MD); + // Set metadata on instructions that say which sections to emit instruction + // addresses into. + void setPCSections(MachineFunction &MF, MDNode *MD); + /// Set the CFI type for the instruction. void setCFIType(MachineFunction &MF, uint32_t Type); @@ -1891,7 +1918,8 @@ /// based on the number of pointers. void setExtraInfo(MachineFunction &MF, ArrayRef MMOs, MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol, - MDNode *HeapAllocMarker, uint32_t CFIType); + MDNode *HeapAllocMarker, MDNode *PCSections, + uint32_t CFIType); }; /// Special DenseMapInfo traits to compare MachineInstr* by *value* of the diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -530,10 +530,11 @@ MachineInstr::ExtraInfo *MachineFunction::createMIExtraInfo( ArrayRef MMOs, MCSymbol *PreInstrSymbol, - MCSymbol *PostInstrSymbol, MDNode *HeapAllocMarker, uint32_t CFIType) { + MCSymbol *PostInstrSymbol, MDNode *HeapAllocMarker, MDNode *PCSections, + uint32_t CFIType) { return MachineInstr::ExtraInfo::create(Allocator, MMOs, PreInstrSymbol, PostInstrSymbol, HeapAllocMarker, - CFIType); + PCSections, CFIType); } const char *MachineFunction::createExternalSymbolName(StringRef Name) { diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -301,13 +301,15 @@ ArrayRef MMOs, MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol, - MDNode *HeapAllocMarker, uint32_t CFIType) { + MDNode *HeapAllocMarker, MDNode *PCSections, + uint32_t CFIType) { bool HasPreInstrSymbol = PreInstrSymbol != nullptr; bool HasPostInstrSymbol = PostInstrSymbol != nullptr; bool HasHeapAllocMarker = HeapAllocMarker != nullptr; + bool HasPCSections = PCSections != nullptr; bool HasCFIType = CFIType != 0; int NumPointers = MMOs.size() + HasPreInstrSymbol + HasPostInstrSymbol + - HasHeapAllocMarker + HasCFIType; + HasHeapAllocMarker + HasPCSections + HasCFIType; // Drop all extra info if there is none. if (NumPointers <= 0) { @@ -319,9 +321,11 @@ // out of line because PointerSumType cannot hold more than 4 tag types with // 32-bit pointers. // FIXME: Maybe we should make the symbols in the extra info mutable? - else if (NumPointers > 1 || HasHeapAllocMarker || HasCFIType) { - Info.set(MF.createMIExtraInfo( - MMOs, PreInstrSymbol, PostInstrSymbol, HeapAllocMarker, CFIType)); + else if (NumPointers > 1 || HasHeapAllocMarker || HasPCSections || + HasCFIType) { + Info.set( + MF.createMIExtraInfo(MMOs, PreInstrSymbol, PostInstrSymbol, + HeapAllocMarker, PCSections, CFIType)); return; } @@ -339,7 +343,7 @@ return; setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(), - getHeapAllocMarker(), getCFIType()); + getHeapAllocMarker(), getPCSections(), getCFIType()); } void MachineInstr::setMemRefs(MachineFunction &MF, @@ -350,7 +354,7 @@ } setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(), - getHeapAllocMarker(), getCFIType()); + getHeapAllocMarker(), getPCSections(), getCFIType()); } void MachineInstr::addMemOperand(MachineFunction &MF, @@ -373,7 +377,8 @@ // are the same (including null). if (getPreInstrSymbol() == MI.getPreInstrSymbol() && getPostInstrSymbol() == MI.getPostInstrSymbol() && - getHeapAllocMarker() == MI.getHeapAllocMarker()) { + getHeapAllocMarker() == MI.getHeapAllocMarker() && + getPCSections() == MI.getPCSections()) { Info = MI.Info; return; } @@ -458,7 +463,7 @@ } setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(), - getHeapAllocMarker(), getCFIType()); + getHeapAllocMarker(), getPCSections(), getCFIType()); } void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) { @@ -473,7 +478,7 @@ } setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol, - getHeapAllocMarker(), getCFIType()); + getHeapAllocMarker(), getPCSections(), getCFIType()); } void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) { @@ -482,7 +487,16 @@ return; setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), - Marker, getCFIType()); + Marker, getPCSections(), getCFIType()); +} + +void MachineInstr::setPCSections(MachineFunction &MF, MDNode *PCSections) { + // Do nothing if old and new symbols are the same. + if (PCSections == getPCSections()) + return; + + setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), + getHeapAllocMarker(), PCSections, getCFIType()); } void MachineInstr::setCFIType(MachineFunction &MF, uint32_t Type) { @@ -491,7 +505,7 @@ return; setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), - getHeapAllocMarker(), Type); + getHeapAllocMarker(), getPCSections(), Type); } void MachineInstr::cloneInstrSymbols(MachineFunction &MF, @@ -506,6 +520,7 @@ setPreInstrSymbol(MF, MI.getPreInstrSymbol()); setPostInstrSymbol(MF, MI.getPostInstrSymbol()); setHeapAllocMarker(MF, MI.getHeapAllocMarker()); + setPCSections(MF, MI.getPCSections()); } uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { @@ -1767,6 +1782,14 @@ OS << " heap-alloc-marker "; HeapAllocMarker->printAsOperand(OS, MST); } + if (MDNode *PCSections = getPCSections()) { + if (!FirstOp) { + FirstOp = false; + OS << ','; + } + OS << " pcsections "; + PCSections->printAsOperand(OS, MST); + } if (uint32_t CFIType = getCFIType()) { if (!FirstOp) OS << ','; diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp --- a/llvm/unittests/CodeGen/MachineInstrTest.cpp +++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -269,36 +269,49 @@ MMOs.push_back(MMO); MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false); MCSymbol *Sym2 = MC->createTempSymbol("post_label", false); - MDNode *MDN = MDNode::getDistinct(Ctx, None); + MDNode *HAM = MDNode::getDistinct(Ctx, None); + MDNode *PCS = MDNode::getDistinct(Ctx, None); ASSERT_TRUE(MI->memoperands_empty()); ASSERT_FALSE(MI->getPreInstrSymbol()); ASSERT_FALSE(MI->getPostInstrSymbol()); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); MI->setMemRefs(*MF, MMOs); ASSERT_TRUE(MI->memoperands().size() == 1); ASSERT_FALSE(MI->getPreInstrSymbol()); ASSERT_FALSE(MI->getPostInstrSymbol()); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); MI->setPreInstrSymbol(*MF, Sym1); ASSERT_TRUE(MI->memoperands().size() == 1); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_FALSE(MI->getPostInstrSymbol()); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); MI->setPostInstrSymbol(*MF, Sym2); ASSERT_TRUE(MI->memoperands().size() == 1); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); - MI->setHeapAllocMarker(*MF, MDN); + MI->setHeapAllocMarker(*MF, HAM); ASSERT_TRUE(MI->memoperands().size() == 1); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2); - ASSERT_TRUE(MI->getHeapAllocMarker() == MDN); + ASSERT_TRUE(MI->getHeapAllocMarker() == HAM); + ASSERT_FALSE(MI->getPCSections()); + + MI->setPCSections(*MF, PCS); + ASSERT_TRUE(MI->memoperands().size() == 1); + ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); + ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2); + ASSERT_TRUE(MI->getHeapAllocMarker() == HAM); + ASSERT_TRUE(MI->getPCSections() == PCS); } TEST(MachineInstrExtraInfo, ChangeExtraInfo) { @@ -316,12 +329,14 @@ MMOs.push_back(MMO); MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false); MCSymbol *Sym2 = MC->createTempSymbol("post_label", false); - MDNode *MDN = MDNode::getDistinct(Ctx, None); + MDNode *HAM = MDNode::getDistinct(Ctx, None); + MDNode *PCS = MDNode::getDistinct(Ctx, None); MI->setMemRefs(*MF, MMOs); MI->setPreInstrSymbol(*MF, Sym1); MI->setPostInstrSymbol(*MF, Sym2); - MI->setHeapAllocMarker(*MF, MDN); + MI->setHeapAllocMarker(*MF, HAM); + MI->setPCSections(*MF, PCS); MMOs.push_back(MMO); @@ -329,13 +344,15 @@ ASSERT_TRUE(MI->memoperands().size() == 2); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_TRUE(MI->getPostInstrSymbol() == Sym2); - ASSERT_TRUE(MI->getHeapAllocMarker() == MDN); + ASSERT_TRUE(MI->getHeapAllocMarker() == HAM); + ASSERT_TRUE(MI->getPCSections() == PCS); MI->setPostInstrSymbol(*MF, Sym1); ASSERT_TRUE(MI->memoperands().size() == 2); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_TRUE(MI->getPostInstrSymbol() == Sym1); - ASSERT_TRUE(MI->getHeapAllocMarker() == MDN); + ASSERT_TRUE(MI->getHeapAllocMarker() == HAM); + ASSERT_TRUE(MI->getPCSections() == PCS); } TEST(MachineInstrExtraInfo, RemoveExtraInfo) { @@ -354,36 +371,49 @@ MMOs.push_back(MMO); MCSymbol *Sym1 = MC->createTempSymbol("pre_label", false); MCSymbol *Sym2 = MC->createTempSymbol("post_label", false); - MDNode *MDN = MDNode::getDistinct(Ctx, None); + MDNode *HAM = MDNode::getDistinct(Ctx, None); + MDNode *PCS = MDNode::getDistinct(Ctx, None); MI->setMemRefs(*MF, MMOs); MI->setPreInstrSymbol(*MF, Sym1); MI->setPostInstrSymbol(*MF, Sym2); - MI->setHeapAllocMarker(*MF, MDN); + MI->setHeapAllocMarker(*MF, HAM); + MI->setPCSections(*MF, PCS); MI->setPostInstrSymbol(*MF, nullptr); ASSERT_TRUE(MI->memoperands().size() == 2); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_FALSE(MI->getPostInstrSymbol()); - ASSERT_TRUE(MI->getHeapAllocMarker() == MDN); + ASSERT_TRUE(MI->getHeapAllocMarker() == HAM); + ASSERT_TRUE(MI->getPCSections() == PCS); MI->setHeapAllocMarker(*MF, nullptr); ASSERT_TRUE(MI->memoperands().size() == 2); ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); ASSERT_FALSE(MI->getPostInstrSymbol()); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_TRUE(MI->getPCSections() == PCS); + + MI->setPCSections(*MF, nullptr); + ASSERT_TRUE(MI->memoperands().size() == 2); + ASSERT_TRUE(MI->getPreInstrSymbol() == Sym1); + ASSERT_FALSE(MI->getPostInstrSymbol()); + ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); MI->setPreInstrSymbol(*MF, nullptr); ASSERT_TRUE(MI->memoperands().size() == 2); ASSERT_FALSE(MI->getPreInstrSymbol()); ASSERT_FALSE(MI->getPostInstrSymbol()); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); MI->setMemRefs(*MF, {}); ASSERT_TRUE(MI->memoperands_empty()); ASSERT_FALSE(MI->getPreInstrSymbol()); ASSERT_FALSE(MI->getPostInstrSymbol()); ASSERT_FALSE(MI->getHeapAllocMarker()); + ASSERT_FALSE(MI->getPCSections()); } TEST(MachineInstrDebugValue, AddDebugValueOperand) {