[llvm] r295356 - [RDF] Differentiate between defining and clobbering nodes
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 16 10:53:04 PST 2017
Author: kparzysz
Date: Thu Feb 16 12:53:04 2017
New Revision: 295356
URL: http://llvm.org/viewvc/llvm-project?rev=295356&view=rev
Log:
[RDF] Differentiate between defining and clobbering nodes
Defining nodes should not alias with one another, while clobbering
nodes can. When pushing defs on stacks, push clobbers first, link
non-clobbering defs, then push the defs.
The data flow in a statement is now: uses -> clobbers -> defs.
Modified:
llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp
llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
llvm/trunk/lib/Target/Hexagon/RDFGraph.h
Modified: llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp?rev=295356&r1=295355&r2=295356&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp Thu Feb 16 12:53:04 2017
@@ -617,7 +617,7 @@ bool HexagonOptAddrMode::constructDefMap
for (NodeAddr<InstrNode *> IA : BA.Addr->members(*DFG)) {
updateMap(IA);
- DFG->pushDefs(IA, DefM);
+ DFG->pushAllDefs(IA, DefM);
}
MachineDomTreeNode *N = MDT->getNode(B);
Modified: llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp?rev=295356&r1=295355&r2=295356&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp Thu Feb 16 12:53:04 2017
@@ -104,7 +104,7 @@ bool CopyPropagation::scanBlock(MachineB
}
updateMap(IA);
- DFG.pushDefs(IA, DefM);
+ DFG.pushAllDefs(IA, DefM);
}
MachineDomTreeNode *N = MDT.getNode(B);
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=295356&r1=295355&r2=295356&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Thu Feb 16 12:53:04 2017
@@ -617,8 +617,12 @@ bool TargetOperandInfo::isPreserving(con
// Check if the definition of RR produces an unspecified value.
bool TargetOperandInfo::isClobbering(const MachineInstr &In, unsigned OpNum)
const {
+ const MachineOperand &Op = In.getOperand(OpNum);
+ if (Op.isRegMask())
+ return true;
+ assert(Op.isReg());
if (In.isCall())
- if (In.getOperand(OpNum).isImplicit())
+ if (Op.isDef() && Op.isDead())
return true;
return false;
}
@@ -1024,11 +1028,61 @@ void DataFlowGraph::releaseBlock(NodeId
// Push all definitions from the instruction node IA to an appropriate
// stack in DefM.
+void DataFlowGraph::pushAllDefs(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
+ pushClobbers(IA, DefM);
+ pushDefs(IA, DefM);
+}
+
+// Push all definitions from the instruction node IA to an appropriate
+// stack in DefM.
+void DataFlowGraph::pushClobbers(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
+ NodeSet Visited;
+ std::set<RegisterId> Defined;
+
+ // The important objectives of this function are:
+ // - to be able to handle instructions both while the graph is being
+ // constructed, and after the graph has been constructed, and
+ // - maintain proper ordering of definitions on the stack for each
+ // register reference:
+ // - if there are two or more related defs in IA (i.e. coming from
+ // the same machine operand), then only push one def on the stack,
+ // - if there are multiple unrelated defs of non-overlapping
+ // subregisters of S, then the stack for S will have both (in an
+ // unspecified order), but the order does not matter from the data-
+ // -flow perspective.
+
+ for (NodeAddr<DefNode*> DA : IA.Addr->members_if(IsDef, *this)) {
+ if (Visited.count(DA.Id))
+ continue;
+ if (!(DA.Addr->getFlags() & NodeAttrs::Clobbering))
+ continue;
+
+ NodeList Rel = getRelatedRefs(IA, DA);
+ NodeAddr<DefNode*> PDA = Rel.front();
+ RegisterRef RR = PDA.Addr->getRegRef(*this);
+
+ // Push the definition on the stack for the register and all aliases.
+ // The def stack traversal in linkNodeUp will check the exact aliasing.
+ DefM[RR.Reg].push(DA);
+ Defined.insert(RR.Reg);
+ for (RegisterId A : PRI.getAliasSet(RR.Reg)) {
+ // Check that we don't push the same def twice.
+ assert(A != RR.Reg);
+ if (!Defined.count(A))
+ DefM[A].push(DA);
+ }
+ // Mark all the related defs as visited.
+ for (NodeAddr<NodeBase*> T : Rel)
+ Visited.insert(T.Id);
+ }
+}
+
+// Push all definitions from the instruction node IA to an appropriate
+// stack in DefM.
void DataFlowGraph::pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DefM) {
- NodeList Defs = IA.Addr->members_if(IsDef, *this);
NodeSet Visited;
#ifndef NDEBUG
- RegisterSet Defined;
+ std::set<RegisterId> Defined;
#endif
// The important objectives of this function are:
@@ -1043,9 +1097,11 @@ void DataFlowGraph::pushDefs(NodeAddr<In
// unspecified order), but the order does not matter from the data-
// -flow perspective.
- for (NodeAddr<DefNode*> DA : Defs) {
+ for (NodeAddr<DefNode*> DA : IA.Addr->members_if(IsDef, *this)) {
if (Visited.count(DA.Id))
continue;
+ if (DA.Addr->getFlags() & NodeAttrs::Clobbering)
+ continue;
NodeList Rel = getRelatedRefs(IA, DA);
NodeAddr<DefNode*> PDA = Rel.front();
@@ -1053,7 +1109,7 @@ void DataFlowGraph::pushDefs(NodeAddr<In
#ifndef NDEBUG
// Assert if the register is defined in two or more unrelated defs.
// This could happen if there are two or more def operands defining it.
- if (!Defined.insert(RR).second) {
+ if (!Defined.insert(RR.Reg).second) {
MachineInstr *MI = NodeAddr<StmtNode*>(IA).Addr->getCode();
dbgs() << "Multiple definitions of register: "
<< Print<RegisterRef>(RR, *this) << " in\n " << *MI
@@ -1611,13 +1667,15 @@ void DataFlowGraph::linkRefUp(NodeAddr<I
}
// Create data-flow links for all reference nodes in the statement node SA.
-void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA) {
+template <typename Predicate>
+void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA,
+ Predicate P) {
#ifndef NDEBUG
RegisterSet Defs;
#endif
// Link all nodes (upwards in the data-flow) with their reaching defs.
- for (NodeAddr<RefNode*> RA : SA.Addr->members(*this)) {
+ for (NodeAddr<RefNode*> RA : SA.Addr->members_if(P, *this)) {
uint16_t Kind = RA.Addr->getKind();
assert(Kind == NodeAttrs::Def || Kind == NodeAttrs::Use);
RegisterRef RR = RA.Addr->getRegRef(*this);
@@ -1646,6 +1704,13 @@ void DataFlowGraph::linkBlockRefs(DefSta
// Push block delimiters.
markBlock(BA.Id, DefM);
+ auto IsClobber = [this] (NodeAddr<RefNode*> RA) -> bool {
+ return IsDef(RA) && (RA.Addr->getFlags() & NodeAttrs::Clobbering);
+ };
+ auto IsNoClobber = [this] (NodeAddr<RefNode*> RA) -> bool {
+ return IsDef(RA) && !(RA.Addr->getFlags() & NodeAttrs::Clobbering);
+ };
+
assert(BA.Addr && "block node address is needed to create a data-flow link");
// For each non-phi instruction in the block, link all the defs and uses
// to their reaching defs. For any member of the block (including phis),
@@ -1653,10 +1718,17 @@ void DataFlowGraph::linkBlockRefs(DefSta
for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this)) {
// Ignore phi nodes here. They will be linked part by part from the
// predecessors.
- if (IA.Addr->getKind() == NodeAttrs::Stmt)
- linkStmtRefs(DefM, IA);
+ if (IA.Addr->getKind() == NodeAttrs::Stmt) {
+ linkStmtRefs(DefM, IA, IsUse);
+ linkStmtRefs(DefM, IA, IsClobber);
+ }
// Push the definitions on the stack.
+ pushClobbers(IA, DefM);
+
+ if (IA.Addr->getKind() == NodeAttrs::Stmt)
+ linkStmtRefs(DefM, IA, IsNoClobber);
+
pushDefs(IA, DefM);
}
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=295356&r1=295355&r2=295356&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Thu Feb 16 12:53:04 2017
@@ -729,7 +729,7 @@ namespace rdf {
typedef std::unordered_map<RegisterId,DefStack> DefStackMap;
void build(unsigned Options = BuildOptions::None);
- void pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
+ void pushAllDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
void markBlock(NodeId B, DefStackMap &DefM);
void releaseBlock(NodeId B, DefStackMap &DefM);
@@ -844,9 +844,12 @@ namespace rdf {
NodeAddr<BlockNode*> BA);
void removeUnusedPhis();
+ void pushClobbers(NodeAddr<InstrNode*> IA, DefStackMap &DM);
+ void pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
template <typename T> void linkRefUp(NodeAddr<InstrNode*> IA,
NodeAddr<T> TA, DefStack &DS);
- void linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA);
+ template <typename Predicate> void linkStmtRefs(DefStackMap &DefM,
+ NodeAddr<StmtNode*> SA, Predicate P);
void linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA);
void unlinkUseDF(NodeAddr<UseNode*> UA);
More information about the llvm-commits
mailing list