Index: lib/Analysis/LazyValueInfo.cpp =================================================================== --- lib/Analysis/LazyValueInfo.cpp +++ lib/Analysis/LazyValueInfo.cpp @@ -60,6 +60,12 @@ /// FIXME: This is basically just for bringup, this can be made a lot more rich /// in the future. /// +/// FIXME: +// - constant and constantrange could be unified. A constant is only +/// a special case of a constant range. +/// - notconstant seems to be a special case of a range, too. +/// Is seems to be used with "null" comparisons only. + namespace { class LVILatticeVal { enum LatticeValueTy { @@ -198,9 +204,15 @@ /// Merge the specified lattice value into this one, updating this /// one and returning true if anything changed. bool mergeIn(const LVILatticeVal &RHS, const DataLayout &DL) { + // FIXME: In a const range prop dfa solver + // undefined would be top and overdefined bottom. So in this + // case the function should return bottom in the case of isOverdefined, too. + // If both are undefined there should be no change. if (RHS.isUndefined() || isOverdefined()) return false; if (RHS.isOverdefined()) return markOverdefined(); + // Note: undefined acts like a top element in a const value range prop + // lattice here. if (isUndefined()) { Tag = RHS.Tag; Val = RHS.Val; @@ -208,6 +220,7 @@ return true; } + // Note: overdefined acts like a bottom element here. if (isConstant()) { if (RHS.isConstant()) { if (Val == RHS.Val) @@ -215,6 +228,7 @@ return markOverdefined(); } + // Note: dito. if (RHS.isNotConstant()) { if (Val == RHS.Val) return markOverdefined(); @@ -239,6 +253,8 @@ } if (isNotConstant()) { + // FIXME: how can isNotConstant.Val be equal to a constant??? + // Example? if (RHS.isConstant()) { if (Val == RHS.Val) return markOverdefined(); @@ -748,6 +764,29 @@ } } + // FIXME: this is to solve a compile-time problem. + // In a test case with thousands of alloca's and + // indiect calls the solver pushed the allocas as undefined + // on the stack and tries to "solve" them. This seems to + // triggered that the value range problem in the current algorithm + // is not solved as a forward problem with well defined top, bottom, meet + // etc. Instead it may walk the CFG spontaneously in any direction and push + // values on the block stack while it tries to determine the lattice values + // of the values on the stack. This is illustrated in the current routine: + // solve -> solveBlockValue -> solveBlockValueNonLocal, which (see below) + // may call getEdgeValue, which in turn could push more values on the stack + // This code fixes the test cases with the alloca's reducing compile-time + // for that ~150K line funciton from "inifinite" to a couple of minutes. + // The rational is that "not null" is the best we can do for a stackaddress. + + if (isa(Val)) { + assert(NotNull && "Stackaddress cannot be zero\n"); + PointerType *PTy = cast(Val->getType()); + Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); + BBLV = Result; + return true; + } + // If this is the entry block, we must be asking about an argument. The // value is overdefined. if (BB == &BB->getParent()->getEntryBlock()) { @@ -768,6 +807,13 @@ for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { LVILatticeVal EdgeResult; EdgesMissing |= !getEdgeValue(Val, *PI, BB, EdgeResult); + // FIXME; When EdgesMissing is set, it is never reset and this funciton + // will return false. Should it be: + // bool EdgeMissing; + // EdgeMissing = !getEdgeValue( ..); + // EdgesMissing |= EdgeMissing; + // if (EdgeMissing) continue???? + if (EdgesMissing) continue; @@ -812,6 +858,13 @@ // Note that we can provide PN as the context value to getEdgeValue, even // though the results will be cached, because PN is the value being used as // the cache key in the caller. + // FIXME; Same as above: When EdgesMissing is set, it is never reset and + // this funciton + // will return false. Should it be: + // bool EdgeMissing; + // EdgeMissing = !getEdgeValue( ..); + // EdgesMissing |= EdgeMissing; + // if (EdgeMissing) continue???? EdgesMissing |= !getEdgeValue(PhiVal, PhiBB, BB, EdgeResult, PN); if (EdgesMissing) continue; @@ -870,6 +923,11 @@ SelectInst *SI, BasicBlock *BB) { // Recurse on our inputs if needed + // FIXME: look at all instances on hasBlockValue. All but one have this + // pattern: + // if (!hasBlockValue(...)) if (push...(..)) return false; BBLV...; return + // true; + // Why no all??? if (!hasBlockValue(SI->getTrueValue(), BB)) { if (pushBlockValue(std::make_pair(BB, SI->getTrueValue()))) return false; @@ -1230,6 +1288,9 @@ << BB->getName() << "'\n"); assert(BlockValueStack.empty() && BlockValueSet.empty()); + // FIXME: so this is the unusual pattern with hasBlockValue(). See + // the FIXME at one of the other instances. Why is solve() invoked + // only here??? if (!hasBlockValue(V, BB)) { pushBlockValue(std::make_pair(BB, V)); solve();