Skip to content

Commit 5d22980

Browse files
authored
[LVI][SCCP] Avoid copying ValueLatticeElement (#163901)
Copying ValueLatticeElement becomes expensive after #111544. This patch eliminates some redundant copies to improve performance. The code change has been carefully reviewed to ensure that there is no dangling reference. Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=f4359301c033694d36865c7560714164d2050240&to=4ea449bd53feef43403c35d8b815ddca752dbc17&stat=instructions%3Au
1 parent 6420da6 commit 5d22980

File tree

2 files changed

+53
-53
lines changed

2 files changed

+53
-53
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -947,9 +947,8 @@ LazyValueInfoImpl::solveBlockValueSelect(SelectInst *SI, BasicBlock *BB) {
947947
/*UseBlockValue*/ false));
948948
}
949949

950-
ValueLatticeElement Result = TrueVal;
951-
Result.mergeIn(FalseVal);
952-
return Result;
950+
TrueVal.mergeIn(FalseVal);
951+
return TrueVal;
953952
}
954953

955954
std::optional<ConstantRange>
@@ -1778,9 +1777,8 @@ ValueLatticeElement LazyValueInfoImpl::getValueInBlock(Value *V, BasicBlock *BB,
17781777
assert(OptResult && "Value not available after solving");
17791778
}
17801779

1781-
ValueLatticeElement Result = *OptResult;
1782-
LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
1783-
return Result;
1780+
LLVM_DEBUG(dbgs() << " Result = " << *OptResult << "\n");
1781+
return *OptResult;
17841782
}
17851783

17861784
ValueLatticeElement LazyValueInfoImpl::getValueAt(Value *V, Instruction *CxtI) {

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -634,18 +634,10 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
634634
/// Merge \p MergeWithV into \p IV and push \p V to the worklist, if \p IV
635635
/// changes.
636636
bool mergeInValue(ValueLatticeElement &IV, Value *V,
637-
ValueLatticeElement MergeWithV,
637+
const ValueLatticeElement &MergeWithV,
638638
ValueLatticeElement::MergeOptions Opts = {
639639
/*MayIncludeUndef=*/false, /*CheckWiden=*/false});
640640

641-
bool mergeInValue(Value *V, ValueLatticeElement MergeWithV,
642-
ValueLatticeElement::MergeOptions Opts = {
643-
/*MayIncludeUndef=*/false, /*CheckWiden=*/false}) {
644-
assert(!V->getType()->isStructTy() &&
645-
"non-structs should use markConstant");
646-
return mergeInValue(ValueState[V], V, MergeWithV, Opts);
647-
}
648-
649641
/// getValueState - Return the ValueLatticeElement object that corresponds to
650642
/// the value. This function handles the case when the value hasn't been seen
651643
/// yet by properly seeding constants etc.
@@ -987,7 +979,7 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
987979
void trackValueOfArgument(Argument *A) {
988980
if (A->getType()->isStructTy())
989981
return (void)markOverdefined(A);
990-
mergeInValue(A, getArgAttributeVL(A));
982+
mergeInValue(ValueState[A], A, getArgAttributeVL(A));
991983
}
992984

993985
bool isStructLatticeConstant(Function *F, StructType *STy);
@@ -1128,8 +1120,7 @@ bool SCCPInstVisitor::isStructLatticeConstant(Function *F, StructType *STy) {
11281120
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
11291121
const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i));
11301122
assert(It != TrackedMultipleRetVals.end());
1131-
ValueLatticeElement LV = It->second;
1132-
if (!SCCPSolver::isConstant(LV))
1123+
if (!SCCPSolver::isConstant(It->second))
11331124
return false;
11341125
}
11351126
return true;
@@ -1160,7 +1151,7 @@ Constant *SCCPInstVisitor::getConstantOrNull(Value *V) const {
11601151
std::vector<Constant *> ConstVals;
11611152
auto *ST = cast<StructType>(V->getType());
11621153
for (unsigned I = 0, E = ST->getNumElements(); I != E; ++I) {
1163-
ValueLatticeElement LV = LVs[I];
1154+
const ValueLatticeElement &LV = LVs[I];
11641155
ConstVals.push_back(SCCPSolver::isConstant(LV)
11651156
? getConstant(LV, ST->getElementType(I))
11661157
: UndefValue::get(ST->getElementType(I)));
@@ -1225,7 +1216,7 @@ void SCCPInstVisitor::visitInstruction(Instruction &I) {
12251216
}
12261217

12271218
bool SCCPInstVisitor::mergeInValue(ValueLatticeElement &IV, Value *V,
1228-
ValueLatticeElement MergeWithV,
1219+
const ValueLatticeElement &MergeWithV,
12291220
ValueLatticeElement::MergeOptions Opts) {
12301221
if (IV.mergeIn(MergeWithV, Opts)) {
12311222
pushUsersToWorkList(V);
@@ -1264,7 +1255,7 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
12641255
return;
12651256
}
12661257

1267-
ValueLatticeElement BCValue = getValueState(BI->getCondition());
1258+
const ValueLatticeElement &BCValue = getValueState(BI->getCondition());
12681259
ConstantInt *CI = getConstantInt(BCValue, BI->getCondition()->getType());
12691260
if (!CI) {
12701261
// Overdefined condition variables, and branches on unfoldable constant
@@ -1326,7 +1317,7 @@ void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
13261317
// the target as executable.
13271318
if (auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
13281319
// Casts are folded by visitCastInst.
1329-
ValueLatticeElement IBRValue = getValueState(IBR->getAddress());
1320+
const ValueLatticeElement &IBRValue = getValueState(IBR->getAddress());
13301321
BlockAddress *Addr = dyn_cast_or_null<BlockAddress>(
13311322
getConstant(IBRValue, IBR->getAddress()->getType()));
13321323
if (!Addr) { // Overdefined or unknown condition?
@@ -1408,7 +1399,7 @@ void SCCPInstVisitor::visitPHINode(PHINode &PN) {
14081399
if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent()))
14091400
continue;
14101401

1411-
ValueLatticeElement IV = getValueState(PN.getIncomingValue(i));
1402+
const ValueLatticeElement &IV = getValueState(PN.getIncomingValue(i));
14121403
PhiState.mergeIn(IV);
14131404
NumActiveIncoming++;
14141405
if (PhiState.isOverdefined())
@@ -1420,10 +1411,10 @@ void SCCPInstVisitor::visitPHINode(PHINode &PN) {
14201411
// extensions to match the number of active incoming values. This helps to
14211412
// limit multiple extensions caused by the same incoming value, if other
14221413
// incoming values are equal.
1423-
mergeInValue(&PN, PhiState,
1414+
ValueLatticeElement &PhiStateRef = ValueState[&PN];
1415+
mergeInValue(PhiStateRef, &PN, PhiState,
14241416
ValueLatticeElement::MergeOptions().setMaxWidenSteps(
14251417
NumActiveIncoming + 1));
1426-
ValueLatticeElement &PhiStateRef = getValueState(&PN);
14271418
PhiStateRef.setNumRangeExtensions(
14281419
std::max(NumActiveIncoming, PhiStateRef.getNumRangeExtensions()));
14291420
}
@@ -1481,7 +1472,7 @@ void SCCPInstVisitor::visitCastInst(CastInst &I) {
14811472
}
14821473
}
14831474

1484-
ValueLatticeElement OpSt = getValueState(I.getOperand(0));
1475+
const ValueLatticeElement &OpSt = getValueState(I.getOperand(0));
14851476
if (OpSt.isUnknownOrUndef())
14861477
return;
14871478

@@ -1496,9 +1487,9 @@ void SCCPInstVisitor::visitCastInst(CastInst &I) {
14961487
if (I.getDestTy()->isIntOrIntVectorTy() &&
14971488
I.getSrcTy()->isIntOrIntVectorTy() &&
14981489
I.getOpcode() != Instruction::BitCast) {
1499-
auto &LV = getValueState(&I);
15001490
ConstantRange OpRange =
15011491
OpSt.asConstantRange(I.getSrcTy(), /*UndefAllowed=*/false);
1492+
auto &LV = getValueState(&I);
15021493

15031494
Type *DestTy = I.getDestTy();
15041495
ConstantRange Res = ConstantRange::getEmpty(DestTy->getScalarSizeInBits());
@@ -1516,19 +1507,24 @@ void SCCPInstVisitor::handleExtractOfWithOverflow(ExtractValueInst &EVI,
15161507
const WithOverflowInst *WO,
15171508
unsigned Idx) {
15181509
Value *LHS = WO->getLHS(), *RHS = WO->getRHS();
1519-
ValueLatticeElement L = getValueState(LHS);
1520-
ValueLatticeElement R = getValueState(RHS);
1510+
Type *Ty = LHS->getType();
1511+
15211512
addAdditionalUser(LHS, &EVI);
15221513
addAdditionalUser(RHS, &EVI);
1523-
if (L.isUnknownOrUndef() || R.isUnknownOrUndef())
1524-
return; // Wait to resolve.
15251514

1526-
Type *Ty = LHS->getType();
1515+
const ValueLatticeElement &L = getValueState(LHS);
1516+
if (L.isUnknownOrUndef())
1517+
return; // Wait to resolve.
15271518
ConstantRange LR = L.asConstantRange(Ty, /*UndefAllowed=*/false);
1519+
1520+
const ValueLatticeElement &R = getValueState(RHS);
1521+
if (R.isUnknownOrUndef())
1522+
return; // Wait to resolve.
1523+
15281524
ConstantRange RR = R.asConstantRange(Ty, /*UndefAllowed=*/false);
15291525
if (Idx == 0) {
15301526
ConstantRange Res = LR.binaryOp(WO->getBinaryOp(), RR);
1531-
mergeInValue(&EVI, ValueLatticeElement::getRange(Res));
1527+
mergeInValue(ValueState[&EVI], &EVI, ValueLatticeElement::getRange(Res));
15321528
} else {
15331529
assert(Idx == 1 && "Index can only be 0 or 1");
15341530
ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
@@ -1560,7 +1556,7 @@ void SCCPInstVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
15601556
if (auto *WO = dyn_cast<WithOverflowInst>(AggVal))
15611557
return handleExtractOfWithOverflow(EVI, WO, i);
15621558
ValueLatticeElement EltVal = getStructValueState(AggVal, i);
1563-
mergeInValue(getValueState(&EVI), &EVI, EltVal);
1559+
mergeInValue(ValueState[&EVI], &EVI, EltVal);
15641560
} else {
15651561
// Otherwise, must be extracting from an array.
15661562
return (void)markOverdefined(&EVI);
@@ -1616,14 +1612,18 @@ void SCCPInstVisitor::visitSelectInst(SelectInst &I) {
16161612
if (ValueState[&I].isOverdefined())
16171613
return (void)markOverdefined(&I);
16181614

1619-
ValueLatticeElement CondValue = getValueState(I.getCondition());
1615+
const ValueLatticeElement &CondValue = getValueState(I.getCondition());
16201616
if (CondValue.isUnknownOrUndef())
16211617
return;
16221618

16231619
if (ConstantInt *CondCB =
16241620
getConstantInt(CondValue, I.getCondition()->getType())) {
16251621
Value *OpVal = CondCB->isZero() ? I.getFalseValue() : I.getTrueValue();
1626-
mergeInValue(&I, getValueState(OpVal));
1622+
const ValueLatticeElement &OpValState = getValueState(OpVal);
1623+
// Safety: ValueState[&I] doesn't invalidate OpValState since it is already
1624+
// in the map.
1625+
assert(ValueState.contains(&I) && "&I is not in ValueState map.");
1626+
mergeInValue(ValueState[&I], &I, OpValState);
16271627
return;
16281628
}
16291629

@@ -1721,7 +1721,7 @@ void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
17211721
// being a special floating value.
17221722
ValueLatticeElement NewV;
17231723
NewV.markConstant(C, /*MayIncludeUndef=*/true);
1724-
return (void)mergeInValue(&I, NewV);
1724+
return (void)mergeInValue(ValueState[&I], &I, NewV);
17251725
}
17261726
}
17271727

@@ -1741,7 +1741,7 @@ void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
17411741
R = A.overflowingBinaryOp(BO->getOpcode(), B, OBO->getNoWrapKind());
17421742
else
17431743
R = A.binaryOp(BO->getOpcode(), B);
1744-
mergeInValue(&I, ValueLatticeElement::getRange(R));
1744+
mergeInValue(ValueState[&I], &I, ValueLatticeElement::getRange(R));
17451745

17461746
// TODO: Currently we do not exploit special values that produce something
17471747
// better than overdefined with an overdefined operand for vector or floating
@@ -1767,7 +1767,7 @@ void SCCPInstVisitor::visitCmpInst(CmpInst &I) {
17671767
if (C) {
17681768
ValueLatticeElement CV;
17691769
CV.markConstant(C);
1770-
mergeInValue(&I, CV);
1770+
mergeInValue(ValueState[&I], &I, CV);
17711771
return;
17721772
}
17731773

@@ -1802,7 +1802,7 @@ void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
18021802
Operands.reserve(I.getNumOperands());
18031803

18041804
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
1805-
ValueLatticeElement State = getValueState(I.getOperand(i));
1805+
const ValueLatticeElement &State = getValueState(I.getOperand(i));
18061806
if (State.isUnknownOrUndef())
18071807
return; // Operands are not resolved yet.
18081808

@@ -1881,14 +1881,13 @@ void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
18811881
if (ValueState[&I].isOverdefined())
18821882
return (void)markOverdefined(&I);
18831883

1884-
ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
1884+
const ValueLatticeElement &PtrVal = getValueState(I.getOperand(0));
18851885
if (PtrVal.isUnknownOrUndef())
18861886
return; // The pointer is not resolved yet!
18871887

1888-
ValueLatticeElement &IV = ValueState[&I];
1889-
18901888
if (SCCPSolver::isConstant(PtrVal)) {
18911889
Constant *Ptr = getConstant(PtrVal, I.getOperand(0)->getType());
1890+
ValueLatticeElement &IV = ValueState[&I];
18921891

18931892
// load null is undefined.
18941893
if (isa<ConstantPointerNull>(Ptr)) {
@@ -1916,7 +1915,7 @@ void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
19161915
}
19171916

19181917
// Fall back to metadata.
1919-
mergeInValue(&I, getValueFromMetadata(&I));
1918+
mergeInValue(ValueState[&I], &I, getValueFromMetadata(&I));
19201919
}
19211920

19221921
void SCCPInstVisitor::visitCallBase(CallBase &CB) {
@@ -1944,7 +1943,7 @@ void SCCPInstVisitor::handleCallOverdefined(CallBase &CB) {
19441943
return markOverdefined(&CB); // Can't handle struct args.
19451944
if (A.get()->getType()->isMetadataTy())
19461945
continue; // Carried in CB, not allowed in Operands.
1947-
ValueLatticeElement State = getValueState(A);
1946+
const ValueLatticeElement &State = getValueState(A);
19481947

19491948
if (State.isUnknownOrUndef())
19501949
return; // Operands are not resolved yet.
@@ -1964,7 +1963,7 @@ void SCCPInstVisitor::handleCallOverdefined(CallBase &CB) {
19641963
}
19651964

19661965
// Fall back to metadata.
1967-
mergeInValue(&CB, getValueFromMetadata(&CB));
1966+
mergeInValue(ValueState[&CB], &CB, getValueFromMetadata(&CB));
19681967
}
19691968

19701969
void SCCPInstVisitor::handleCallArguments(CallBase &CB) {
@@ -1992,10 +1991,11 @@ void SCCPInstVisitor::handleCallArguments(CallBase &CB) {
19921991
mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
19931992
getMaxWidenStepsOpts());
19941993
}
1995-
} else
1996-
mergeInValue(&*AI,
1997-
getValueState(*CAI).intersect(getArgAttributeVL(&*AI)),
1998-
getMaxWidenStepsOpts());
1994+
} else {
1995+
ValueLatticeElement CallArg =
1996+
getValueState(*CAI).intersect(getArgAttributeVL(&*AI));
1997+
mergeInValue(ValueState[&*AI], &*AI, CallArg, getMaxWidenStepsOpts());
1998+
}
19991999
}
20002000
}
20012001
}
@@ -2076,7 +2076,8 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
20762076
if (II->getIntrinsicID() == Intrinsic::vscale) {
20772077
unsigned BitWidth = CB.getType()->getScalarSizeInBits();
20782078
const ConstantRange Result = getVScaleRange(II->getFunction(), BitWidth);
2079-
return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
2079+
return (void)mergeInValue(ValueState[II], II,
2080+
ValueLatticeElement::getRange(Result));
20802081
}
20812082

20822083
if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
@@ -2094,7 +2095,8 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
20942095

20952096
ConstantRange Result =
20962097
ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
2097-
return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
2098+
return (void)mergeInValue(ValueState[II], II,
2099+
ValueLatticeElement::getRange(Result));
20982100
}
20992101
}
21002102

@@ -2121,7 +2123,7 @@ void SCCPInstVisitor::handleCallResult(CallBase &CB) {
21212123
return handleCallOverdefined(CB); // Not tracking this callee.
21222124

21232125
// If so, propagate the return value of the callee into this call result.
2124-
mergeInValue(&CB, TFRVI->second, getMaxWidenStepsOpts());
2126+
mergeInValue(ValueState[&CB], &CB, TFRVI->second, getMaxWidenStepsOpts());
21252127
}
21262128
}
21272129

0 commit comments

Comments
 (0)