210 changes: 94 additions & 116 deletions llvm/lib/Transforms/Scalar/SCCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,20 @@ STATISTIC(IPNumGlobalConst, "Number of globals found to be constant by IPSCCP");

namespace {

// Use ValueLatticeElement as LatticeVal.
using LatticeVal = ValueLatticeElement;

// Helper to check if \p LV is either a constant or a constant
// range with a single element. This should cover exactly the same cases as the
// old LatticeVal::isConstant() and is intended to be used in the transition
// from LatticeVal to LatticeValueElement.
bool isConstant(const LatticeVal &LV) {
// old ValueLatticeElement::isConstant() and is intended to be used in the
// transition to ValueLatticeElement.
bool isConstant(const ValueLatticeElement &LV) {
return LV.isConstant() ||
(LV.isConstantRange() && LV.getConstantRange().isSingleElement());
}

// Helper to check if \p LV is either overdefined or a constant range with more
// than a single element. This should cover exactly the same cases as the old
// LatticeVal::isOverdefined() and is intended to be used in the transition from
// LatticeVal to LatticeValueElement.
bool isOverdefined(const LatticeVal &LV) {
// ValueLatticeElement::isOverdefined() and is intended to be used in the
// transition to ValueLatticeElement.
bool isOverdefined(const ValueLatticeElement &LV) {
return LV.isOverdefined() ||
(LV.isConstantRange() && !LV.getConstantRange().isSingleElement());
}
Expand All @@ -104,26 +101,28 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
const DataLayout &DL;
std::function<const TargetLibraryInfo &(Function &)> GetTLI;
SmallPtrSet<BasicBlock *, 8> BBExecutable; // The BBs that are executable.
DenseMap<Value *, LatticeVal> ValueState; // The state each value is in.
DenseMap<Value *, ValueLatticeElement>
ValueState; // The state each value is in.

/// StructValueState - This maintains ValueState for values that have
/// StructType, for example for formal arguments, calls, insertelement, etc.
DenseMap<std::pair<Value *, unsigned>, LatticeVal> StructValueState;
DenseMap<std::pair<Value *, unsigned>, ValueLatticeElement> StructValueState;

/// GlobalValue - If we are tracking any values for the contents of a global
/// variable, we keep a mapping from the constant accessor to the element of
/// the global, to the currently known value. If the value becomes
/// overdefined, it's entry is simply removed from this map.
DenseMap<GlobalVariable *, LatticeVal> TrackedGlobals;
DenseMap<GlobalVariable *, ValueLatticeElement> TrackedGlobals;

/// TrackedRetVals - If we are tracking arguments into and the return
/// value out of a function, it will have an entry in this map, indicating
/// what the known return value for the function is.
MapVector<Function *, LatticeVal> TrackedRetVals;
MapVector<Function *, ValueLatticeElement> TrackedRetVals;

/// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions
/// that return multiple values.
MapVector<std::pair<Function *, unsigned>, LatticeVal> TrackedMultipleRetVals;
MapVector<std::pair<Function *, unsigned>, ValueLatticeElement>
TrackedMultipleRetVals;

/// MRVFunctionsTracked - Each function in TrackedMultipleRetVals is
/// represented here for efficient lookup.
Expand Down Expand Up @@ -203,7 +202,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
void TrackValueOfGlobalVariable(GlobalVariable *GV) {
// We only track the contents of scalar globals.
if (GV->getValueType()->isSingleValueType()) {
LatticeVal &IV = TrackedGlobals[GV];
ValueLatticeElement &IV = TrackedGlobals[GV];
if (!isa<UndefValue>(GV->getInitializer()))
IV.markConstant(GV->getInitializer());
}
Expand All @@ -217,10 +216,10 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
MRVFunctionsTracked.insert(F);
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
TrackedMultipleRetVals.insert(std::make_pair(std::make_pair(F, i),
LatticeVal()));
TrackedMultipleRetVals.insert(
std::make_pair(std::make_pair(F, i), ValueLatticeElement()));
} else
TrackedRetVals.insert(std::make_pair(F, LatticeVal()));
TrackedRetVals.insert(std::make_pair(F, ValueLatticeElement()));
}

/// AddMustTailCallee - If the SCCP solver finds that this function is called
Expand Down Expand Up @@ -263,8 +262,8 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
// block to the 'To' basic block is currently feasible.
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To);

std::vector<LatticeVal> getStructLatticeValueFor(Value *V) const {
std::vector<LatticeVal> StructValues;
std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const {
std::vector<ValueLatticeElement> StructValues;
auto *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) {
Expand All @@ -275,23 +274,24 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
return StructValues;
}

const LatticeVal &getLatticeValueFor(Value *V) const {
const ValueLatticeElement &getLatticeValueFor(Value *V) const {
assert(!V->getType()->isStructTy() &&
"Should use getStructLatticeValueFor");
DenseMap<Value *, LatticeVal>::const_iterator I = ValueState.find(V);
DenseMap<Value *, ValueLatticeElement>::const_iterator I =
ValueState.find(V);
assert(I != ValueState.end() &&
"V not found in ValueState nor Paramstate map!");
return I->second;
}

/// getTrackedRetVals - Get the inferred return value map.
const MapVector<Function*, LatticeVal> &getTrackedRetVals() {
const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals() {
return TrackedRetVals;
}

/// getTrackedGlobals - Get and return the set of inferred initializers for
/// global variables.
const DenseMap<GlobalVariable*, LatticeVal> &getTrackedGlobals() {
const DenseMap<GlobalVariable *, ValueLatticeElement> &getTrackedGlobals() {
return TrackedGlobals;
}

Expand Down Expand Up @@ -324,7 +324,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i));
assert(It != TrackedMultipleRetVals.end());
LatticeVal LV = It->second;
ValueLatticeElement LV = It->second;
if (!isConstant(LV))
return false;
}
Expand All @@ -333,7 +333,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {

/// Helper to return a Constant if \p LV is either a constant or a constant
/// range with a single element.
Constant *getConstant(const LatticeVal &LV) const {
Constant *getConstant(const ValueLatticeElement &LV) const {
if (LV.isConstant())
return LV.getConstant();

Expand All @@ -346,20 +346,20 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
}

private:
ConstantInt *getConstantInt(const LatticeVal &IV) const {
ConstantInt *getConstantInt(const ValueLatticeElement &IV) const {
return dyn_cast_or_null<ConstantInt>(getConstant(IV));
}

// pushToWorkList - Helper for markConstant/markOverdefined
void pushToWorkList(LatticeVal &IV, Value *V) {
void pushToWorkList(ValueLatticeElement &IV, Value *V) {
if (IV.isOverdefined())
return OverdefinedInstWorkList.push_back(V);
InstWorkList.push_back(V);
}

// Helper to push \p V to the worklist, after updating it to \p IV. Also
// prints a debug message with the updated value.
void pushToWorkListMsg(LatticeVal &IV, Value *V) {
void pushToWorkListMsg(ValueLatticeElement &IV, Value *V) {
LLVM_DEBUG(dbgs() << "updated " << IV << ": " << *V << '\n');
if (IV.isOverdefined())
return OverdefinedInstWorkList.push_back(V);
Expand All @@ -369,7 +369,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
// markConstant - Make a value be marked as "constant". If the value
// is not already a constant, add it to the instruction work list so that
// the users of the instruction are updated later.
bool markConstant(LatticeVal &IV, Value *V, Constant *C) {
bool markConstant(ValueLatticeElement &IV, Value *V, Constant *C) {
if (!IV.markConstant(C)) return false;
LLVM_DEBUG(dbgs() << "markConstant: " << *C << ": " << *V << '\n');
pushToWorkList(IV, V);
Expand All @@ -384,7 +384,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
// markOverdefined - Make a value be marked as "overdefined". If the
// value is not already overdefined, add it to the overdefined instruction
// work list so that the users of the instruction are updated later.
bool markOverdefined(LatticeVal &IV, Value *V) {
bool markOverdefined(ValueLatticeElement &IV, Value *V) {
if (!IV.markOverdefined()) return false;

LLVM_DEBUG(dbgs() << "markOverdefined: ";
Expand All @@ -396,8 +396,8 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
return true;
}

bool mergeInValue(LatticeVal &IV, Value *V, LatticeVal MergeWithV,
bool Widen = true) {
bool mergeInValue(ValueLatticeElement &IV, Value *V,
ValueLatticeElement MergeWithV, bool Widen = true) {
// Do a simple form of widening, to avoid extending a range repeatedly in a
// loop. If IV is a constant range, it means we already set it once. If
// MergeWithV would extend IV, mark V as overdefined.
Expand All @@ -415,21 +415,21 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
return false;
}

bool mergeInValue(Value *V, LatticeVal MergeWithV, bool Widen = true) {
bool mergeInValue(Value *V, ValueLatticeElement MergeWithV,
bool Widen = true) {
assert(!V->getType()->isStructTy() &&
"non-structs should use markConstant");
return mergeInValue(ValueState[V], V, MergeWithV, Widen);
}

/// getValueState - Return the LatticeVal object that corresponds to the
/// value. This function handles the case when the value hasn't been seen yet
/// by properly seeding constants etc.
LatticeVal &getValueState(Value *V) {
/// getValueState - Return the ValueLatticeElement object that corresponds to
/// the value. This function handles the case when the value hasn't been seen
/// yet by properly seeding constants etc.
ValueLatticeElement &getValueState(Value *V) {
assert(!V->getType()->isStructTy() && "Should use getStructValueState");

std::pair<DenseMap<Value*, LatticeVal>::iterator, bool> I =
ValueState.insert(std::make_pair(V, LatticeVal()));
LatticeVal &LV = I.first->second;
auto I = ValueState.insert(std::make_pair(V, ValueLatticeElement()));
ValueLatticeElement &LV = I.first->second;

if (!I.second)
return LV; // Common case, already in the map.
Expand All @@ -441,36 +441,17 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
return LV;
}

LatticeVal toLatticeVal(const ValueLatticeElement &V, Type *T) {
LatticeVal Res;
if (V.isUnknownOrUndef())
return Res;

if (V.isConstant()) {
Res.markConstant(V.getConstant());
return Res;
}
if (V.isConstantRange() && V.getConstantRange().isSingleElement()) {
Res.markConstant(
ConstantInt::get(T, *V.getConstantRange().getSingleElement()));
return Res;
}
Res.markOverdefined();
return Res;
}

/// getStructValueState - Return the LatticeVal object that corresponds to the
/// value/field pair. This function handles the case when the value hasn't
/// been seen yet by properly seeding constants etc.
LatticeVal &getStructValueState(Value *V, unsigned i) {
/// getStructValueState - Return the ValueLatticeElement object that
/// corresponds to the value/field pair. This function handles the case when
/// the value hasn't been seen yet by properly seeding constants etc.
ValueLatticeElement &getStructValueState(Value *V, unsigned i) {
assert(V->getType()->isStructTy() && "Should use getValueState");
assert(i < cast<StructType>(V->getType())->getNumElements() &&
"Invalid element #");

std::pair<DenseMap<std::pair<Value*, unsigned>, LatticeVal>::iterator,
bool> I = StructValueState.insert(
std::make_pair(std::make_pair(V, i), LatticeVal()));
LatticeVal &LV = I.first->second;
auto I = StructValueState.insert(
std::make_pair(std::make_pair(V, i), ValueLatticeElement()));
ValueLatticeElement &LV = I.first->second;

if (!I.second)
return LV; // Common case, already in the map.
Expand Down Expand Up @@ -627,7 +608,7 @@ void SCCPSolver::getFeasibleSuccessors(Instruction &TI,
return;
}

LatticeVal BCValue = getValueState(BI->getCondition());
ValueLatticeElement BCValue = getValueState(BI->getCondition());
ConstantInt *CI = getConstantInt(BCValue);
if (!CI) {
// Overdefined condition variables, and branches on unfoldable constant
Expand All @@ -653,7 +634,7 @@ void SCCPSolver::getFeasibleSuccessors(Instruction &TI,
Succs[0] = true;
return;
}
LatticeVal SCValue = getValueState(SI->getCondition());
ValueLatticeElement SCValue = getValueState(SI->getCondition());
ConstantInt *CI = getConstantInt(SCValue);

if (!CI) { // Overdefined or unknown condition?
Expand All @@ -671,7 +652,7 @@ void SCCPSolver::getFeasibleSuccessors(Instruction &TI,
// the target as executable.
if (auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
// Casts are folded by visitCastInst.
LatticeVal IBRValue = getValueState(IBR->getAddress());
ValueLatticeElement IBRValue = getValueState(IBR->getAddress());
BlockAddress *Addr = dyn_cast_or_null<BlockAddress>(getConstant(IBRValue));
if (!Addr) { // Overdefined or unknown condition?
// All destinations are executable!
Expand Down Expand Up @@ -754,11 +735,11 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
// If there are no executable operands, the PHI remains unknown.
bool Changed = false;
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
LatticeVal IV = getValueState(PN.getIncomingValue(i));
ValueLatticeElement IV = getValueState(PN.getIncomingValue(i));
if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent()))
continue;

LatticeVal &Res = getValueState(&PN);
ValueLatticeElement &Res = getValueState(&PN);
Changed |= Res.mergeIn(IV, DL);
if (Res.isOverdefined())
break;
Expand All @@ -780,8 +761,7 @@ void SCCPSolver::visitReturnInst(ReturnInst &I) {

// If we are tracking the return value of this function, merge it in.
if (!TrackedRetVals.empty() && !ResultOp->getType()->isStructTy()) {
MapVector<Function*, LatticeVal>::iterator TFRVI =
TrackedRetVals.find(F);
auto TFRVI = TrackedRetVals.find(F);
if (TFRVI != TrackedRetVals.end()) {
mergeInValue(TFRVI->second, F, getValueState(ResultOp));
return;
Expand Down Expand Up @@ -816,7 +796,7 @@ void SCCPSolver::visitCastInst(CastInst &I) {
if (isOverdefined(ValueState[&I]))
return (void)markOverdefined(&I);

LatticeVal OpSt = getValueState(I.getOperand(0));
ValueLatticeElement OpSt = getValueState(I.getOperand(0));
if (Constant *OpC = getConstant(OpSt)) {
// Fold the constant as we build.
Constant *C = ConstantFoldCastOperand(I.getOpcode(), OpC, I.getType(), DL);
Expand Down Expand Up @@ -846,7 +826,7 @@ void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) {
Value *AggVal = EVI.getAggregateOperand();
if (AggVal->getType()->isStructTy()) {
unsigned i = *EVI.idx_begin();
LatticeVal EltVal = getStructValueState(AggVal, i);
ValueLatticeElement EltVal = getStructValueState(AggVal, i);
mergeInValue(getValueState(&EVI), &EVI, EltVal);
} else {
// Otherwise, must be extracting from an array.
Expand Down Expand Up @@ -876,7 +856,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) {
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
// This passes through all values that aren't the inserted element.
if (i != Idx) {
LatticeVal EltVal = getStructValueState(Aggr, i);
ValueLatticeElement EltVal = getStructValueState(Aggr, i);
mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
continue;
}
Expand All @@ -886,7 +866,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) {
// We don't track structs in structs.
markOverdefined(getStructValueState(&IVI, i), &IVI);
else {
LatticeVal InVal = getValueState(Val);
ValueLatticeElement InVal = getValueState(Val);
mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
}
}
Expand All @@ -903,7 +883,7 @@ void SCCPSolver::visitSelectInst(SelectInst &I) {
if (ValueState[&I].isOverdefined())
return (void)markOverdefined(&I);

LatticeVal CondValue = getValueState(I.getCondition());
ValueLatticeElement CondValue = getValueState(I.getCondition());
if (CondValue.isUnknownOrUndef())
return;

Expand All @@ -916,8 +896,8 @@ void SCCPSolver::visitSelectInst(SelectInst &I) {
// Otherwise, the condition is overdefined or a constant we can't evaluate.
// See if we can produce something better than overdefined based on the T/F
// value.
LatticeVal TVal = getValueState(I.getTrueValue());
LatticeVal FVal = getValueState(I.getFalseValue());
ValueLatticeElement TVal = getValueState(I.getTrueValue());
ValueLatticeElement FVal = getValueState(I.getFalseValue());

bool Changed = ValueState[&I].mergeIn(TVal, DL);
Changed |= ValueState[&I].mergeIn(FVal, DL);
Expand All @@ -927,9 +907,9 @@ void SCCPSolver::visitSelectInst(SelectInst &I) {

// Handle Unary Operators.
void SCCPSolver::visitUnaryOperator(Instruction &I) {
LatticeVal V0State = getValueState(I.getOperand(0));
ValueLatticeElement V0State = getValueState(I.getOperand(0));

LatticeVal &IV = ValueState[&I];
ValueLatticeElement &IV = ValueState[&I];
// ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would
// discover a concrete value later.
if (isOverdefined(IV))
Expand All @@ -953,10 +933,10 @@ void SCCPSolver::visitUnaryOperator(Instruction &I) {

// Handle Binary Operators.
void SCCPSolver::visitBinaryOperator(Instruction &I) {
LatticeVal V1State = getValueState(I.getOperand(0));
LatticeVal V2State = getValueState(I.getOperand(1));
ValueLatticeElement V1State = getValueState(I.getOperand(0));
ValueLatticeElement V2State = getValueState(I.getOperand(1));

LatticeVal &IV = ValueState[&I];
ValueLatticeElement &IV = ValueState[&I];
if (IV.isOverdefined())
return;

Expand Down Expand Up @@ -988,7 +968,7 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
B = V2State.getConstantRange();

ConstantRange R = A.binaryOp(cast<BinaryOperator>(&I)->getOpcode(), B);
mergeInValue(&I, LatticeVal::getRange(R));
mergeInValue(&I, ValueLatticeElement::getRange(R));

// TODO: Currently we do not exploit special values that produce something
// better than overdefined with an overdefined operand for vector or floating
Expand All @@ -1014,7 +994,7 @@ void SCCPSolver::visitCmpInst(CmpInst &I) {
if (C) {
if (isa<UndefValue>(C))
return;
LatticeVal CV;
ValueLatticeElement CV;
CV.markConstant(C);
mergeInValue(&I, CV);
return;
Expand All @@ -1038,7 +1018,7 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) {
Operands.reserve(I.getNumOperands());

for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
LatticeVal State = getValueState(I.getOperand(i));
ValueLatticeElement State = getValueState(I.getOperand(i));
if (State.isUnknownOrUndef())
return; // Operands are not resolved yet.

Expand Down Expand Up @@ -1076,7 +1056,7 @@ void SCCPSolver::visitStoreInst(StoreInst &SI) {
return (void)markOverdefined(&SI);

GlobalVariable *GV = cast<GlobalVariable>(SI.getOperand(1));
DenseMap<GlobalVariable*, LatticeVal>::iterator I = TrackedGlobals.find(GV);
auto I = TrackedGlobals.find(GV);
if (I == TrackedGlobals.end())
return;

Expand All @@ -1098,11 +1078,11 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
if (isOverdefined(ValueState[&I]))
return (void)markOverdefined(&I);

LatticeVal PtrVal = getValueState(I.getOperand(0));
ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
if (PtrVal.isUnknownOrUndef())
return; // The pointer is not resolved yet!

LatticeVal &IV = ValueState[&I];
ValueLatticeElement &IV = ValueState[&I];

if (!isConstant(PtrVal) || I.isVolatile())
return (void)markOverdefined(IV, &I);
Expand All @@ -1121,8 +1101,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
if (!TrackedGlobals.empty()) {
// If we are tracking this global, merge in the known value for it.
DenseMap<GlobalVariable*, LatticeVal>::iterator It =
TrackedGlobals.find(GV);
auto It = TrackedGlobals.find(GV);
if (It != TrackedGlobals.end()) {
mergeInValue(IV, &I, It->second);
return;
Expand Down Expand Up @@ -1164,7 +1143,7 @@ void SCCPSolver::handleCallOverdefined(CallSite CS) {
++AI) {
if (AI->get()->getType()->isStructTy())
return markOverdefined(I); // Can't handle struct args.
LatticeVal State = getValueState(*AI);
ValueLatticeElement State = getValueState(*AI);

if (State.isUnknownOrUndef())
return; // Operands are not resolved yet.
Expand Down Expand Up @@ -1214,7 +1193,7 @@ void SCCPSolver::handleCallArguments(CallSite CS) {

if (auto *STy = dyn_cast<StructType>(AI->getType())) {
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
LatticeVal CallArg = getStructValueState(*CAI, i);
ValueLatticeElement CallArg = getStructValueState(*CAI, i);
mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg);
}
} else
Expand Down Expand Up @@ -1262,9 +1241,9 @@ void SCCPSolver::handleCallResult(CallSite CS) {
if (CmpOp0 != CopyOf)
std::swap(CmpOp0, CmpOp1);

LatticeVal OriginalVal = getValueState(CopyOf);
LatticeVal EqVal = getValueState(CmpOp1);
LatticeVal &IV = ValueState[I];
ValueLatticeElement OriginalVal = getValueState(CopyOf);
ValueLatticeElement EqVal = getValueState(CmpOp1);
ValueLatticeElement &IV = ValueState[I];
if (PBranch->TrueEdge && Cmp->getPredicate() == CmpInst::ICMP_EQ) {
addAdditionalUser(CmpOp1, I);
if (isConstant(OriginalVal))
Expand Down Expand Up @@ -1303,7 +1282,7 @@ void SCCPSolver::handleCallResult(CallSite CS) {
mergeInValue(getStructValueState(I, i), I,
TrackedMultipleRetVals[std::make_pair(F, i)]);
} else {
MapVector<Function*, LatticeVal>::iterator TFRVI = TrackedRetVals.find(F);
auto TFRVI = TrackedRetVals.find(F);
if (TFRVI == TrackedRetVals.end())
return handleCallOverdefined(CS); // Not tracking this callee.

Expand Down Expand Up @@ -1405,14 +1384,14 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// Send the results of everything else to overdefined. We could be
// more precise than this but it isn't worth bothering.
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
LatticeVal &LV = getStructValueState(&I, i);
ValueLatticeElement &LV = getStructValueState(&I, i);
if (LV.isUnknownOrUndef())
markOverdefined(LV, &I);
}
continue;
}

LatticeVal &LV = getValueState(&I);
ValueLatticeElement &LV = getValueState(&I);
if (!LV.isUnknownOrUndef())
continue;

Expand Down Expand Up @@ -1525,20 +1504,21 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
Constant *Const = nullptr;
if (V->getType()->isStructTy()) {
std::vector<LatticeVal> IVs = Solver.getStructLatticeValueFor(V);
if (any_of(IVs, [](const LatticeVal &LV) { return isOverdefined(LV); }))
std::vector<ValueLatticeElement> IVs = Solver.getStructLatticeValueFor(V);
if (any_of(IVs,
[](const ValueLatticeElement &LV) { return isOverdefined(LV); }))
return false;
std::vector<Constant *> ConstVals;
auto *ST = cast<StructType>(V->getType());
for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
LatticeVal V = IVs[i];
ValueLatticeElement V = IVs[i];
ConstVals.push_back(isConstant(V)
? Solver.getConstant(V)
: UndefValue::get(ST->getElementType(i)));
}
Const = ConstantStruct::get(ST, ConstVals);
} else {
const LatticeVal &IV = Solver.getLatticeValueFor(V);
const ValueLatticeElement &IV = Solver.getLatticeValueFor(V);
if (isOverdefined(IV))
return false;

Expand Down Expand Up @@ -1718,9 +1698,10 @@ static void findReturnsToZap(Function &F,
if (!CallSite(U))
return true;
if (U->getType()->isStructTy()) {
return all_of(
Solver.getStructLatticeValueFor(U),
[](const LatticeVal &LV) { return !isOverdefined(LV); });
return all_of(Solver.getStructLatticeValueFor(U),
[](const ValueLatticeElement &LV) {
return !isOverdefined(LV);
});
}
return !isOverdefined(Solver.getLatticeValueFor(U));
}) &&
Expand Down Expand Up @@ -1962,8 +1943,7 @@ bool llvm::runIPSCCP(
// whether other functions are optimizable.
SmallVector<ReturnInst*, 8> ReturnsToZap;

const MapVector<Function*, LatticeVal> &RV = Solver.getTrackedRetVals();
for (const auto &I : RV) {
for (const auto &I : Solver.getTrackedRetVals()) {
Function *F = I.first;
if (isOverdefined(I.second) || F->getReturnType()->isVoidTy())
continue;
Expand All @@ -1986,11 +1966,9 @@ bool llvm::runIPSCCP(

// If we inferred constant or undef values for globals variables, we can
// delete the global and any stores that remain to it.
const DenseMap<GlobalVariable*, LatticeVal> &TG = Solver.getTrackedGlobals();
for (DenseMap<GlobalVariable*, LatticeVal>::const_iterator I = TG.begin(),
E = TG.end(); I != E; ++I) {
GlobalVariable *GV = I->first;
if (isOverdefined(I->second))
for (auto &I : make_early_inc_range(Solver.getTrackedGlobals())) {
GlobalVariable *GV = I.first;
if (isOverdefined(I.second))
continue;
LLVM_DEBUG(dbgs() << "Found that GV '" << GV->getName()
<< "' is constant!\n");
Expand Down