summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/CodeGenPrepare.cpp
diff options
context:
space:
mode:
authorJohn Brawn <john.brawn@arm.com>2017-10-03 13:04:15 +0000
committerJohn Brawn <john.brawn@arm.com>2017-10-03 13:04:15 +0000
commiteb83c7554e5eee2b0c4c145050a0da901c25e4bb (patch)
tree53a395f9f0776d6403d24bee05cb326392f50453 /llvm/lib/CodeGen/CodeGenPrepare.cpp
parent68aa7de5172002935b14549aedeb7310b0b715e5 (diff)
downloadbcm5719-llvm-eb83c7554e5eee2b0c4c145050a0da901c25e4bb.tar.gz
bcm5719-llvm-eb83c7554e5eee2b0c4c145050a0da901c25e4bb.zip
[CGP] In optimizeMemoryInst handle select similarly to phi
This lets us optimize away selects that perform the same address computation in two different ways and is also the first step towards being able to handle selects between two different, but compatible, address computations. Differential Revision: https://reviews.llvm.org/D38242 llvm-svn: 314794
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index bbd1f59eb2f..e6a7a3e978c 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -4389,11 +4389,11 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
SmallPtrSet<Value*, 16> Visited;
worklist.push_back(Addr);
- // Use a worklist to iteratively look through PHI nodes, and ensure that
- // the addressing mode obtained from the non-PHI roots of the graph
- // are equivalent.
+ // Use a worklist to iteratively look through PHI and select nodes, and
+ // ensure that the addressing mode obtained from the non-PHI/select roots of
+ // the graph are equivalent.
bool AddrModeFound = false;
- bool PhiSeen = false;
+ bool PhiOrSelectSeen = false;
SmallVector<Instruction*, 16> AddrModeInsts;
ExtAddrMode AddrMode;
TypePromotionTransaction TPT(RemovedInsts);
@@ -4419,7 +4419,14 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
if (PHINode *P = dyn_cast<PHINode>(V)) {
for (Value *IncValue : P->incoming_values())
worklist.push_back(IncValue);
- PhiSeen = true;
+ PhiOrSelectSeen = true;
+ continue;
+ }
+ // Similar for select.
+ if (SelectInst *SI = dyn_cast<SelectInst>(V)) {
+ worklist.push_back(SI->getFalseValue());
+ worklist.push_back(SI->getTrueValue());
+ PhiOrSelectSeen = true;
continue;
}
@@ -4452,8 +4459,10 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
TPT.commit();
// If all the instructions matched are already in this BB, don't do anything.
- // If we saw Phi node then it is not local definitely.
- if (!PhiSeen && none_of(AddrModeInsts, [&](Value *V) {
+ // If we saw a Phi node then it is not local definitely, and if we saw a select
+ // then we want to push the address calculation past it even if it's already
+ // in this BB.
+ if (!PhiOrSelectSeen && none_of(AddrModeInsts, [&](Value *V) {
return IsNonLocalValue(V, MemoryInst->getParent());
})) {
DEBUG(dbgs() << "CGP: Found local addrmode: " << AddrMode << "\n");
OpenPOWER on IntegriCloud