27
27
#include " llvm/Analysis/ConstantFolding.h"
28
28
#include " llvm/Analysis/GlobalsModRef.h"
29
29
#include " llvm/Analysis/TargetLibraryInfo.h"
30
+ #include " llvm/Analysis/ValueLattice.h"
30
31
#include " llvm/IR/CallSite.h"
31
32
#include " llvm/IR/Constants.h"
32
33
#include " llvm/IR/DataLayout.h"
@@ -52,6 +53,8 @@ STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
52
53
STATISTIC (IPNumInstRemoved, " Number of instructions removed by IPSCCP" );
53
54
STATISTIC (IPNumArgsElimed ," Number of arguments constant propagated by IPSCCP" );
54
55
STATISTIC (IPNumGlobalConst, " Number of globals found to be constant by IPSCCP" );
56
+ STATISTIC (IPNumRangeInfoUsed, " Number of times constant range info was used by"
57
+ " IPSCCP" );
55
58
56
59
namespace {
57
60
// / LatticeVal class - This class represents the different lattice values that
@@ -153,6 +156,14 @@ class LatticeVal {
153
156
Val.setInt (forcedconstant);
154
157
Val.setPointer (V);
155
158
}
159
+
160
+ ValueLatticeElement toValueLattice () const {
161
+ if (isOverdefined ())
162
+ return ValueLatticeElement::getOverdefined ();
163
+ if (isConstant ())
164
+ return ValueLatticeElement::get (getConstant ());
165
+ return ValueLatticeElement ();
166
+ }
156
167
};
157
168
} // end anonymous namespace.
158
169
@@ -169,6 +180,8 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
169
180
const TargetLibraryInfo *TLI;
170
181
SmallPtrSet<BasicBlock*, 8 > BBExecutable; // The BBs that are executable.
171
182
DenseMap<Value*, LatticeVal> ValueState; // The state each value is in.
183
+ // The state each parameter is in.
184
+ DenseMap<Value *, ValueLatticeElement> ParamState;
172
185
173
186
// / StructValueState - This maintains ValueState for values that have
174
187
// / StructType, for example for formal arguments, calls, insertelement, etc.
@@ -290,10 +303,15 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
290
303
return StructValues;
291
304
}
292
305
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];
297
315
}
298
316
299
317
// / getTrackedRetVals - Get the inferred return value map.
@@ -426,6 +444,15 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
426
444
return LV;
427
445
}
428
446
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
+
429
456
// / getStructValueState - Return the LatticeVal object that corresponds to the
430
457
// / value/field pair. This function handles the case when the value hasn't
431
458
// / been seen yet by properly seeding constants etc.
@@ -1162,6 +1189,9 @@ void SCCPSolver::visitCallSite(CallSite CS) {
1162
1189
mergeInValue (getStructValueState (&*AI, i), &*AI, CallArg);
1163
1190
}
1164
1191
} 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);
1165
1195
mergeInValue (&*AI, getValueState (*CAI));
1166
1196
}
1167
1197
}
@@ -1557,6 +1587,46 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
1557
1587
return false ;
1558
1588
}
1559
1589
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 UI = V->uses ().begin (), E = V->uses ().end (); UI != E;) {
1604
+ // Advance the iterator here, as we might remove the current use.
1605
+ const Use &U = *UI++;
1606
+ auto *Icmp = dyn_cast<ICmpInst>(U.getUser ());
1607
+ if (!Icmp)
1608
+ continue ;
1609
+
1610
+ auto A = Solver.getLatticeValueFor (Icmp->getOperand (0 ));
1611
+ auto B = Solver.getLatticeValueFor (Icmp->getOperand (1 ));
1612
+ Constant *C = nullptr ;
1613
+ if (A.satisfiesPredicate (Icmp->getPredicate (), B))
1614
+ C = ConstantInt::getTrue (Icmp->getType ());
1615
+ else if (A.satisfiesPredicate (Icmp->getInversePredicate (), B))
1616
+ C = ConstantInt::getFalse (Icmp->getType ());
1617
+
1618
+ if (C) {
1619
+ Icmp->replaceAllUsesWith (C);
1620
+ DEBUG (dbgs () << " Replacing " << *Icmp << " with " << *C
1621
+ << " , because of range information " << A << " " << B
1622
+ << " \n " );
1623
+ Icmp->eraseFromParent ();
1624
+ Changed = true ;
1625
+ }
1626
+ }
1627
+ return Changed;
1628
+ }
1629
+
1560
1630
static bool tryToReplaceWithConstant (SCCPSolver &Solver, Value *V) {
1561
1631
Constant *Const = nullptr ;
1562
1632
if (V->getType ()->isStructTy ()) {
@@ -1573,10 +1643,19 @@ static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
1573
1643
}
1574
1644
Const = ConstantStruct::get (ST, ConstVals);
1575
1645
} else {
1576
- LatticeVal IV = Solver.getLatticeValueFor (V);
1646
+ const ValueLatticeElement & IV = Solver.getLatticeValueFor (V);
1577
1647
if (IV.isOverdefined ())
1578
1648
return false ;
1579
- Const = IV.isConstant () ? IV.getConstant () : UndefValue::get (V->getType ());
1649
+
1650
+ if (IV.isConstantRange ()) {
1651
+ if (IV.getConstantRange ().isSingleElement ())
1652
+ Const =
1653
+ ConstantInt::get (V->getType (), IV.asConstantInteger ().getValue ());
1654
+ else
1655
+ return false ;
1656
+ } else
1657
+ Const =
1658
+ IV.isConstant () ? IV.getConstant () : UndefValue::get (V->getType ());
1580
1659
}
1581
1660
assert (Const && " Constant is nullptr here!" );
1582
1661
DEBUG (dbgs () << " Constant: " << *Const << " = " << *V << ' \n ' );
@@ -1816,12 +1895,17 @@ static bool runIPSCCP(Module &M, const DataLayout &DL,
1816
1895
if (F.isDeclaration ())
1817
1896
continue ;
1818
1897
1819
- if (Solver.isBlockExecutable (&F.front ()))
1898
+ if (Solver.isBlockExecutable (&F.front ())) {
1820
1899
for (Function::arg_iterator AI = F.arg_begin (), E = F.arg_end (); AI != E;
1821
- ++AI)
1900
+ ++AI) {
1822
1901
if (!AI->use_empty () && tryToReplaceWithConstant (Solver, &*AI))
1823
1902
++IPNumArgsElimed;
1824
1903
1904
+ if (!AI->use_empty () && tryToReplaceWithConstantRange (Solver, &*AI))
1905
+ ++IPNumRangeInfoUsed;
1906
+ }
1907
+ }
1908
+
1825
1909
for (Function::iterator BB = F.begin (), E = F.end (); BB != E; ++BB) {
1826
1910
if (!Solver.isBlockExecutable (&*BB)) {
1827
1911
DEBUG (dbgs () << " BasicBlock Dead:" << *BB);
0 commit comments