30
30
#include " llvm/Analysis/ConstantFolding.h"
31
31
#include " llvm/Analysis/GlobalsModRef.h"
32
32
#include " llvm/Analysis/TargetLibraryInfo.h"
33
+ #include " llvm/Analysis/ValueLattice.h"
33
34
#include " llvm/Analysis/ValueLatticeUtils.h"
34
35
#include " llvm/IR/BasicBlock.h"
35
36
#include " llvm/IR/CallSite.h"
@@ -70,6 +71,8 @@ STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
70
71
STATISTIC (IPNumInstRemoved, " Number of instructions removed by IPSCCP" );
71
72
STATISTIC (IPNumArgsElimed ," Number of arguments constant propagated by IPSCCP" );
72
73
STATISTIC (IPNumGlobalConst, " Number of globals found to be constant by IPSCCP" );
74
+ STATISTIC (IPNumRangeInfoUsed, " Number of times constant range info was used by"
75
+ " IPSCCP" );
73
76
74
77
namespace {
75
78
@@ -174,6 +177,14 @@ class LatticeVal {
174
177
Val.setInt (forcedconstant);
175
178
Val.setPointer (V);
176
179
}
180
+
181
+ ValueLatticeElement toValueLattice () const {
182
+ if (isOverdefined ())
183
+ return ValueLatticeElement::getOverdefined ();
184
+ if (isConstant ())
185
+ return ValueLatticeElement::get (getConstant ());
186
+ return ValueLatticeElement ();
187
+ }
177
188
};
178
189
179
190
// ===----------------------------------------------------------------------===//
@@ -186,6 +197,8 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
186
197
const TargetLibraryInfo *TLI;
187
198
SmallPtrSet<BasicBlock *, 8 > BBExecutable; // The BBs that are executable.
188
199
DenseMap<Value *, LatticeVal> ValueState; // The state each value is in.
200
+ // The state each parameter is in.
201
+ DenseMap<Value *, ValueLatticeElement> ParamState;
189
202
190
203
// / StructValueState - This maintains ValueState for values that have
191
204
// / StructType, for example for formal arguments, calls, insertelement, etc.
@@ -312,10 +325,20 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
312
325
return StructValues;
313
326
}
314
327
315
- LatticeVal getLatticeValueFor (Value *V) const {
316
- DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find (V);
317
- assert (I != ValueState.end () && " V is not in valuemap!" );
318
- return I->second ;
328
+ ValueLatticeElement getLatticeValueFor (Value *V) {
329
+ assert (!V->getType ()->isStructTy () &&
330
+ " Should use getStructLatticeValueFor" );
331
+ std::pair<DenseMap<Value*, ValueLatticeElement>::iterator, bool >
332
+ PI = ParamState.insert (std::make_pair (V, ValueLatticeElement ()));
333
+ ValueLatticeElement &LV = PI.first ->second ;
334
+ if (PI.second ) {
335
+ DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find (V);
336
+ assert (I != ValueState.end () &&
337
+ " V not found in ValueState nor Paramstate map!" );
338
+ LV = I->second .toValueLattice ();
339
+ }
340
+
341
+ return LV;
319
342
}
320
343
321
344
// / getTrackedRetVals - Get the inferred return value map.
@@ -444,6 +467,18 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
444
467
return LV;
445
468
}
446
469
470
+ ValueLatticeElement &getParamState (Value *V) {
471
+ assert (!V->getType ()->isStructTy () && " Should use getStructValueState" );
472
+
473
+ std::pair<DenseMap<Value*, ValueLatticeElement>::iterator, bool >
474
+ PI = ParamState.insert (std::make_pair (V, ValueLatticeElement ()));
475
+ ValueLatticeElement &LV = PI.first ->second ;
476
+ if (PI.second )
477
+ LV = getValueState (V).toValueLattice ();
478
+
479
+ return LV;
480
+ }
481
+
447
482
// / getStructValueState - Return the LatticeVal object that corresponds to the
448
483
// / value/field pair. This function handles the case when the value hasn't
449
484
// / been seen yet by properly seeding constants etc.
@@ -1170,6 +1205,9 @@ void SCCPSolver::visitCallSite(CallSite CS) {
1170
1205
mergeInValue (getStructValueState (&*AI, i), &*AI, CallArg);
1171
1206
}
1172
1207
} else {
1208
+ // Most other parts of the Solver still only use the simpler value
1209
+ // lattice, so we propagate changes for parameters to both lattices.
1210
+ getParamState (&*AI).mergeIn (getValueState (*CAI).toValueLattice (), DL);
1173
1211
mergeInValue (&*AI, getValueState (*CAI));
1174
1212
}
1175
1213
}
@@ -1560,6 +1598,43 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
1560
1598
return false ;
1561
1599
}
1562
1600
1601
+ static bool tryToReplaceWithConstantRange (SCCPSolver &Solver, Value *V) {
1602
+ bool Changed = false ;
1603
+
1604
+ // Currently we only use range information for integer values.
1605
+ if (!V->getType ()->isIntegerTy ())
1606
+ return false ;
1607
+
1608
+ const ValueLatticeElement &IV = Solver.getLatticeValueFor (V);
1609
+ if (!IV.isConstantRange ())
1610
+ return false ;
1611
+
1612
+ for (auto UI = V->uses ().begin (), E = V->uses ().end (); UI != E;) {
1613
+ const Use &U = *UI++;
1614
+ auto *Icmp = dyn_cast<ICmpInst>(U.getUser ());
1615
+ if (!Icmp || !Solver.isBlockExecutable (Icmp->getParent ()))
1616
+ continue ;
1617
+
1618
+ auto A = Solver.getLatticeValueFor (Icmp->getOperand (0 ));
1619
+ auto B = Solver.getLatticeValueFor (Icmp->getOperand (1 ));
1620
+ Constant *C = nullptr ;
1621
+ if (A.satisfiesPredicate (Icmp->getPredicate (), B))
1622
+ C = ConstantInt::getTrue (Icmp->getType ());
1623
+ else if (A.satisfiesPredicate (Icmp->getInversePredicate (), B))
1624
+ C = ConstantInt::getFalse (Icmp->getType ());
1625
+
1626
+ if (C) {
1627
+ Icmp->replaceAllUsesWith (C);
1628
+ DEBUG (dbgs () << " Replacing " << *Icmp << " with " << *C
1629
+ << " , because of range information " << A << " " << B
1630
+ << " \n " );
1631
+ Icmp->eraseFromParent ();
1632
+ Changed = true ;
1633
+ }
1634
+ }
1635
+ return Changed;
1636
+ }
1637
+
1563
1638
static bool tryToReplaceWithConstant (SCCPSolver &Solver, Value *V) {
1564
1639
Constant *Const = nullptr ;
1565
1640
if (V->getType ()->isStructTy ()) {
@@ -1577,10 +1652,19 @@ static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
1577
1652
}
1578
1653
Const = ConstantStruct::get (ST, ConstVals);
1579
1654
} else {
1580
- LatticeVal IV = Solver.getLatticeValueFor (V);
1655
+ const ValueLatticeElement & IV = Solver.getLatticeValueFor (V);
1581
1656
if (IV.isOverdefined ())
1582
1657
return false ;
1583
- Const = IV.isConstant () ? IV.getConstant () : UndefValue::get (V->getType ());
1658
+
1659
+ if (IV.isConstantRange ()) {
1660
+ if (IV.getConstantRange ().isSingleElement ())
1661
+ Const =
1662
+ ConstantInt::get (V->getType (), IV.asConstantInteger ().getValue ());
1663
+ else
1664
+ return false ;
1665
+ } else
1666
+ Const =
1667
+ IV.isConstant () ? IV.getConstant () : UndefValue::get (V->getType ());
1584
1668
}
1585
1669
assert (Const && " Constant is nullptr here!" );
1586
1670
DEBUG (dbgs () << " Constant: " << *Const << " = " << *V << ' \n ' );
@@ -1781,10 +1865,14 @@ static bool runIPSCCP(Module &M, const DataLayout &DL,
1781
1865
1782
1866
if (Solver.isBlockExecutable (&F.front ()))
1783
1867
for (Function::arg_iterator AI = F.arg_begin (), E = F.arg_end (); AI != E;
1784
- ++AI)
1868
+ ++AI) {
1785
1869
if (!AI->use_empty () && tryToReplaceWithConstant (Solver, &*AI))
1786
1870
++IPNumArgsElimed;
1787
1871
1872
+ if (!AI->use_empty () && tryToReplaceWithConstantRange (Solver, &*AI))
1873
+ ++IPNumRangeInfoUsed;
1874
+ }
1875
+
1788
1876
for (Function::iterator BB = F.begin (), E = F.end (); BB != E; ++BB) {
1789
1877
if (!Solver.isBlockExecutable (&*BB)) {
1790
1878
DEBUG (dbgs () << " BasicBlock Dead:" << *BB);
0 commit comments