[PATCH] D20174: [InstCombine] Allow removal of PHI cycles which only contain PHIs
silviu.baranga@arm.com via llvm-commits
llvm-commits at lists.llvm.org
Wed May 11 09:40:38 PDT 2016
sbaranga created this revision.
sbaranga added reviewers: majnemer, jmolloy.
sbaranga added a subscriber: llvm-commits.
This teaches instcombine to be able to remove PHI cycles which
only contain PHIs.
When a PHI doesn't have a non-PHI incoming value, we will now
try to resolve the PHI to each of the incoming values.
http://reviews.llvm.org/D20174
Files:
lib/Transforms/InstCombine/InstCombinePHI.cpp
test/Transforms/InstCombine/phi-cycle.ll
Index: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -591,10 +591,10 @@
return false;
}
-/// Return true if this phi node is always equal to NonPhiInVal.
+/// Return true if this phi node is always equal to Val.
/// This happens with mutually cyclic phi nodes like:
/// z = some value; x = phi (y, z); y = phi (x, z)
-static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
+static bool PHIsEqualValue(PHINode *PN, Value *Val,
SmallPtrSetImpl<PHINode*> &ValueEqualPHIs) {
// See if we already saw this PHI node.
if (!ValueEqualPHIs.insert(PN).second)
@@ -607,11 +607,14 @@
// Scan the operands to see if they are either phi nodes or are equal to
// the value.
for (Value *Op : PN->incoming_values()) {
- if (PHINode *OpPN = dyn_cast<PHINode>(Op)) {
- if (!PHIsEqualValue(OpPN, NonPhiInVal, ValueEqualPHIs))
- return false;
- } else if (Op != NonPhiInVal)
- return false;
+ if (Val == Op)
+ continue;
+
+ if (PHINode *OpPN = dyn_cast<PHINode>(Op))
+ if (PHIsEqualValue(OpPN, Val, ValueEqualPHIs))
+ continue;
+
+ return false;
}
return true;
@@ -962,6 +965,21 @@
if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs))
return replaceInstUsesWith(PN, NonPhiInVal);
}
+ } else {
+ // This is a PHI of PHIs. See if any one of the incoming values
+ // can be proven to be the equal with this PHI.
+ InValNo = 0;
+ while (InValNo != NumIncomingVals) {
+ Value *Val = PN.getIncomingValue(InValNo);
+
+ // Scan to see if we can prove that this is a phi cycle equal to
+ // Val.
+ SmallPtrSet<PHINode*, 16> ValueEqualPHIs;
+ if (PHIsEqualValue(&PN, Val, ValueEqualPHIs))
+ return replaceInstUsesWith(PN, Val);
+
+ ++InValNo;
+ }
}
}
Index: test/Transforms/InstCombine/phi-cycle.ll
===================================================================
--- /dev/null
+++ test/Transforms/InstCombine/phi-cycle.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128:n8:16:32:64"
+
+; Check that we can remove a dead phi cycle made up
+; entirely out of PHIs.
+
+; CHECK-LABEL: func1
+define i32 @func1(i1 %c, i1 %c2, i32 %x) {
+entry:
+ br i1 %c, label %if.else, label %pre
+
+if.else:
+ br label %pre
+
+pre:
+ %p0 = phi i32 [ %x, %entry ], [ 1, %if.else ]
+ br label %loop
+
+loop:
+ %p1 = phi i32 [ %p2, %loop-bb1 ], [ %p0, %pre ]
+ br i1 %c2, label %loop-bb1, label %loop-bb2
+
+loop-bb2:
+ br label %loop-bb1
+
+loop-bb1:
+ %p2 = phi i32 [ %p0, %loop ] , [ %p1, %loop-bb2 ]
+ br i1 %c, label %loop, label %exit
+
+exit:
+
+; CHECK: ret i32 %p0
+ ret i32 %p1
+}
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20174.56931.patch
Type: text/x-patch
Size: 3028 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160511/08c586bc/attachment.bin>
More information about the llvm-commits
mailing list