[PATCH] D28834: Improve what can be promoted in LICM.

Xin Tong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 17 16:29:41 PST 2017


trentxintong created this revision.

In case of non-alloca pointers, we check for whether it is a pointer
from malloc-like calls and it is not captured. In such case, we can
promote the pointer, as the caller will have no way to access this pointer
even if there is unwinding in middle of the loop.


https://reviews.llvm.org/D28834

Files:
  lib/Transforms/Scalar/LICM.cpp
  test/Transforms/LICM/scalar-promote-unwind.ll


Index: test/Transforms/LICM/scalar-promote-unwind.ll
===================================================================
--- test/Transforms/LICM/scalar-promote-unwind.ll
+++ test/Transforms/LICM/scalar-promote-unwind.ll
@@ -137,6 +137,42 @@
   resume { i8*, i32 } %lpad.val3
 }
 
+; This is a local allocation by new and the returned pointer is
+; not captured, so in case of unwind, the caller will have no way
+; to access this memory.
+define void @local_allocation(i1 zeroext %y) uwtable {
+entry:
+  %n = call i8* @_Znwm(i64 4)
+  %a = bitcast i8* %n to i32*
+  br label %for.body
+
+; CHECK: for.body:
+; CHECK-NOT: load
+; CHECK-NOT: store
+; CHECK: br
+for.body:
+  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %0 = load i32, i32* %a, align 4
+  %add = add nsw i32 %0, 1
+  store i32 %add, i32* %a, align 4
+  br i1 %y, label %if.then, label %for.inc
+
+if.then:
+  tail call void @f()
+  br label %for.inc
+
+for.inc:
+  %inc = add nuw nsw i32 %i.03, 1
+  %exitcond = icmp eq i32 %inc, 10000
+  br i1 %exitcond, label %for.cond.cleanup, label %for.body
+
+; CHECK: for.cond.cleanup:
+; CHECK: store
+; CHECK: ret void
+for.cond.cleanup:
+  ret void
+}
+
 declare void @boo()
 
 declare i32 @__gxx_personality_v0(...)
@@ -148,3 +184,6 @@
 declare void @__cxa_end_catch()
 
 declare void @f() uwtable
+
+; Function Attrs: nobuiltin
+declare noalias i8* @_Znwm(i64)
Index: lib/Transforms/Scalar/LICM.cpp
===================================================================
--- lib/Transforms/Scalar/LICM.cpp
+++ lib/Transforms/Scalar/LICM.cpp
@@ -1004,8 +1004,18 @@
     // That said, we can't actually make the unwind edge explicit. Therefore,
     // we have to prove that the store is dead along the unwind edge.
     //
-    // Currently, this code just special-cases alloca instructions.
-    if (!isa<AllocaInst>(GetUnderlyingObject(SomePtr, MDL)))
+    // If the underlying object is not an alloca, nor a pointer that does not
+    // escape, then we can not effectively prove that the store is dead along
+    // the unwind edge. i.e. the caller of this function could have ways to
+    // access the pointed object.
+    //
+    // NOTE: PointerMayBeCaptured is not enough as the pointer may have escaped
+    // even though its not captured by the enclosing function. Standard allocation
+    // functions like malloc, calloc, and operator new return values which can
+    // be assumed not to have previously escaped.
+    Value *Object = GetUnderlyingObject(SomePtr, MDL);
+    if (!isa<AllocaInst>(Object) &&
+        (!isAllocLikeFn(Object, TLI) || PointerMayBeCaptured(Object, true, true)))
       return false;
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28834.84776.patch
Type: text/x-patch
Size: 2648 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170118/8f57aaa4/attachment.bin>


More information about the llvm-commits mailing list