diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-05-29 16:59:48 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-05-29 16:59:48 +0000 |
commit | f80c4241b306ce4cf2d718b590e516866d787c67 (patch) | |
tree | 3850bfd3cbd2b2e45d60efb551226c579d3d1caf | |
parent | 5b2088d1fac1f464cd51d4b660b29c5db47a54c4 (diff) | |
download | bcm5719-llvm-f80c4241b306ce4cf2d718b590e516866d787c67.tar.gz bcm5719-llvm-f80c4241b306ce4cf2d718b590e516866d787c67.zip |
CallSiteSplitting: Respect convergent and noduplicate
llvm-svn: 361990
-rw-r--r-- | llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp | 3 | ||||
-rw-r--r-- | llvm/test/Transforms/CallSiteSplitting/convergent.ll | 89 | ||||
-rw-r--r-- | llvm/test/Transforms/CallSiteSplitting/noduplicate.ll | 91 |
3 files changed, 183 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp index 6b749238d2b..3519b000a33 100644 --- a/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp +++ b/llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp @@ -183,6 +183,9 @@ static SmallVector<BasicBlock *, 2> getTwoPredecessors(BasicBlock *BB) { } static bool canSplitCallSite(CallSite CS, TargetTransformInfo &TTI) { + if (CS.isConvergent() || CS.cannotDuplicate()) + return false; + // FIXME: As of now we handle only CallInst. InvokeInst could be handled // without too much effort. Instruction *Instr = CS.getInstruction(); diff --git a/llvm/test/Transforms/CallSiteSplitting/convergent.ll b/llvm/test/Transforms/CallSiteSplitting/convergent.ll new file mode 100644 index 00000000000..4dcff027434 --- /dev/null +++ b/llvm/test/Transforms/CallSiteSplitting/convergent.ll @@ -0,0 +1,89 @@ +; RUN: opt -S -callsite-splitting -callsite-splitting-duplication-threshold=100000000 < %s | FileCheck -enable-var-scope %s + +; Convergent calls should not be duplicated in this case +; CHECK-LABEL: define void @convergent_caller( +; CHECK: call void @convergent_callee( +; CHECK-NOT: call void @convergent_callee( +define void @convergent_caller(i1 %c, i8* %a_elt, i8* %b_elt) #0 { +entry: + br label %Top + +Top: + %tobool1 = icmp eq i8* %a_elt, null + br i1 %tobool1, label %CallSiteBB, label %NextCond + +NextCond: + %cmp = icmp ne i8* %b_elt, null + br i1 %cmp, label %CallSiteBB, label %End + +CallSiteBB: + %p = phi i1 [ false, %Top ], [ %c, %NextCond ] + call void @convergent_callee(i8* %a_elt, i1 %p) + br label %End + +End: + ret void +} + +; CHECK-LABEL: define void @convergent_callee( +; CHECK: call void @convergent_external( +; CHECK-NOT: call void @convergent_external( +define void @convergent_callee(i8* %a_elt, i1 %c) #0 { +entry: + %tobool = icmp ne i8* %a_elt, null + br i1 %tobool, label %then, label %endif + +then: + br label %endif + +endif: + call void @convergent_external(i8* %a_elt) #0 + ret void +} + +; Make sure an otherwise identical function is transformed +; CHECK-LABEL: define void @reference_caller( +; CHECK: call void @nonconvergent_callee( +; CHECK: call void @nonconvergent_callee( +define void @reference_caller(i1 %c, i8* %a_elt, i8* %b_elt) #1 { +entry: + br label %Top + +Top: + %tobool1 = icmp eq i8* %a_elt, null + br i1 %tobool1, label %CallSiteBB, label %NextCond + +NextCond: + %cmp = icmp ne i8* %b_elt, null + br i1 %cmp, label %CallSiteBB, label %End + +CallSiteBB: + %p = phi i1 [ false, %Top ], [ %c, %NextCond ] + call void @nonconvergent_callee(i8* %a_elt, i1 %p) + br label %End + +End: + ret void +} + +; CHECK-LABEL: define void @nonconvergent_callee( +; CHECK: call void @nonconvergent_external( +; CHECK-NOT: call void @nonconvergent_external( +define void @nonconvergent_callee(i8* %a_elt, i1 %c) #1 { +entry: + %tobool = icmp ne i8* %a_elt, null + br i1 %tobool, label %then, label %endif + +then: + br label %endif + +endif: + call void @nonconvergent_external(i8* %a_elt) + ret void +} + +declare void @convergent_external(i8*) #0 +declare void @nonconvergent_external(i8*) #1 + +attributes #0 = { convergent nounwind } +attributes #1 = { nounwind } diff --git a/llvm/test/Transforms/CallSiteSplitting/noduplicate.ll b/llvm/test/Transforms/CallSiteSplitting/noduplicate.ll new file mode 100644 index 00000000000..cdc4fdc77da --- /dev/null +++ b/llvm/test/Transforms/CallSiteSplitting/noduplicate.ll @@ -0,0 +1,91 @@ +; RUN: opt -S -callsite-splitting -callsite-splitting-duplication-threshold=100000000 < %s | FileCheck -enable-var-scope %s +; RUN: opt -S -callsite-splitting -callsite-splitting-duplication-threshold=100000000 < %s | FileCheck -enable-var-scope %s + +; Noduplicate calls should not be duplicated +; CHECK-LABEL: define void @noduplicate_caller( +; CHECK: call void @noduplicate_callee( +; CHECK-NOT: call void @noduplicate_callee( +define void @noduplicate_caller(i1 %c, i8* %a_elt, i8* %b_elt) #0 { +entry: + br label %Top + +Top: + %tobool1 = icmp eq i8* %a_elt, null + br i1 %tobool1, label %CallSiteBB, label %NextCond + +NextCond: + %cmp = icmp ne i8* %b_elt, null + br i1 %cmp, label %CallSiteBB, label %End + +CallSiteBB: + %p = phi i1 [ false, %Top ], [ %c, %NextCond ] + call void @noduplicate_callee(i8* %a_elt, i1 %p) + br label %End + +End: + ret void +} + +; CHECK-LABEL: define void @noduplicate_callee( +; CHECK: call void @noduplicate_external( +; CHECK-NOT: call void @noduplicate_external( +define void @noduplicate_callee(i8* %a_elt, i1 %c) #0 { +entry: + %tobool = icmp ne i8* %a_elt, null + br i1 %tobool, label %then, label %endif + +then: + br label %endif + +endif: + call void @noduplicate_external(i8* %a_elt) #0 + ret void +} + +; Make sure an otherwise identical function is transformed +; CHECK-LABEL: define void @reference_caller( +; CHECK: call void @nonnoduplicate_callee( +; CHECK: call void @nonnoduplicate_callee( +define void @reference_caller(i1 %c, i8* %a_elt, i8* %b_elt) #1 { +entry: + br label %Top + +Top: + %tobool1 = icmp eq i8* %a_elt, null + br i1 %tobool1, label %CallSiteBB, label %NextCond + +NextCond: + %cmp = icmp ne i8* %b_elt, null + br i1 %cmp, label %CallSiteBB, label %End + +CallSiteBB: + %p = phi i1 [ false, %Top ], [ %c, %NextCond ] + call void @nonnoduplicate_callee(i8* %a_elt, i1 %p) + br label %End + +End: + ret void +} + +; CHECK-LABEL: define void @nonnoduplicate_callee( +; CHECK: call void @nonnoduplicate_external( +; CHECK-NOT: call void @nonnoduplicate_external( +define void @nonnoduplicate_callee(i8* %a_elt, i1 %c) #1 { +entry: + %tobool = icmp ne i8* %a_elt, null + br i1 %tobool, label %then, label %endif + +then: + br label %endif + +endif: + call void @nonnoduplicate_external(i8* %a_elt) + ret void +} + +declare void @noduplicate_external(i8*) #0 +declare void @nonnoduplicate_external(i8*) #1 + +attributes #0 = { noduplicate nounwind } +attributes #1 = { nounwind } + |