[llvm] 4c58b00 - [SelectionDAG] Propagate PCSections through SDNodes
Marco Elver via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 7 02:24:14 PDT 2022
Author: Marco Elver
Date: 2022-09-07T11:22:50+02:00
New Revision: 4c58b00801add008e1f2bd0774d9a0d7297c3f93
URL: https://github.com/llvm/llvm-project/commit/4c58b00801add008e1f2bd0774d9a0d7297c3f93
DIFF: https://github.com/llvm/llvm-project/commit/4c58b00801add008e1f2bd0774d9a0d7297c3f93.diff
LOG: [SelectionDAG] Propagate PCSections through SDNodes
Add a new entry to SDNodeExtraInfo to propagate PCSections through
SelectionDAG.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D130882
Added:
Modified:
llvm/include/llvm/CodeGen/SelectionDAG.h
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index ba7fc62e40042..0d88f55451d43 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -275,6 +275,7 @@ class SelectionDAG {
struct NodeExtraInfo {
CallSiteInfo CSInfo;
MDNode *HeapAllocSite = nullptr;
+ MDNode *PCSections = nullptr;
bool NoMerge = false;
};
/// Out-of-line extra information for SDNodes.
@@ -336,6 +337,19 @@ class SelectionDAG {
virtual void anchor();
};
+ struct DAGNodeInsertedListener : public DAGUpdateListener {
+ std::function<void(SDNode *)> Callback;
+
+ DAGNodeInsertedListener(SelectionDAG &DAG,
+ std::function<void(SDNode *)> Callback)
+ : DAGUpdateListener(DAG), Callback(std::move(Callback)) {}
+
+ void NodeInserted(SDNode *N) override { Callback(N); }
+
+ private:
+ virtual void anchor();
+ };
+
/// Help to insert SDNodeFlags automatically in transforming. Use
/// RAII to save and resume flags in current scope.
class FlagInserter {
@@ -2184,6 +2198,15 @@ class SelectionDAG {
auto I = SDEI.find(Node);
return I != SDEI.end() ? I->second.HeapAllocSite : nullptr;
}
+ /// Set PCSections to be associated with Node.
+ void addPCSections(const SDNode *Node, MDNode *MD) {
+ SDEI[Node].PCSections = MD;
+ }
+ /// Return PCSections associated with Node, or nullptr if none exists.
+ MDNode *getPCSections(const SDNode *Node) const {
+ auto It = SDEI.find(Node);
+ return It != SDEI.end() ? It->second.PCSections : nullptr;
+ }
/// Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
if (NoMerge)
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index 5166db033c629..bb0f29bbaad4f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -890,6 +890,9 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
MI->setFlag(MachineInstr::MIFlag::NoMerge);
}
+ if (MDNode *MD = DAG->getPCSections(Node))
+ MI->setPCSections(MF, MD);
+
return MI;
};
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 97b14b46e720e..70e046571c590 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -92,6 +92,7 @@ void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {}
void SelectionDAG::DAGUpdateListener::NodeInserted(SDNode *) {}
void SelectionDAG::DAGNodeDeletedListener::anchor() {}
+void SelectionDAG::DAGNodeInsertedListener::anchor() {}
#define DEBUG_TYPE "selectiondag"
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 4c21dfc4392a5..bc72e45cb4411 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1123,12 +1123,36 @@ void SelectionDAGBuilder::visit(const Instruction &I) {
CurInst = &I;
+ // Set inserted listener only if required.
+ bool NodeInserted = false;
+ std::unique_ptr<SelectionDAG::DAGNodeInsertedListener> InsertedListener;
+ MDNode *PCSectionsMD = I.getMetadata(LLVMContext::MD_pcsections);
+ if (PCSectionsMD) {
+ InsertedListener = std::make_unique<SelectionDAG::DAGNodeInsertedListener>(
+ DAG, [&](SDNode *) { NodeInserted = true; });
+ }
+
visit(I.getOpcode(), I);
if (!I.isTerminator() && !HasTailCall &&
!isa<GCStatepointInst>(I)) // statepoints handle their exports internally
CopyToExportRegsIfNeeded(&I);
+ // Handle metadata.
+ if (PCSectionsMD) {
+ auto It = NodeMap.find(&I);
+ if (It != NodeMap.end()) {
+ DAG.addPCSections(It->second.getNode(), PCSectionsMD);
+ } else if (NodeInserted) {
+ // This should not happen; if it does, don't let it go unnoticed so we can
+ // fix it. Relevant visit*() function is probably missing a setValue().
+ errs() << "warning: loosing !pcsections metadata ["
+ << I.getModule()->getName() << "]\n";
+ LLVM_DEBUG(I.dump());
+ assert(false);
+ }
+ }
+
CurInst = nullptr;
}
@@ -2543,6 +2567,8 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB,
MVT::Other, getControlRoot(), Cond,
DAG.getBasicBlock(CB.TrueBB));
+ setValue(CurInst, BrCond);
+
// Insert the false branch. Do this even if it's a fall through branch,
// this makes it easier to do DAG optimizations which require inverting
// the branch condition.
@@ -4303,6 +4329,7 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
SDValue StoreNode = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
makeArrayRef(Chains.data(), ChainI));
+ setValue(&I, StoreNode);
DAG.setRoot(StoreNode);
}
@@ -4667,7 +4694,9 @@ void SelectionDAGBuilder::visitFence(const FenceInst &I) {
TLI.getFenceOperandTy(DAG.getDataLayout()));
Ops[2] = DAG.getTargetConstant(I.getSyncScopeID(), dl,
TLI.getFenceOperandTy(DAG.getDataLayout()));
- DAG.setRoot(DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops));
+ SDValue N = DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops);
+ setValue(&I, N);
+ DAG.setRoot(N);
}
void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
@@ -4754,13 +4783,14 @@ void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) {
// TODO: Once this is better exercised by tests, it should be merged with
// the normal path for stores to prevent future divergence.
SDValue S = DAG.getStore(InChain, dl, Val, Ptr, MMO);
+ setValue(&I, S);
DAG.setRoot(S);
return;
}
SDValue OutChain = DAG.getAtomic(ISD::ATOMIC_STORE, dl, MemVT, InChain,
Ptr, Val, MMO);
-
+ setValue(&I, OutChain);
DAG.setRoot(OutChain);
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index d46a0a23cca3e..366eb7ab42510 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -997,6 +997,15 @@ class ISelUpdater : public SelectionDAG::DAGUpdateListener {
if (ISelPosition == SelectionDAG::allnodes_iterator(N))
++ISelPosition;
}
+
+ /// NodeInserted - Handle new nodes inserted into the graph: propagate
+ /// metadata from root nodes that also applies to new nodes, in case the root
+ /// is later deleted.
+ void NodeInserted(SDNode *N) override {
+ SDNode *CurNode = &*ISelPosition;
+ if (MDNode *MD = DAG.getPCSections(CurNode))
+ DAG.addPCSections(N, MD);
+ }
};
} // end anonymous namespace
@@ -1073,7 +1082,7 @@ void SelectionDAGISel::DoInstructionSelection() {
++ISelPosition;
// Make sure that ISelPosition gets properly updated when nodes are deleted
- // in calls made from this function.
+ // in calls made from this function. New nodes inherit relevant metadata.
ISelUpdater ISU(*CurDAG, ISelPosition);
// The AllNodes list is now topological-sorted. Visit the
diff --git a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp b/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
index 1fedcf1467440..94171001691fc 100644
--- a/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
+++ b/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
@@ -601,11 +601,14 @@ TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
+ EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
MDNode *MD = MDNode::get(Context, None);
DAG->addHeapAllocSite(N2.getNode(), MD);
DAG->addNoMergeSiteInfo(N2.getNode(), true);
+ DAG->addPCSections(N2.getNode(), MD);
EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
+ EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);
EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
@@ -613,11 +616,13 @@ TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);
EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
+ EXPECT_FALSE(DAG->getPCSections(New.getNode()));
DAG->ReplaceAllUsesWith(N2, New);
EXPECT_EQ(Root->getOperand(0), New);
EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
+ EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
}
} // end namespace llvm
More information about the llvm-commits
mailing list