[PATCH] D18066: Add some shortcuts in Value Propagation for alloca

Wei Mi via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 10 15:00:38 PST 2016


wmi created this revision.
wmi added reviewers: atrick, reames, hfinkel.
wmi added subscribers: llvm-commits, davidxl.
wmi set the repository for this revision to rL LLVM.

The is the part1 to solve https://llvm.org/bugs/show_bug.cgi?id=10584

Inlining functions called inside of a large loop can introduce many long stretched variables because the alloca instructions inside callee will be promoted to the entry of the caller. Such long stretched variables could increase the compile time of correlated value propagation (CVP) and register allocation significantly (More significantly for value propagation).

The fact that a lot of alloca instructions are promoted can be used to reduce the compile time of CVP. CVP checks non-null for pointer params of each callsite. If we know the def of param is an alloca instruction, we know it is non-null without querying LVI. Similarly, CVP checks constant pointer for each mem access. If the def of the pointer is an alloca instruction, we know it is not a constant pointer without querying LVI. These shortcuts can reduce the cost of CVP significantly.

Repository:
  rL LLVM

http://reviews.llvm.org/D18066

Files:
  lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
  test/Transforms/CorrelatedValuePropagation/alloca.ll

Index: test/Transforms/CorrelatedValuePropagation/alloca.ll
===================================================================
--- test/Transforms/CorrelatedValuePropagation/alloca.ll
+++ test/Transforms/CorrelatedValuePropagation/alloca.ll
@@ -0,0 +1,44 @@
+; RUN: opt -S -correlated-propagation -debug-only=lazy-value-info <%s 2>&1 | FileCheck %s
+;
+; Shortcut in Correlated Value Propagation ensures not to take Lazy Value Info
+; analysis for %a.i because %a.i is defined by alloca and we know it is not-constant.
+; CHECK-NOT: LVI Getting block end value   %a.i = alloca i64, align 8 at 'for.body'
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [8 x i8] c"a = %l\0A\00", align 1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start(i64, i8* nocapture)
+
+declare void @hoo(i64*)
+
+declare i32 @printf(i8* nocapture readonly, ...)
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end(i64, i8* nocapture)
+
+define void @goo(i32 %N) {
+entry:
+  %a.i = alloca i64, align 8
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i32 %i.0, %N
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %tmp = bitcast i64* %a.i to i8*
+  call void @llvm.lifetime.start(i64 8, i8* %tmp)
+  call void @hoo(i64* nonnull %a.i)
+  %tmp1 = load volatile i64, i64* %a.i, align 8
+  %call.i = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %tmp1)
+  call void @llvm.lifetime.end(i64 8, i8* %tmp)
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
Index: lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
===================================================================
--- lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -177,6 +177,9 @@
     Pointer = cast<StoreInst>(I)->getPointerOperand();
 
   if (isa<Constant>(Pointer)) return false;
+  // For pointer defined by AllocaInst, it cannot be a constant.
+  if (dyn_cast<AllocaInst>(Pointer))
+    return false;
 
   Constant *C = LVI->getConstant(Pointer, I->getParent(), I);
   if (!C) return false;
@@ -315,11 +318,13 @@
     // Try to mark pointer typed parameters as non-null.  We skip the
     // relatively expensive analysis for constants which are obviously either
     // null or non-null to start with.
+    // For pointer defined by AllocaInst, we know it is non-null.
     if (Type && !CS.paramHasAttr(ArgNo + 1, Attribute::NonNull) &&
-        !isa<Constant>(V) && 
-        LVI->getPredicateAt(ICmpInst::ICMP_EQ, V,
-                            ConstantPointerNull::get(Type),
-                            CS.getInstruction()) == LazyValueInfo::False)
+        !isa<Constant>(V) &&
+        (dyn_cast<AllocaInst>(V) ||
+         LVI->getPredicateAt(ICmpInst::ICMP_EQ, V,
+                             ConstantPointerNull::get(Type),
+                             CS.getInstruction()) == LazyValueInfo::False))
       Indices.push_back(ArgNo + 1);
     ArgNo++;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18066.50361.patch
Type: text/x-patch
Size: 3372 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160310/d7c5d8e4/attachment.bin>


More information about the llvm-commits mailing list