[SCCP] Rename undefined -> unknown.

In the solver, isUndefined() does really mean "we don't know the
value yet" rather than "this is an UndefinedValue". Discussed with
Eli Friedman.

Differential Revision:  http://reviews.llvm.org/D22192

llvm-svn: 275004
This commit is contained in:
Davide Italiano 2016-07-10 00:35:15 +00:00
parent 89c3762a7a
commit 0f03ce0c88
1 changed files with 40 additions and 40 deletions

View File

@ -59,8 +59,8 @@ namespace {
/// ///
class LatticeVal { class LatticeVal {
enum LatticeValueTy { enum LatticeValueTy {
/// undefined - This LLVM Value has no known value yet. /// unknown - This LLVM Value has no known value yet.
undefined, unknown,
/// constant - This LLVM Value has a specific constant value. /// constant - This LLVM Value has a specific constant value.
constant, constant,
@ -85,9 +85,9 @@ class LatticeVal {
} }
public: public:
LatticeVal() : Val(nullptr, undefined) {} LatticeVal() : Val(nullptr, unknown) {}
bool isUndefined() const { return getLatticeValue() == undefined; } bool isUnknown() const { return getLatticeValue() == unknown; }
bool isConstant() const { bool isConstant() const {
return getLatticeValue() == constant || getLatticeValue() == forcedconstant; return getLatticeValue() == constant || getLatticeValue() == forcedconstant;
} }
@ -114,7 +114,7 @@ public:
return false; return false;
} }
if (isUndefined()) { if (isUnknown()) {
Val.setInt(constant); Val.setInt(constant);
assert(V && "Marking constant with NULL"); assert(V && "Marking constant with NULL");
Val.setPointer(V); Val.setPointer(V);
@ -141,7 +141,7 @@ public:
} }
void markForcedConstant(Constant *V) { void markForcedConstant(Constant *V) {
assert(isUndefined() && "Can't force a defined value!"); assert(isUnknown() && "Can't force a defined value!");
Val.setInt(forcedconstant); Val.setInt(forcedconstant);
Val.setPointer(V); Val.setPointer(V);
} }
@ -350,11 +350,11 @@ private:
} }
void mergeInValue(LatticeVal &IV, Value *V, LatticeVal MergeWithV) { void mergeInValue(LatticeVal &IV, Value *V, LatticeVal MergeWithV) {
if (IV.isOverdefined() || MergeWithV.isUndefined()) if (IV.isOverdefined() || MergeWithV.isUnknown())
return; // Noop. return; // Noop.
if (MergeWithV.isOverdefined()) if (MergeWithV.isOverdefined())
markOverdefined(IV, V); markOverdefined(IV, V);
else if (IV.isUndefined()) else if (IV.isUnknown())
markConstant(IV, V, MergeWithV.getConstant()); markConstant(IV, V, MergeWithV.getConstant());
else if (IV.getConstant() != MergeWithV.getConstant()) else if (IV.getConstant() != MergeWithV.getConstant())
markOverdefined(IV, V); markOverdefined(IV, V);
@ -380,7 +380,7 @@ private:
return LV; // Common case, already in the map. return LV; // Common case, already in the map.
if (Constant *C = dyn_cast<Constant>(V)) { if (Constant *C = dyn_cast<Constant>(V)) {
// Undef values remain undefined. // Undef values remain unknown.
if (!isa<UndefValue>(V)) if (!isa<UndefValue>(V))
LV.markConstant(C); // Constants are constant LV.markConstant(C); // Constants are constant
} }
@ -411,7 +411,7 @@ private:
if (!Elt) if (!Elt)
LV.markOverdefined(); // Unknown sort of constant. LV.markOverdefined(); // Unknown sort of constant.
else if (isa<UndefValue>(Elt)) else if (isa<UndefValue>(Elt))
; // Undef values remain undefined. ; // Undef values remain unknown.
else else
LV.markConstant(Elt); // Constants are constant. LV.markConstant(Elt); // Constants are constant.
} }
@ -539,7 +539,7 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
if (!CI) { if (!CI) {
// Overdefined condition variables, and branches on unfoldable constant // Overdefined condition variables, and branches on unfoldable constant
// conditions, mean the branch could go either way. // conditions, mean the branch could go either way.
if (!BCValue.isUndefined()) if (!BCValue.isUnknown())
Succs[0] = Succs[1] = true; Succs[0] = Succs[1] = true;
return; return;
} }
@ -563,9 +563,9 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
LatticeVal SCValue = getValueState(SI->getCondition()); LatticeVal SCValue = getValueState(SI->getCondition());
ConstantInt *CI = SCValue.getConstantInt(); ConstantInt *CI = SCValue.getConstantInt();
if (!CI) { // Overdefined or undefined condition? if (!CI) { // Overdefined or unknown condition?
// All destinations are executable! // All destinations are executable!
if (!SCValue.isUndefined()) if (!SCValue.isUnknown())
Succs.assign(TI.getNumSuccessors(), true); Succs.assign(TI.getNumSuccessors(), true);
return; return;
} }
@ -609,7 +609,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
// undef conditions mean that neither edge is feasible yet. // undef conditions mean that neither edge is feasible yet.
ConstantInt *CI = BCValue.getConstantInt(); ConstantInt *CI = BCValue.getConstantInt();
if (!CI) if (!CI)
return !BCValue.isUndefined(); return !BCValue.isUnknown();
// Constant condition variables mean the branch can only go a single way. // Constant condition variables mean the branch can only go a single way.
return BI->getSuccessor(CI->isZero()) == To; return BI->getSuccessor(CI->isZero()) == To;
@ -627,7 +627,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
ConstantInt *CI = SCValue.getConstantInt(); ConstantInt *CI = SCValue.getConstantInt();
if (!CI) if (!CI)
return !SCValue.isUndefined(); return !SCValue.isUnknown();
return SI->findCaseValue(CI).getCaseSuccessor() == To; return SI->findCaseValue(CI).getCaseSuccessor() == To;
} }
@ -679,12 +679,12 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
// are overdefined, the PHI becomes overdefined as well. If they are all // are overdefined, the PHI becomes overdefined as well. If they are all
// constant, and they agree with each other, the PHI becomes the identical // constant, and they agree with each other, the PHI becomes the identical
// constant. If they are constant and don't agree, the PHI is overdefined. // constant. If they are constant and don't agree, the PHI is overdefined.
// If there are no executable operands, the PHI remains undefined. // If there are no executable operands, the PHI remains unknown.
// //
Constant *OperandVal = nullptr; Constant *OperandVal = nullptr;
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
LatticeVal IV = getValueState(PN.getIncomingValue(i)); LatticeVal IV = getValueState(PN.getIncomingValue(i));
if (IV.isUndefined()) continue; // Doesn't influence PHI node. if (IV.isUnknown()) continue; // Doesn't influence PHI node.
if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent()))
continue; continue;
@ -710,7 +710,7 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
// If we exited the loop, this means that the PHI node only has constant // If we exited the loop, this means that the PHI node only has constant
// arguments that agree with each other(and OperandVal is the constant) or // arguments that agree with each other(and OperandVal is the constant) or
// OperandVal is null because there are no defined incoming arguments. If // OperandVal is null because there are no defined incoming arguments. If
// this is the case, the PHI remains undefined. // this is the case, the PHI remains unknown.
// //
if (OperandVal) if (OperandVal)
markConstant(&PN, OperandVal); // Acquire operand value markConstant(&PN, OperandVal); // Acquire operand value
@ -833,7 +833,7 @@ void SCCPSolver::visitSelectInst(SelectInst &I) {
return markAnythingOverdefined(&I); return markAnythingOverdefined(&I);
LatticeVal CondValue = getValueState(I.getCondition()); LatticeVal CondValue = getValueState(I.getCondition());
if (CondValue.isUndefined()) if (CondValue.isUnknown())
return; return;
if (ConstantInt *CondCB = CondValue.getConstantInt()) { if (ConstantInt *CondCB = CondValue.getConstantInt()) {
@ -853,9 +853,9 @@ void SCCPSolver::visitSelectInst(SelectInst &I) {
TVal.getConstant() == FVal.getConstant()) TVal.getConstant() == FVal.getConstant())
return markConstant(&I, FVal.getConstant()); return markConstant(&I, FVal.getConstant());
if (TVal.isUndefined()) // select ?, undef, X -> X. if (TVal.isUnknown()) // select ?, undef, X -> X.
return mergeInValue(&I, FVal); return mergeInValue(&I, FVal);
if (FVal.isUndefined()) // select ?, X, undef -> X. if (FVal.isUnknown()) // select ?, X, undef -> X.
return mergeInValue(&I, TVal); return mergeInValue(&I, TVal);
markOverdefined(&I); markOverdefined(&I);
} }
@ -894,7 +894,7 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
NonOverdefVal = &V2State; NonOverdefVal = &V2State;
if (NonOverdefVal) { if (NonOverdefVal) {
if (NonOverdefVal->isUndefined()) { if (NonOverdefVal->isUnknown()) {
// Could annihilate value. // Could annihilate value.
if (I.getOpcode() == Instruction::And) if (I.getOpcode() == Instruction::And)
markConstant(IV, &I, Constant::getNullValue(I.getType())); markConstant(IV, &I, Constant::getNullValue(I.getType()));
@ -938,7 +938,7 @@ void SCCPSolver::visitCmpInst(CmpInst &I) {
return markConstant(IV, &I, C); return markConstant(IV, &I, C);
} }
// If operands are still undefined, wait for it to resolve. // If operands are still unknown, wait for it to resolve.
if (!V1State.isOverdefined() && !V2State.isOverdefined()) if (!V1State.isOverdefined() && !V2State.isOverdefined())
return; return;
@ -971,7 +971,7 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) {
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
LatticeVal State = getValueState(I.getOperand(i)); LatticeVal State = getValueState(I.getOperand(i));
if (State.isUndefined()) if (State.isUnknown())
return; // Operands are not resolved yet. return; // Operands are not resolved yet.
if (State.isOverdefined()) if (State.isOverdefined())
@ -1017,7 +1017,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
return markAnythingOverdefined(&I); return markAnythingOverdefined(&I);
LatticeVal PtrVal = getValueState(I.getOperand(0)); LatticeVal PtrVal = getValueState(I.getOperand(0));
if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! if (PtrVal.isUnknown()) return; // The pointer is not resolved yet!
LatticeVal &IV = ValueState[&I]; LatticeVal &IV = ValueState[&I];
if (IV.isOverdefined()) return; if (IV.isOverdefined()) return;
@ -1078,7 +1078,7 @@ CallOverdefined:
AI != E; ++AI) { AI != E; ++AI) {
LatticeVal State = getValueState(*AI); LatticeVal State = getValueState(*AI);
if (State.isUndefined()) if (State.isUnknown())
return; // Operands are not resolved yet. return; // Operands are not resolved yet.
if (State.isOverdefined()) if (State.isOverdefined())
return markOverdefined(I); return markOverdefined(I);
@ -1252,14 +1252,14 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// more precise than this but it isn't worth bothering. // more precise than this but it isn't worth bothering.
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
LatticeVal &LV = getStructValueState(&I, i); LatticeVal &LV = getStructValueState(&I, i);
if (LV.isUndefined()) if (LV.isUnknown())
markOverdefined(LV, &I); markOverdefined(LV, &I);
} }
continue; continue;
} }
LatticeVal &LV = getValueState(&I); LatticeVal &LV = getValueState(&I);
if (!LV.isUndefined()) continue; if (!LV.isUnknown()) continue;
// extractvalue is safe; check here because the argument is a struct. // extractvalue is safe; check here because the argument is a struct.
if (isa<ExtractValueInst>(I)) if (isa<ExtractValueInst>(I))
@ -1298,7 +1298,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::FDiv: case Instruction::FDiv:
case Instruction::FRem: case Instruction::FRem:
// Floating-point binary operation: be conservative. // Floating-point binary operation: be conservative.
if (Op0LV.isUndefined() && Op1LV.isUndefined()) if (Op0LV.isUnknown() && Op1LV.isUnknown())
markForcedConstant(&I, Constant::getNullValue(ITy)); markForcedConstant(&I, Constant::getNullValue(ITy));
else else
markOverdefined(&I); markOverdefined(&I);
@ -1318,7 +1318,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::Mul: case Instruction::Mul:
case Instruction::And: case Instruction::And:
// Both operands undef -> undef // Both operands undef -> undef
if (Op0LV.isUndefined() && Op1LV.isUndefined()) if (Op0LV.isUnknown() && Op1LV.isUnknown())
break; break;
// undef * X -> 0. X could be zero. // undef * X -> 0. X could be zero.
// undef & X -> 0. X could be zero. // undef & X -> 0. X could be zero.
@ -1327,7 +1327,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::Or: case Instruction::Or:
// Both operands undef -> undef // Both operands undef -> undef
if (Op0LV.isUndefined() && Op1LV.isUndefined()) if (Op0LV.isUnknown() && Op1LV.isUnknown())
break; break;
// undef | X -> -1. X could be -1. // undef | X -> -1. X could be -1.
markForcedConstant(&I, Constant::getAllOnesValue(ITy)); markForcedConstant(&I, Constant::getAllOnesValue(ITy));
@ -1337,7 +1337,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
// undef ^ undef -> 0; strictly speaking, this is not strictly // undef ^ undef -> 0; strictly speaking, this is not strictly
// necessary, but we try to be nice to people who expect this // necessary, but we try to be nice to people who expect this
// behavior in simple cases // behavior in simple cases
if (Op0LV.isUndefined() && Op1LV.isUndefined()) { if (Op0LV.isUnknown() && Op1LV.isUnknown()) {
markForcedConstant(&I, Constant::getNullValue(ITy)); markForcedConstant(&I, Constant::getNullValue(ITy));
return true; return true;
} }
@ -1350,7 +1350,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::URem: case Instruction::URem:
// X / undef -> undef. No change. // X / undef -> undef. No change.
// X % undef -> undef. No change. // X % undef -> undef. No change.
if (Op1LV.isUndefined()) break; if (Op1LV.isUnknown()) break;
// X / 0 -> undef. No change. // X / 0 -> undef. No change.
// X % 0 -> undef. No change. // X % 0 -> undef. No change.
@ -1364,7 +1364,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::AShr: case Instruction::AShr:
// X >>a undef -> undef. // X >>a undef -> undef.
if (Op1LV.isUndefined()) break; if (Op1LV.isUnknown()) break;
// Shifting by the bitwidth or more is undefined. // Shifting by the bitwidth or more is undefined.
if (Op1LV.isConstant()) { if (Op1LV.isConstant()) {
@ -1381,7 +1381,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::Shl: case Instruction::Shl:
// X << undef -> undef. // X << undef -> undef.
// X >> undef -> undef. // X >> undef -> undef.
if (Op1LV.isUndefined()) break; if (Op1LV.isUnknown()) break;
// Shifting by the bitwidth or more is undefined. // Shifting by the bitwidth or more is undefined.
if (Op1LV.isConstant()) { if (Op1LV.isConstant()) {
@ -1398,13 +1398,13 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
case Instruction::Select: case Instruction::Select:
Op1LV = getValueState(I.getOperand(1)); Op1LV = getValueState(I.getOperand(1));
// undef ? X : Y -> X or Y. There could be commonality between X/Y. // undef ? X : Y -> X or Y. There could be commonality between X/Y.
if (Op0LV.isUndefined()) { if (Op0LV.isUnknown()) {
if (!Op1LV.isConstant()) // Pick the constant one if there is any. if (!Op1LV.isConstant()) // Pick the constant one if there is any.
Op1LV = getValueState(I.getOperand(2)); Op1LV = getValueState(I.getOperand(2));
} else if (Op1LV.isUndefined()) { } else if (Op1LV.isUnknown()) {
// c ? undef : undef -> undef. No change. // c ? undef : undef -> undef. No change.
Op1LV = getValueState(I.getOperand(2)); Op1LV = getValueState(I.getOperand(2));
if (Op1LV.isUndefined()) if (Op1LV.isUnknown())
break; break;
// Otherwise, c ? undef : x -> x. // Otherwise, c ? undef : x -> x.
} else { } else {
@ -1457,7 +1457,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
TerminatorInst *TI = BB.getTerminator(); TerminatorInst *TI = BB.getTerminator();
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
if (!BI->isConditional()) continue; if (!BI->isConditional()) continue;
if (!getValueState(BI->getCondition()).isUndefined()) if (!getValueState(BI->getCondition()).isUnknown())
continue; continue;
// If the input to SCCP is actually branch on undef, fix the undef to // If the input to SCCP is actually branch on undef, fix the undef to
@ -1479,7 +1479,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) { if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
if (!SI->getNumCases()) if (!SI->getNumCases())
continue; continue;
if (!getValueState(SI->getCondition()).isUndefined()) if (!getValueState(SI->getCondition()).isUnknown())
continue; continue;
// If the input to SCCP is actually switch on undef, fix the undef to // If the input to SCCP is actually switch on undef, fix the undef to