[llvm] r269843 - [WebAssembly] Don't stackify calls past stack pointer modifications.

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Tue May 17 14:14:26 PDT 2016


Author: djg
Date: Tue May 17 16:14:26 2016
New Revision: 269843

URL: http://llvm.org/viewvc/llvm-project?rev=269843&view=rev
Log:
[WebAssembly] Don't stackify calls past stack pointer modifications.

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

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp?rev=269843&r1=269842&r2=269843&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp Tue May 17 16:14:26 2016
@@ -82,7 +82,8 @@ static void writeSPToMemory(unsigned Src
                             MachineBasicBlock::iterator &InsertAddr,
                             MachineBasicBlock::iterator &InsertStore,
                             DebugLoc DL) {
-  auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
+  const char *ES = "__stack_pointer";
+  auto *SPSymbol = MF.createExternalSymbolName(ES);
   MachineRegisterInfo &MRI = MF.getRegInfo();
   const TargetRegisterClass *PtrRC =
       MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
@@ -92,7 +93,8 @@ static void writeSPToMemory(unsigned Src
 
   BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
       .addExternalSymbol(SPSymbol);
-  auto *MMO = new MachineMemOperand(MachinePointerInfo(),
+  auto *MMO = new MachineMemOperand(MachinePointerInfo(MF.getPSVManager()
+                                        .getExternalSymbolCallEntry(ES)),
                                     MachineMemOperand::MOStore, 4, 4);
   BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32),
           Discard)
@@ -138,14 +140,12 @@ void WebAssemblyFrameLowering::emitProlo
       MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
   unsigned SPAddr = MRI.createVirtualRegister(PtrRC);
   unsigned SPReg = MRI.createVirtualRegister(PtrRC);
-  auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
+  const char *ES = "__stack_pointer";
+  auto *SPSymbol = MF.createExternalSymbolName(ES);
   BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
       .addExternalSymbol(SPSymbol);
-  // This MachinePointerInfo should reference __stack_pointer as well but
-  // doesn't because MachinePointerInfo() takes a GV which we don't have for
-  // __stack_pointer. TODO: check if PseudoSourceValue::ExternalSymbolCallEntry
-  // is appropriate instead. (likewise for EmitEpologue below)
-  auto *LoadMMO = new MachineMemOperand(MachinePointerInfo(),
+  auto *LoadMMO = new MachineMemOperand(MachinePointerInfo(MF.getPSVManager()
+                                            .getExternalSymbolCallEntry(ES)),
                                         MachineMemOperand::MOLoad, 4, 4);
   // Load the SP value.
   BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32),

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp?rev=269843&r1=269842&r2=269843&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp Tue May 17 16:14:26 2016
@@ -90,7 +90,11 @@ static void ImposeStackOrdering(MachineI
 // MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
 // effects.
 static void QueryCallee(const MachineInstr *MI, unsigned CalleeOpNo,
-                        bool &Read, bool &Write, bool &Effects) {
+                        bool &Read, bool &Write, bool &Effects,
+                        bool &StackPointer) {
+  // All calls can use the stack pointer.
+  StackPointer = true;
+
   const MachineOperand &MO = MI->getOperand(CalleeOpNo);
   if (MO.isGlobal()) {
     const Constant *GV = MO.getGlobal();
@@ -116,10 +120,10 @@ static void QueryCallee(const MachineIns
   Effects = true;
 }
 
-// Determine whether MI reads memory, writes memory, and/or has side
-// effects.
+// Determine whether MI reads memory, writes memory, has side effects,
+// and/or uses the __stack_pointer value.
 static void Query(const MachineInstr *MI, AliasAnalysis &AA,
-                  bool &Read, bool &Write, bool &Effects) {
+                  bool &Read, bool &Write, bool &Effects, bool &StackPointer) {
   assert(!MI->isPosition());
   assert(!MI->isTerminator());
   assert(!MI->isDebugValue());
@@ -129,9 +133,21 @@ static void Query(const MachineInstr *MI
     Read = true;
 
   // Check for stores.
-  if (MI->mayStore())
+  if (MI->mayStore()) {
     Write = true;
-  else if (MI->hasOrderedMemoryRef()) {
+
+    // Check for stores to __stack_pointer.
+    for (auto MMO : MI->memoperands()) {
+      const MachinePointerInfo &MPI = MMO->getPointerInfo();
+      if (MPI.V.is<const PseudoSourceValue *>()) {
+        auto PSV = MPI.V.get<const PseudoSourceValue *>();
+        if (const ExternalSymbolPseudoSourceValue *EPSV =
+                dyn_cast<ExternalSymbolPseudoSourceValue>(PSV))
+          if (StringRef(EPSV->getSymbol()) == "__stack_pointer")
+            StackPointer = true;
+      }
+    }
+  } else if (MI->hasOrderedMemoryRef()) {
     switch (MI->getOpcode()) {
     case WebAssembly::DIV_S_I32: case WebAssembly::DIV_S_I64:
     case WebAssembly::REM_S_I32: case WebAssembly::REM_S_I64:
@@ -181,13 +197,13 @@ static void Query(const MachineInstr *MI
   if (MI->isCall()) {
     switch (MI->getOpcode()) {
     case WebAssembly::CALL_VOID:
-      QueryCallee(MI, 0, Read, Write, Effects);
+      QueryCallee(MI, 0, Read, Write, Effects, StackPointer);
       break;
     case WebAssembly::CALL_I32:
     case WebAssembly::CALL_I64:
     case WebAssembly::CALL_F32:
     case WebAssembly::CALL_F64:
-      QueryCallee(MI, 1, Read, Write, Effects);
+      QueryCallee(MI, 1, Read, Write, Effects, StackPointer);
       break;
     case WebAssembly::CALL_INDIRECT_VOID:
     case WebAssembly::CALL_INDIRECT_I32:
@@ -197,6 +213,7 @@ static void Query(const MachineInstr *MI
       Read = true;
       Write = true;
       Effects = true;
+      StackPointer = true;
       break;
     default:
       llvm_unreachable("unexpected call opcode");
@@ -308,12 +325,12 @@ static bool IsSafeToMove(const MachineIn
       return false;
   }
 
-  bool Read = false, Write = false, Effects = false;
-  Query(Def, AA, Read, Write, Effects);
+  bool Read = false, Write = false, Effects = false, StackPointer = false;
+  Query(Def, AA, Read, Write, Effects, StackPointer);
 
   // If the instruction does not access memory and has no side effects, it has
   // no additional dependencies.
-  if (!Read && !Write && !Effects)
+  if (!Read && !Write && !Effects && !StackPointer)
     return true;
 
   // Scan through the intervening instructions between Def and Insert.
@@ -322,13 +339,17 @@ static bool IsSafeToMove(const MachineIn
     bool InterveningRead = false;
     bool InterveningWrite = false;
     bool InterveningEffects = false;
-    Query(I, AA, InterveningRead, InterveningWrite, InterveningEffects);
+    bool InterveningStackPointer = false;
+    Query(I, AA, InterveningRead, InterveningWrite, InterveningEffects,
+          InterveningStackPointer);
     if (Effects && InterveningEffects)
       return false;
     if (Read && InterveningWrite)
       return false;
     if (Write && (InterveningRead || InterveningWrite))
       return false;
+    if (StackPointer && InterveningStackPointer)
+      return false;
   }
 
   return true;

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=269843&r1=269842&r2=269843&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/reg-stackify.ll Tue May 17 16:14:26 2016
@@ -402,7 +402,7 @@ define i32 @no_stackify_past_epilogue()
 
 ; Stackify a loop induction variable into a loop comparison.
 
-; CHECK_LABEL: stackify_indvar:
+; CHECK-LABEL: stackify_indvar:
 ; CHECK:             i32.const   $push[[L5:.+]]=, 1{{$}}
 ; CHECK-NEXT:        i32.add     $push[[L4:.+]]=, $[[R0:.+]], $pop[[L5]]{{$}}
 ; CHECK-NEXT:        tee_local   $push[[L3:.+]]=, $[[R0]]=, $pop[[L4]]{{$}}
@@ -424,6 +424,20 @@ bb10:
   ret void
 }
 
+; Don't stackify a call past a __stack_pointer store.
+
+; CHECK-LABEL: stackpointer_dependency:
+; CHECK:      call {{.+}}, stackpointer_callee at FUNCTION,
+; CHECK:      i32.const $push[[L0:.+]]=, __stack_pointer
+; CHECK-NEXT: i32.store $discard=, 0($pop[[L0]]),
+declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
+declare i8* @llvm.frameaddress(i32)
+define i32 @stackpointer_dependency(i8* readnone) {
+  %2 = tail call i8* @llvm.frameaddress(i32 0)
+  %3 = tail call i32 @stackpointer_callee(i8* %0, i8* %2)
+  ret i32 %3
+}
+
 !llvm.module.flags = !{!0}
 !llvm.dbg.cu = !{!1}
 




More information about the llvm-commits mailing list