[llvm-branch-commits] [llvm] afbb6d9 - [CVP] Simplify and generalize switch handling
Nikita Popov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Dec 12 12:16:51 PST 2020
Author: Nikita Popov
Date: 2020-12-12T21:12:27+01:00
New Revision: afbb6d97b501502b89bedc3da2a5d7ec00f56dba
URL: https://github.com/llvm/llvm-project/commit/afbb6d97b501502b89bedc3da2a5d7ec00f56dba
DIFF: https://github.com/llvm/llvm-project/commit/afbb6d97b501502b89bedc3da2a5d7ec00f56dba.diff
LOG: [CVP] Simplify and generalize switch handling
CVP currently handles switches by checking an equality predicate
on all edges from predecessor blocks. Of course, this can only
work if the value being switched over is defined in a different block.
Replace this implementation with a call to getPredicateAt(), which
also does the predecessor edge predicate check (if not defined in
the same block), but can also do quite a bit more: It can reason
about phi-nodes by checking edge predicates for incoming values,
it can reason about assumes, and it can reason about block values.
As such, this makes the implementation both simpler and more
powerful. The compile-time impact on CTMark is in the noise.
Added:
Modified:
llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index b7b1b9c6aa58..b671d68031a8 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -330,15 +330,6 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
Value *Cond = I->getCondition();
BasicBlock *BB = I->getParent();
- // If the condition was defined in same block as the switch then LazyValueInfo
- // currently won't say anything useful about it, though in theory it could.
- if (isa<Instruction>(Cond) && cast<Instruction>(Cond)->getParent() == BB)
- return false;
-
- // If the switch is unreachable then trying to improve it is a waste of time.
- pred_iterator PB = pred_begin(BB), PE = pred_end(BB);
- if (PB == PE) return false;
-
// Analyse each switch case in turn.
bool Changed = false;
DenseMap<BasicBlock*, int> SuccessorsCount;
@@ -351,35 +342,9 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
for (auto CI = SI->case_begin(), CE = SI->case_end(); CI != CE;) {
ConstantInt *Case = CI->getCaseValue();
-
- // Check to see if the switch condition is equal to/not equal to the case
- // value on every incoming edge, equal/not equal being the same each time.
- LazyValueInfo::Tristate State = LazyValueInfo::Unknown;
- for (pred_iterator PI = PB; PI != PE; ++PI) {
- // Is the switch condition equal to the case value?
- LazyValueInfo::Tristate Value = LVI->getPredicateOnEdge(CmpInst::ICMP_EQ,
- Cond, Case, *PI,
- BB, SI);
- // Give up on this case if nothing is known.
- if (Value == LazyValueInfo::Unknown) {
- State = LazyValueInfo::Unknown;
- break;
- }
-
- // If this was the first edge to be visited, record that all other edges
- // need to give the same result.
- if (PI == PB) {
- State = Value;
- continue;
- }
-
- // If this case is known to fire for some edges and known not to fire for
- // others then there is nothing we can do - give up.
- if (Value != State) {
- State = LazyValueInfo::Unknown;
- break;
- }
- }
+ LazyValueInfo::Tristate State =
+ LVI->getPredicateAt(CmpInst::ICMP_EQ, Cond, Case, I,
+ /* UseBlockValue */ true);
if (State == LazyValueInfo::False) {
// This case never fires - remove it.
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
index 20d285641da1..0c41bb6270f9 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -285,11 +285,7 @@ define void @switch_nonzero_zext(i8 %s) {
; CHECK-NEXT: br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]]
; CHECK: switch:
; CHECK-NEXT: [[S_EXT:%.*]] = zext i8 [[S]] to i32
-; CHECK-NEXT: switch i32 [[S_EXT]], label [[EXIT]] [
-; CHECK-NEXT: i32 0, label [[UNREACHABLE:%.*]]
-; CHECK-NEXT: i32 1, label [[EXIT]]
-; CHECK-NEXT: i32 -1, label [[EXIT]]
-; CHECK-NEXT: ]
+; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
; CHECK: unreachable:
@@ -319,11 +315,7 @@ define void @switch_assume_nonzero(i32 %s) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[S:%.*]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: switch i32 [[S]], label [[EXIT:%.*]] [
-; CHECK-NEXT: i32 0, label [[UNREACHABLE:%.*]]
-; CHECK-NEXT: i32 1, label [[EXIT]]
-; CHECK-NEXT: i32 -1, label [[EXIT]]
-; CHECK-NEXT: ]
+; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
; CHECK: unreachable:
@@ -355,11 +347,7 @@ define void @switch_nonzero_phi(i1 %cond) {
; CHECK-NEXT: br label [[SWITCH]]
; CHECK: switch:
; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ]
-; CHECK-NEXT: switch i32 [[S]], label [[EXIT:%.*]] [
-; CHECK-NEXT: i32 0, label [[UNREACHABLE:%.*]]
-; CHECK-NEXT: i32 1, label [[EXIT]]
-; CHECK-NEXT: i32 -1, label [[EXIT]]
-; CHECK-NEXT: ]
+; CHECK-NEXT: br label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
; CHECK: unreachable:
More information about the llvm-branch-commits
mailing list