[RDF] Fix liveness propagation through shadows
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 3 Oct 2016 20:17:20 +0000 (20:17 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 3 Oct 2016 20:17:20 +0000 (20:17 +0000)
Each shadow only represents data flow that is restricted to its reaching
def. Propagating more than that could lead to spurious register liveness,
resulting in extra (incorrectly) block live-ins.

llvm-svn: 283143

llvm/lib/Target/Hexagon/RDFLiveness.cpp
llvm/test/CodeGen/Hexagon/rdf-extra-livein.ll [new file with mode: 0644]

index efc4511..d3b2d57 100644 (file)
@@ -530,7 +530,7 @@ void Liveness::computePhiInfo() {
         RegisterSet UpReached;
         for (const std::pair<RegisterRef,NodeSet> &T : RUM) {
           RegisterRef R = T.first;
-          if (!isRestrictedToRef(PA, UA, R))
+          if (UA.Addr->getFlags() & NodeAttrs::Shadow)
             R = getRestrictedRegRef(UA);
           if (!MidDefs.hasCoverOf(R))
             UpReached.insert(R);
@@ -648,7 +648,7 @@ void Liveness::computeLiveIns() {
         auto &LOX = PhiLOX[PrA.Addr->getCode()];
         for (auto R : RUs) {
           RegisterRef RR = R.first;
-          if (!isRestrictedToRef(PA, UA, RR))
+          if (UA.Addr->getFlags() & NodeAttrs::Shadow)
             RR = getRestrictedRegRef(UA);
           // The restricted ref may be different from the ref that was
           // accessed in the "real use". This means that this phi use
@@ -770,29 +770,6 @@ void Liveness::resetKills(MachineBasicBlock *B) {
 }
 
 
-// For shadows, determine if RR is aliased to a reaching def of any other
-// shadow associated with RA. The register ref on RA will be "larger" than
-// each individual reaching def, and to determine the data-flow between defs
-// and uses of RR it may be necessary to visit all shadows. If RR is not
-// aliased to the reaching def of any other shadow, then visiting only RA
-// is sufficient. In that sense, the data flow of RR would be restricted to
-// the reference RA.
-// For non-shadows, this function returns "true".
-bool Liveness::isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
-      RegisterRef RR) const {
-  NodeId Start = RA.Id;
-  for (NodeAddr<RefNode*> TA = DFG.getNextShadow(IA, RA);
-       TA.Id != 0 && TA.Id != Start; TA = DFG.getNextShadow(IA, TA)) {
-    NodeId RD = TA.Addr->getReachingDef();
-    if (RD == 0)
-      continue;
-    if (DFG.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef()))
-      return false;
-  }
-  return true;
-}
-
-
 RegisterRef Liveness::getRestrictedRegRef(NodeAddr<RefNode*> RA) const {
   assert(DFG.IsRef<NodeAttrs::Use>(RA));
   if (RA.Addr->getFlags() & NodeAttrs::Shadow) {
@@ -850,12 +827,13 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
   }
 
   if (Trace) {
-    dbgs() << LLVM_FUNCTION_NAME << " in BB#" << B->getNumber()
-           << " after recursion into";
+    dbgs() << "\n-- BB#" << B->getNumber() << ": " << LLVM_FUNCTION_NAME
+           << " after recursion into: {";
     for (auto I : *N)
       dbgs() << ' ' << I->getBlock()->getNumber();
-    dbgs() << "\n  LiveIn: " << Print<RefMap>(LiveIn, DFG);
-    dbgs() << "\n  Local:  " << Print<RegisterSet>(LiveMap[B], DFG) << '\n';
+    dbgs() << " }\n";
+    dbgs() << "  LiveIn: " << Print<RefMap>(LiveIn, DFG) << '\n';
+    dbgs() << "  Local:  " << Print<RegisterSet>(LiveMap[B], DFG) << '\n';
   }
 
   // Add phi uses that are live on exit from this block.
diff --git a/llvm/test/CodeGen/Hexagon/rdf-extra-livein.ll b/llvm/test/CodeGen/Hexagon/rdf-extra-livein.ll
new file mode 100644 (file)
index 0000000..5d947e6
--- /dev/null
@@ -0,0 +1,73 @@
+; RUN: llc -march=hexagon -verify-machineinstrs < %s | FileCheck %s
+; Verify that the code compiles successfully.
+; CHECK: call printf
+
+target triple = "hexagon"
+
+%struct.0 = type { i32, i32, i32, i32, i32, i32, i32, i32, i32 }
+
+@.str.13 = external unnamed_addr constant [60 x i8], align 1
+
+declare void @printf(i8* nocapture readonly, ...) local_unnamed_addr #0
+
+declare void @danny() local_unnamed_addr #0
+declare zeroext i8 @sammy() local_unnamed_addr #0
+
+; Function Attrs: nounwind
+define void @main() local_unnamed_addr #0 {
+entry:
+  br i1 undef, label %if.then8, label %if.end10
+
+if.then8:                                         ; preds = %entry
+  ret void
+
+if.end10:                                         ; preds = %entry
+  br label %do.body
+
+do.body:                                          ; preds = %if.end88.do.body_crit_edge, %if.end10
+  %cond = icmp eq i32 undef, 0
+  br i1 %cond, label %if.end49, label %if.then124
+
+if.end49:                                         ; preds = %do.body
+  br i1 undef, label %if.end55, label %if.then53
+
+if.then53:                                        ; preds = %if.end49
+  call void @danny()
+  br label %if.end55
+
+if.end55:                                         ; preds = %if.then53, %if.end49
+  %call76 = call zeroext i8 @sammy() #0
+  switch i8 %call76, label %sw.epilog79 [
+    i8 0, label %sw.bb77
+    i8 3, label %sw.bb77
+  ]
+
+sw.bb77:                                          ; preds = %if.end55, %if.end55
+  unreachable
+
+sw.epilog79:                                      ; preds = %if.end55
+  br i1 undef, label %if.end88, label %if.then81
+
+if.then81:                                        ; preds = %sw.epilog79
+  %div87 = fdiv float 0.000000e+00, undef
+  br label %if.end88
+
+if.end88:                                         ; preds = %if.then81, %sw.epilog79
+  %t.1 = phi float [ undef, %sw.epilog79 ], [ %div87, %if.then81 ]
+  %div89 = fdiv float 1.000000e+00, %t.1
+  %mul92 = fmul float undef, %div89
+  %div93 = fdiv float %mul92, 1.000000e+06
+  %conv107 = fpext float %div93 to double
+  call void (i8*, ...) @printf(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.13, i32 0, i32 0), double %conv107, double undef, i64 undef, i32 undef) #0
+  br i1 undef, label %if.end88.do.body_crit_edge, label %if.then124
+
+if.end88.do.body_crit_edge:                       ; preds = %if.end88
+  br label %do.body
+
+if.then124:                                       ; preds = %if.end88, %do.body
+  unreachable
+}
+
+
+attributes #0 = { nounwind }
+