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/Transforms | |
| 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/Transforms')
| -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. | 

