HexagonRegisterAliasInfo HAI(HRI);
TargetOperandInfo TOI(HII);
DataFlowGraph G(MF, HII, HRI, *MDT, MDF, HAI, TOI);
- G.build();
+ // Dead phi nodes are necessary for copy propagation: we can add a use
+ // of a register in a block where it would need a phi node, but which
+ // was dead (and removed) during the graph build time.
+ G.build(BuildOptions::KeepDeadPhis);
if (RDFDump)
dbgs() << "Starting copy propagation on: " << MF.getName() << '\n'
}
// Build the data flow graph.
-void DataFlowGraph::build() {
+void DataFlowGraph::build(unsigned Options) {
reset();
Func = newFunc(&MF);
linkBlockRefs(DM, EA);
// Finally, remove all unused phi nodes.
- removeUnusedPhis();
+ if (!(Options & BuildOptions::KeepDeadPhis))
+ removeUnusedPhis();
}
// For each stack in the map DefM, push the delimiter for block B on it.
}
};
+ struct BuildOptions {
+ enum : unsigned {
+ None = 0x00,
+ KeepDeadPhis = 0x01, // Do not remove dead phis during build.
+ };
+ };
+
template <typename T> struct NodeAddr {
NodeAddr() : Addr(nullptr), Id(0) {}
NodeAddr(T A, NodeId I) : Addr(A), Id(I) {}
typedef std::map<RegisterRef,DefStack> DefStackMap;
- void build();
+ void build(unsigned Options = BuildOptions::None);
void pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
void markBlock(NodeId B, DefStackMap &DefM);
void releaseBlock(NodeId B, DefStackMap &DefM);