diff options
| author | Davide Italiano <davide@freebsd.org> | 2016-07-12 19:54:19 +0000 |
|---|---|---|
| committer | Davide Italiano <davide@freebsd.org> | 2016-07-12 19:54:19 +0000 |
| commit | 00802693424f3b3150edfa41b3a3d64744afe44d (patch) | |
| tree | 5497ea0ce8fdfa87bbfd7e3e1d7deeb728cf391b /llvm/lib | |
| parent | e318b8374522af8d5a8102564b21cbd01f8bde9f (diff) | |
| download | bcm5719-llvm-00802693424f3b3150edfa41b3a3d64744afe44d.tar.gz bcm5719-llvm-00802693424f3b3150edfa41b3a3d64744afe44d.zip | |
[SCCP] Constant fold structs if all the lattice value are constant.
Differential Revision: http://reviews.llvm.org/D22269
llvm-svn: 275208
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index f93f4ee517a..a8667eb4256 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -270,6 +270,18 @@ public: return BBExecutable.count(BB); } + std::vector<LatticeVal> getStructLatticeValueFor(Value *V) const { + std::vector<LatticeVal> StructValues; + StructType *STy = dyn_cast<StructType>(V->getType()); + assert(STy && "getStructLatticeValueFor() can be called only on structs"); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + auto I = StructValueState.find(std::make_pair(V, i)); + assert(I != StructValueState.end() && "Value not in valuemap!"); + StructValues.push_back(I->second); + } + return StructValues; + } + LatticeVal getLatticeValueFor(Value *V) const { DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V); assert(I != ValueState.end() && "V is not in valuemap!"); @@ -1545,16 +1557,30 @@ static bool runSCCP(Function &F, const DataLayout &DL, if (Inst->getType()->isVoidTy() || isa<TerminatorInst>(Inst)) continue; - // TODO: Reconstruct structs from their elements. - if (Inst->getType()->isStructTy()) - continue; - - LatticeVal IV = Solver.getLatticeValueFor(Inst); - if (IV.isOverdefined()) - continue; + Constant *Const = nullptr; + if (Inst->getType()->isStructTy()) { + std::vector<LatticeVal> IVs = Solver.getStructLatticeValueFor(Inst); + if (std::any_of(IVs.begin(), IVs.end(), + [](LatticeVal &LV) { return LV.isOverdefined(); })) + continue; + std::vector<Constant *> ConstVals; + StructType *ST = dyn_cast<StructType>(Inst->getType()); + for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) { + LatticeVal V = IVs[i]; + ConstVals.push_back(V.isConstant() + ? V.getConstant() + : UndefValue::get(ST->getElementType(i))); + } + Const = ConstantStruct::get(ST, ConstVals); + } else { + LatticeVal IV = Solver.getLatticeValueFor(Inst); + if (IV.isOverdefined()) + continue; - Constant *Const = IV.isConstant() - ? IV.getConstant() : UndefValue::get(Inst->getType()); + Const = IV.isConstant() ? IV.getConstant() + : UndefValue::get(Inst->getType()); + } + assert(Const && "Constant is nullptr here!"); DEBUG(dbgs() << " Constant: " << *Const << " = " << *Inst << '\n'); // Replaces all of the uses of a variable with uses of the constant. |

