[PATCH] D109916: Introduce API for stack state modifying instructions

Anna Thomas via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 16 13:16:07 PDT 2021


anna created this revision.
anna added reviewers: nikic, apilipenko, reames, lebedev.ri.
Herald added subscribers: dexonsmith, hiraditya.
anna requested review of this revision.
Herald added a project: LLVM.

This patch introduces an API to identify instructions that modify the
function stack state. The name here may not be accurate enough, but the
idea is to use a common API for transforms that move instructions (see
updated transforms).

This is also used in an upcoming change in InstCombine.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D109916

Files:
  llvm/include/llvm/IR/Instruction.h
  llvm/lib/IR/Instruction.cpp
  llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
  llvm/lib/Transforms/Scalar/IndVarSimplify.cpp


Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1241,8 +1241,7 @@
     // Don't sink alloca: we never want to sink static alloca's out of the
     // entry block, and correctly sinking dynamic alloca's requires
     // checks for stacksave/stackrestore intrinsics.
-    // FIXME: Refactor this check somehow?
-    if (isa<AllocaInst>(I))
+    if (I->isFunctionStackStateModifying())
       continue;
 
     // Determine if there is a use in or before the loop (direct or
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3671,7 +3671,7 @@
   // remain in the entry block, and dynamic allocas must not be sunk in between
   // a stacksave / stackrestore pair, which would incorrectly shorten its
   // lifetime.
-  if (isa<AllocaInst>(I))
+  if (I->isFunctionStackStateModifying())
     return false;
 
   // Do not sink into catchswitch blocks.
Index: llvm/lib/IR/Instruction.cpp
===================================================================
--- llvm/lib/IR/Instruction.cpp
+++ llvm/lib/IR/Instruction.cpp
@@ -680,6 +680,20 @@
   return isa<ResumeInst>(this);
 }
 
+bool Instruction::isFunctionStackStateModifying() const {
+  // This includes both static allocas (in entry blocks) and dynamic allocas
+  // (recorded between a stacksave/stackrestore pair). 
+  // Correctly sinking dynamic allocas require proper checks for
+  // stacksave/stackrestore intrinsics.
+  if (isa<AllocaInst>(this))
+    return true;
+  auto *II = dyn_cast<IntrinsicInst>(this);
+  if (!II)
+    return false;
+  Intrinsic::ID ID = II->getIntrinsicID();
+  return ID == Intrinsic::stacksave || ID == Intrinsic::stackrestore;
+}
+
 bool Instruction::mayHaveSideEffects() const {
   return mayWriteToMemory() || mayThrow() || !willReturn();
 }
Index: llvm/include/llvm/IR/Instruction.h
===================================================================
--- llvm/include/llvm/IR/Instruction.h
+++ llvm/include/llvm/IR/Instruction.h
@@ -634,6 +634,15 @@
     }
   }
 
+  /// Returns true if I modifies the stack state of the function.
+  /// These are:
+  ///   1. static and dynamic allocas
+  ///   2. llvm.stacksave and llvm.stackrestore intrinsics used with dynamic
+  ///      allocas. 
+  /// Use this API to identify instructions that are illegal to move (even if
+  /// they are marked side-effect free: allocas for example).
+  bool isFunctionStackStateModifying() const;
+
   /// Return true if the instruction may have side effects.
   ///
   /// Side effects are:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109916.373049.patch
Type: text/x-patch
Size: 2844 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210916/c00bcea8/attachment.bin>


More information about the llvm-commits mailing list