47 changes: 35 additions & 12 deletions llvm/lib/CodeGen/MachineInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,15 @@ void MachineInstr::setExtraInfo(MachineFunction &MF,
ArrayRef<MachineMemOperand *> 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) {
Expand All @@ -319,9 +321,11 @@ void MachineInstr::setExtraInfo(MachineFunction &MF,
// 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<EIIK_OutOfLine>(MF.createMIExtraInfo(
MMOs, PreInstrSymbol, PostInstrSymbol, HeapAllocMarker, CFIType));
else if (NumPointers > 1 || HasHeapAllocMarker || HasPCSections ||
HasCFIType) {
Info.set<EIIK_OutOfLine>(
MF.createMIExtraInfo(MMOs, PreInstrSymbol, PostInstrSymbol,
HeapAllocMarker, PCSections, CFIType));
return;
}

Expand All @@ -339,7 +343,7 @@ void MachineInstr::dropMemRefs(MachineFunction &MF) {
return;

setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(),
getHeapAllocMarker(), getCFIType());
getHeapAllocMarker(), getPCSections(), getCFIType());
}

void MachineInstr::setMemRefs(MachineFunction &MF,
Expand All @@ -350,7 +354,7 @@ void MachineInstr::setMemRefs(MachineFunction &MF,
}

setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(),
getHeapAllocMarker(), getCFIType());
getHeapAllocMarker(), getPCSections(), getCFIType());
}

void MachineInstr::addMemOperand(MachineFunction &MF,
Expand All @@ -373,7 +377,8 @@ void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {
// 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;
}
Expand Down Expand Up @@ -458,7 +463,7 @@ void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
}

setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(),
getHeapAllocMarker(), getCFIType());
getHeapAllocMarker(), getPCSections(), getCFIType());
}

void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
Expand All @@ -473,7 +478,7 @@ void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
}

setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol,
getHeapAllocMarker(), getCFIType());
getHeapAllocMarker(), getPCSections(), getCFIType());
}

void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {
Expand All @@ -482,7 +487,16 @@ void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {
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) {
Expand All @@ -491,7 +505,7 @@ void MachineInstr::setCFIType(MachineFunction &MF, uint32_t Type) {
return;

setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
getHeapAllocMarker(), Type);
getHeapAllocMarker(), getPCSections(), Type);
}

void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
Expand All @@ -506,6 +520,7 @@ void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
setPreInstrSymbol(MF, MI.getPreInstrSymbol());
setPostInstrSymbol(MF, MI.getPostInstrSymbol());
setHeapAllocMarker(MF, MI.getHeapAllocMarker());
setPCSections(MF, MI.getPCSections());
}

uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
Expand Down Expand Up @@ -1767,6 +1782,14 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
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 << ',';
Expand Down
21 changes: 21 additions & 0 deletions llvm/lib/IR/MDBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,27 @@ MDNode *MDBuilder::createRTTIPointerPrologue(Constant *PrologueSig,
return MDNode::get(Context, Ops);
}

MDNode *MDBuilder::createPCSections(ArrayRef<PCSection> Sections) {
SmallVector<Metadata *, 2> Ops;

for (const auto &Entry : Sections) {
const StringRef &Sec = Entry.first;
Ops.push_back(createString(Sec));

// If auxiliary data for this section exists, append it.
const SmallVector<Constant *> &AuxConsts = Entry.second;
if (!AuxConsts.empty()) {
SmallVector<Metadata *, 1> AuxMDs;
AuxMDs.reserve(AuxConsts.size());
for (Constant *C : AuxConsts)
AuxMDs.push_back(createConstant(C));
Ops.push_back(MDNode::get(Context, AuxMDs));
}
}

return MDNode::get(Context, Ops);
}

MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
SmallVector<Metadata *, 3> Args(1, nullptr);
if (Extra)
Expand Down
50 changes: 40 additions & 10 deletions llvm/unittests/CodeGen/MachineInstrTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,36 +269,49 @@ TEST(MachineInstrExtraInfo, AddExtraInfo) {
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) {
Expand All @@ -316,26 +329,30 @@ TEST(MachineInstrExtraInfo, ChangeExtraInfo) {
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);

MI->setMemRefs(*MF, MMOs);
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) {
Expand All @@ -354,36 +371,49 @@ TEST(MachineInstrExtraInfo, RemoveExtraInfo) {
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) {
Expand Down
23 changes: 23 additions & 0 deletions llvm/unittests/IR/MDBuilderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Operator.h"
Expand Down Expand Up @@ -104,4 +105,26 @@ TEST_F(MDBuilderTest, createTBAANode) {
EXPECT_EQ(mdconst::extract<ConstantInt>(N2->getOperand(2))->getZExtValue(),
1U);
}
TEST_F(MDBuilderTest, createPCSections) {
MDBuilder MDHelper(Context);
ConstantInt *C1 = ConstantInt::get(Context, APInt(8, 1));
ConstantInt *C2 = ConstantInt::get(Context, APInt(8, 2));
MDNode *PCS = MDHelper.createPCSections({{"s1", {C1, C2}}, {"s2", {}}});
ASSERT_EQ(PCS->getNumOperands(), 3U);
const auto *S1 = dyn_cast<MDString>(PCS->getOperand(0));
const auto *Aux = dyn_cast<MDNode>(PCS->getOperand(1));
const auto *S2 = dyn_cast<MDString>(PCS->getOperand(2));
ASSERT_NE(S1, nullptr);
ASSERT_NE(Aux, nullptr);
ASSERT_NE(S2, nullptr);
EXPECT_EQ(S1->getString(), "s1");
EXPECT_EQ(S2->getString(), "s2");
ASSERT_EQ(Aux->getNumOperands(), 2U);
ASSERT_TRUE(isa<ConstantAsMetadata>(Aux->getOperand(0)));
ASSERT_TRUE(isa<ConstantAsMetadata>(Aux->getOperand(1)));
EXPECT_EQ(mdconst::extract<ConstantInt>(Aux->getOperand(0))->getValue(),
C1->getValue());
EXPECT_EQ(mdconst::extract<ConstantInt>(Aux->getOperand(1))->getValue(),
C2->getValue());
}
} // namespace