[RDF] Add option to keep dead phi nodes in DFG
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Thu, 28 Apr 2016 20:17:06 +0000 (20:17 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Thu, 28 Apr 2016 20:17:06 +0000 (20:17 +0000)
Dead phi nodes are needed for code motion (such as copy propagation),
where a new use would be placed in a location that would be dominated
by a dead phi. Such a transformation is not legal for copy propagation,
and the existence of the phi would prevent it, but if the phi is not
there, it may appear to be valid.

llvm-svn: 267932

llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
llvm/lib/Target/Hexagon/RDFGraph.cpp
llvm/lib/Target/Hexagon/RDFGraph.h

index d735acf..642a878 100644 (file)
@@ -289,7 +289,10 @@ bool HexagonRDFOpt::runOnMachineFunction(MachineFunction &MF) {
   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'
index 335e5cb..53743e6 100644 (file)
@@ -919,7 +919,7 @@ NodeAddr<FuncNode*> DataFlowGraph::newFunc(MachineFunction *MF) {
 }
 
 // Build the data flow graph.
-void DataFlowGraph::build() {
+void DataFlowGraph::build(unsigned Options) {
   reset();
   Func = newFunc(&MF);
 
@@ -964,7 +964,8 @@ void DataFlowGraph::build() {
   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.
index 1de50d7..43eeb48 100644 (file)
@@ -287,6 +287,13 @@ namespace rdf {
     }
   };
 
+  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) {}
@@ -677,7 +684,7 @@ namespace rdf {
 
     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);