summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2019-05-29 16:59:48 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2019-05-29 16:59:48 +0000
commitf80c4241b306ce4cf2d718b590e516866d787c67 (patch)
tree3850bfd3cbd2b2e45d60efb551226c579d3d1caf
parent5b2088d1fac1f464cd51d4b660b29c5db47a54c4 (diff)
downloadbcm5719-llvm-f80c4241b306ce4cf2d718b590e516866d787c67.tar.gz
bcm5719-llvm-f80c4241b306ce4cf2d718b590e516866d787c67.zip
CallSiteSplitting: Respect convergent and noduplicate
llvm-svn: 361990
-rw-r--r--llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp3
-rw-r--r--llvm/test/Transforms/CallSiteSplitting/convergent.ll89
-rw-r--r--llvm/test/Transforms/CallSiteSplitting/noduplicate.ll91
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 }
+
OpenPOWER on IntegriCloud