summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorHaicheng Wu <haicheng@codeaurora.org>2017-09-27 14:44:56 +0000
committerHaicheng Wu <haicheng@codeaurora.org>2017-09-27 14:44:56 +0000
commit3ec848bc50b46d0583689cd83f4da4b1d23690cf (patch)
tree2fe8a68c1548b9eb5b790adccec4e03e2727d31d /llvm/lib
parent87337a2bb924c5e057355d82c912f2fd21c9f01e (diff)
downloadbcm5719-llvm-3ec848bc50b46d0583689cd83f4da4b1d23690cf.tar.gz
bcm5719-llvm-3ec848bc50b46d0583689cd83f4da4b1d23690cf.zip
[InlineCost] add visitSelectInst()
InlineCost can understand Select IR now. This patch finds free Select IRs and continue the propagation of SimplifiedValues, ConstantOffsetPtrs, and SROAArgValues. Differential Revision: https://reviews.llvm.org/D37198 llvm-svn: 314307
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/InlineCost.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index 416298b51b7..2ee75c83d70 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -241,6 +241,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
bool visitCallSite(CallSite CS);
bool visitReturnInst(ReturnInst &RI);
bool visitBranchInst(BranchInst &BI);
+ bool visitSelectInst(SelectInst &SI);
bool visitSwitchInst(SwitchInst &SI);
bool visitIndirectBrInst(IndirectBrInst &IBI);
bool visitResumeInst(ResumeInst &RI);
@@ -1177,6 +1178,87 @@ bool CallAnalyzer::visitBranchInst(BranchInst &BI) {
SimplifiedValues.lookup(BI.getCondition()));
}
+bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
+ bool CheckSROA = SI.getType()->isPointerTy();
+ Value *TrueVal = SI.getTrueValue();
+ Value *FalseVal = SI.getFalseValue();
+
+ Constant *TrueC = dyn_cast<Constant>(TrueVal);
+ if (!TrueC)
+ TrueC = SimplifiedValues.lookup(TrueVal);
+ Constant *FalseC = dyn_cast<Constant>(FalseVal);
+ if (!FalseC)
+ FalseC = SimplifiedValues.lookup(FalseVal);
+ Constant *CondC =
+ dyn_cast_or_null<Constant>(SimplifiedValues.lookup(SI.getCondition()));
+
+ if (!CondC) {
+ // Select C, X, X => X
+ if (TrueC == FalseC && TrueC) {
+ SimplifiedValues[&SI] = TrueC;
+ return true;
+ }
+
+ if (!CheckSROA)
+ return Base::visitSelectInst(SI);
+
+ std::pair<Value *, APInt> TrueBaseAndOffset =
+ ConstantOffsetPtrs.lookup(TrueVal);
+ std::pair<Value *, APInt> FalseBaseAndOffset =
+ ConstantOffsetPtrs.lookup(FalseVal);
+ if (TrueBaseAndOffset == FalseBaseAndOffset && TrueBaseAndOffset.first) {
+ ConstantOffsetPtrs[&SI] = TrueBaseAndOffset;
+
+ Value *SROAArg;
+ DenseMap<Value *, int>::iterator CostIt;
+ if (lookupSROAArgAndCost(TrueVal, SROAArg, CostIt))
+ SROAArgValues[&SI] = SROAArg;
+ return true;
+ }
+
+ return Base::visitSelectInst(SI);
+ }
+
+ // Select condition is a constant.
+ Value *SelectedV = CondC->isAllOnesValue()
+ ? TrueVal
+ : (CondC->isNullValue()) ? FalseVal : nullptr;
+ if (!SelectedV) {
+ // Condition is a vector constant that is not all 1s or all 0s. If all
+ // operands are constants, ConstantExpr::getSelect() can handle the cases
+ // such as select vectors.
+ if (TrueC && FalseC) {
+ if (auto *C = ConstantExpr::getSelect(CondC, TrueC, FalseC)) {
+ SimplifiedValues[&SI] = C;
+ return true;
+ }
+ }
+ return Base::visitSelectInst(SI);
+ }
+
+ // Condition is either all 1s or all 0s. SI can be simplified.
+ if (Constant *SelectedC = dyn_cast<Constant>(SelectedV)) {
+ SimplifiedValues[&SI] = SelectedC;
+ return true;
+ }
+
+ if (!CheckSROA)
+ return true;
+
+ std::pair<Value *, APInt> BaseAndOffset =
+ ConstantOffsetPtrs.lookup(SelectedV);
+ if (BaseAndOffset.first) {
+ ConstantOffsetPtrs[&SI] = BaseAndOffset;
+
+ Value *SROAArg;
+ DenseMap<Value *, int>::iterator CostIt;
+ if (lookupSROAArgAndCost(SelectedV, SROAArg, CostIt))
+ SROAArgValues[&SI] = SROAArg;
+ }
+
+ return true;
+}
+
bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
// We model unconditional switches as free, see the comments on handling
// branches.
OpenPOWER on IntegriCloud