2727#include " llvm/Analysis/ConstantFolding.h"
2828#include " llvm/Analysis/GlobalsModRef.h"
2929#include " llvm/Analysis/TargetLibraryInfo.h"
30+ #include " llvm/Analysis/ValueLattice.h"
3031#include " llvm/IR/CallSite.h"
3132#include " llvm/IR/Constants.h"
3233#include " llvm/IR/DataLayout.h"
@@ -52,6 +53,8 @@ STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
5253STATISTIC (IPNumInstRemoved, " Number of instructions removed by IPSCCP" );
5354STATISTIC (IPNumArgsElimed ," Number of arguments constant propagated by IPSCCP" );
5455STATISTIC (IPNumGlobalConst, " Number of globals found to be constant by IPSCCP" );
56+ STATISTIC (IPNumRangeInfoUsed, " Number of times constant range info was used by"
57+ " IPSCCP" );
5558
5659namespace {
5760// / LatticeVal class - This class represents the different lattice values that
@@ -153,6 +156,14 @@ class LatticeVal {
153156 Val.setInt (forcedconstant);
154157 Val.setPointer (V);
155158 }
159+
160+ ValueLatticeElement toValueLattice () const {
161+ if (isOverdefined ())
162+ return ValueLatticeElement::getOverdefined ();
163+ if (isConstant ())
164+ return ValueLatticeElement::get (getConstant ());
165+ return ValueLatticeElement ();
166+ }
156167};
157168} // end anonymous namespace.
158169
@@ -169,6 +180,8 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
169180 const TargetLibraryInfo *TLI;
170181 SmallPtrSet<BasicBlock*, 8 > BBExecutable; // The BBs that are executable.
171182 DenseMap<Value*, LatticeVal> ValueState; // The state each value is in.
183+ // The state each parameter is in.
184+ DenseMap<Value *, ValueLatticeElement> ParamState;
172185
173186 // / StructValueState - This maintains ValueState for values that have
174187 // / StructType, for example for formal arguments, calls, insertelement, etc.
@@ -290,10 +303,15 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
290303 return StructValues;
291304 }
292305
293- LatticeVal getLatticeValueFor (Value *V) const {
294- DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find (V);
295- assert (I != ValueState.end () && " V is not in valuemap!" );
296- return I->second ;
306+ ValueLatticeElement getLatticeValueFor (Value *V) {
307+ if (ParamState.count (V) == 0 ) {
308+ DenseMap<Value *, LatticeVal>::const_iterator I = ValueState.find (V);
309+ assert (I != ValueState.end () &&
310+ " V not found in ValueState nor Paramstate map!" );
311+ ParamState[V] = I->second .toValueLattice ();
312+ }
313+
314+ return ParamState[V];
297315 }
298316
299317 // / getTrackedRetVals - Get the inferred return value map.
@@ -426,6 +444,15 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
426444 return LV;
427445 }
428446
447+ ValueLatticeElement &getParamState (Value *V) {
448+ assert (!V->getType ()->isStructTy () && " Should use getStructValueState" );
449+
450+ if (ParamState.count (V) == 0 )
451+ ParamState[V] = getValueState (V).toValueLattice ();
452+
453+ return ParamState[V];
454+ }
455+
429456 // / getStructValueState - Return the LatticeVal object that corresponds to the
430457 // / value/field pair. This function handles the case when the value hasn't
431458 // / been seen yet by properly seeding constants etc.
@@ -1162,6 +1189,9 @@ void SCCPSolver::visitCallSite(CallSite CS) {
11621189 mergeInValue (getStructValueState (&*AI, i), &*AI, CallArg);
11631190 }
11641191 } else {
1192+ // Most other parts of the Solver still only use the simpler value
1193+ // lattice, so we propagate changes for parameters to both lattices.
1194+ getParamState (&*AI).mergeIn (getValueState (*CAI).toValueLattice (), DL);
11651195 mergeInValue (&*AI, getValueState (*CAI));
11661196 }
11671197 }
@@ -1557,6 +1587,44 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
15571587 return false ;
15581588}
15591589
1590+ static bool tryToReplaceWithConstantRange (SCCPSolver &Solver, Value *V) {
1591+ bool Changed = false ;
1592+ if (!V->getType ()->isIntegerTy ())
1593+ return false ;
1594+
1595+ const ValueLatticeElement &IV = Solver.getLatticeValueFor (V);
1596+ if (IV.isOverdefined ())
1597+ return false ;
1598+
1599+ // Currently we only use range information for integer values.
1600+ if (!(V->getType ()->isIntegerTy () && IV.isConstantRange ()))
1601+ return false ;
1602+
1603+ for (auto &Use : V->uses ()) {
1604+ auto *Icmp = dyn_cast<ICmpInst>(Use.getUser ());
1605+ if (!Icmp)
1606+ continue ;
1607+
1608+ auto A = Solver.getLatticeValueFor (Icmp->getOperand (0 ));
1609+ auto B = Solver.getLatticeValueFor (Icmp->getOperand (1 ));
1610+ Constant *C = nullptr ;
1611+ if (A.satisfiesPredicate (Icmp->getPredicate (), B))
1612+ C = ConstantInt::getTrue (Icmp->getType ());
1613+ else if (A.satisfiesPredicate (Icmp->getInversePredicate (), B))
1614+ C = ConstantInt::getFalse (Icmp->getType ());
1615+
1616+ if (C) {
1617+ Icmp->replaceAllUsesWith (C);
1618+ DEBUG (dbgs () << " Replacing " << *Icmp << " with " << *C
1619+ << " , because of range information " << A << " " << B
1620+ << " \n " );
1621+ Icmp->eraseFromParent ();
1622+ Changed = true ;
1623+ }
1624+ }
1625+ return Changed;
1626+ }
1627+
15601628static bool tryToReplaceWithConstant (SCCPSolver &Solver, Value *V) {
15611629 Constant *Const = nullptr ;
15621630 if (V->getType ()->isStructTy ()) {
@@ -1573,10 +1641,19 @@ static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
15731641 }
15741642 Const = ConstantStruct::get (ST, ConstVals);
15751643 } else {
1576- LatticeVal IV = Solver.getLatticeValueFor (V);
1644+ const ValueLatticeElement & IV = Solver.getLatticeValueFor (V);
15771645 if (IV.isOverdefined ())
15781646 return false ;
1579- Const = IV.isConstant () ? IV.getConstant () : UndefValue::get (V->getType ());
1647+
1648+ if (IV.isConstantRange ()) {
1649+ if (IV.getConstantRange ().isSingleElement ())
1650+ Const =
1651+ ConstantInt::get (V->getType (), IV.asConstantInteger ().getValue ());
1652+ else
1653+ return false ;
1654+ } else
1655+ Const =
1656+ IV.isConstant () ? IV.getConstant () : UndefValue::get (V->getType ());
15801657 }
15811658 assert (Const && " Constant is nullptr here!" );
15821659 DEBUG (dbgs () << " Constant: " << *Const << " = " << *V << ' \n ' );
@@ -1816,12 +1893,17 @@ static bool runIPSCCP(Module &M, const DataLayout &DL,
18161893 if (F.isDeclaration ())
18171894 continue ;
18181895
1819- if (Solver.isBlockExecutable (&F.front ()))
1896+ if (Solver.isBlockExecutable (&F.front ())) {
18201897 for (Function::arg_iterator AI = F.arg_begin (), E = F.arg_end (); AI != E;
1821- ++AI)
1898+ ++AI) {
18221899 if (!AI->use_empty () && tryToReplaceWithConstant (Solver, &*AI))
18231900 ++IPNumArgsElimed;
18241901
1902+ if (!AI->use_empty () && tryToReplaceWithConstantRange (Solver, &*AI))
1903+ ++IPNumRangeInfoUsed;
1904+ }
1905+ }
1906+
18251907 for (Function::iterator BB = F.begin (), E = F.end (); BB != E; ++BB) {
18261908 if (!Solver.isBlockExecutable (&*BB)) {
18271909 DEBUG (dbgs () << " BasicBlock Dead:" << *BB);
0 commit comments