[llvm] r259013 - [WebAssembly] Don't stackify a register def past a get_local use in the same tree.

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 27 19:59:10 PST 2016


Author: djg
Date: Wed Jan 27 21:59:09 2016
New Revision: 259013

URL: http://llvm.org/viewvc/llvm-project?rev=259013&view=rev
Log:
[WebAssembly] Don't stackify a register def past a get_local use in the same tree.

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
    llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp?rev=259013&r1=259012&r2=259013&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp Wed Jan 27 21:59:09 2016
@@ -326,6 +326,17 @@ public:
     const RangeTy &Range = Worklist.back();
     return Range.begin() != Range.end() && Range.begin()->getParent() == Instr;
   }
+
+  /// Test whether the given register is present on the stack, indicating an
+  /// operand in the tree that we haven't visited yet. Moving a definition of
+  /// Reg to a point in the tree after that would change its value.
+  bool IsOnStack(unsigned Reg) const {
+    for (const RangeTy &Range : Worklist)
+      for (const MachineOperand &MO : Range)
+        if (MO.isReg() && MO.getReg() == Reg)
+          return true;
+    return false;
+  }
 };
 
 /// State to keep track of whether commuting is in flight or whether it's been
@@ -467,7 +478,8 @@ bool WebAssemblyRegStackify::runOnMachin
         // supports intra-block moves) and it's MachineSink's job to catch all
         // the sinking opportunities anyway.
         bool SameBlock = Def->getParent() == &MBB;
-        bool CanMove = SameBlock && IsSafeToMove(Def, Insert, AA, LIS, MRI);
+        bool CanMove = SameBlock && IsSafeToMove(Def, Insert, AA, LIS, MRI) &&
+                       !TreeWalker.IsOnStack(Reg);
         if (CanMove && MRI.hasOneUse(Reg)) {
           Insert = MoveForSingleUse(Reg, Def, MBB, Insert, LIS, MFI);
         } else if (Def->isAsCheapAsAMove() &&

Modified: llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll?rev=259013&r1=259012&r2=259013&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll Wed Jan 27 21:59:09 2016
@@ -244,4 +244,25 @@ define i32 @commute() {
   ret i32 %add3
 }
 
+; Don't stackify a register when it would move a the def of the register past
+; an implicit get_local for the register.
+
+; CHECK-LABEL: no_stackify_past_use:
+; CHECK: i32.call        $1=, callee at FUNCTION, $0
+; CHECK: i32.const       $push0=, 1
+; CHECK: i32.add         $push1=, $0, $pop0
+; CHECK: i32.call        $push2=, callee at FUNCTION, $pop1
+; CHECK: i32.add         $push3=, $1, $pop2
+; CHECK: i32.mul         $push4=, $1, $pop3
+; CHECK: return          $pop4
+declare i32 @callee(i32)
+define i32 @no_stackify_past_use(i32 %arg) {
+  %tmp1 = call i32 @callee(i32 %arg)
+  %tmp2 = add i32 %arg, 1
+  %tmp3 = call i32 @callee(i32 %tmp2)
+  %tmp5 = add i32 %tmp3, %tmp1
+  %tmp6 = mul i32 %tmp5, %tmp1
+  ret i32 %tmp6
+}
+
 !0 = !{}




More information about the llvm-commits mailing list