Skip to content

Commit ff8049a

Browse files
[InlineCost] Allow simplifying to non-Constant values (NFCI) (#145083)
Allow mapping callee Values to arbitrary (non-Constant) simplified values. The simplified values can also originate from the caller. This enables us to simplify instructions in the callee with instructions from the caller. The first use case for this is simplifying extractvalues (PR #145054).
1 parent b054363 commit ff8049a

File tree

1 file changed

+51
-25
lines changed

1 file changed

+51
-25
lines changed

llvm/lib/Analysis/InlineCost.cpp

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
391391
/// likely simplifications post-inlining. The most important aspect we track
392392
/// is CFG altering simplifications -- when we prove a basic block dead, that
393393
/// can cause dramatic shifts in the cost of inlining a function.
394-
DenseMap<Value *, Constant *> SimplifiedValues;
394+
/// Note: The simplified Value may be owned by the caller function.
395+
DenseMap<Value *, Value *> SimplifiedValues;
395396

396397
/// Keep track of the values which map back (through function arguments) to
397398
/// allocas on the caller stack which could be simplified through SROA.
@@ -432,7 +433,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
432433
template <typename T> T *getDirectOrSimplifiedValue(Value *V) const {
433434
if (auto *Direct = dyn_cast<T>(V))
434435
return Direct;
435-
return dyn_cast_if_present<T>(SimplifiedValues.lookup(V));
436+
return getSimplifiedValue<T>(V);
436437
}
437438

438439
// Custom simplification helper routines.
@@ -525,11 +526,33 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
525526

526527
InlineResult analyze();
527528

528-
std::optional<Constant *> getSimplifiedValue(Instruction *I) {
529-
auto It = SimplifiedValues.find(I);
530-
if (It != SimplifiedValues.end())
531-
return It->second;
532-
return std::nullopt;
529+
/// Lookup simplified Value. May return a value owned by the caller.
530+
Value *getSimplifiedValueUnchecked(Value *V) const {
531+
return SimplifiedValues.lookup(V);
532+
}
533+
534+
/// Lookup simplified Value, but return nullptr if the simplified value is
535+
/// owned by the caller.
536+
template <typename T> T *getSimplifiedValue(Value *V) const {
537+
Value *SimpleV = SimplifiedValues.lookup(V);
538+
if (!SimpleV)
539+
return nullptr;
540+
541+
// Skip checks if we know T is a global. This has a small, but measurable
542+
// impact on compile-time.
543+
if constexpr (std::is_base_of_v<Constant, T>)
544+
return dyn_cast<T>(SimpleV);
545+
546+
// Make sure the simplified Value is owned by this function
547+
if (auto *I = dyn_cast<Instruction>(SimpleV)) {
548+
if (I->getFunction() != &F)
549+
return nullptr;
550+
} else if (auto *Arg = dyn_cast<Argument>(SimpleV)) {
551+
if (Arg->getParent() != &F)
552+
return nullptr;
553+
} else if (!isa<Constant>(SimpleV))
554+
return nullptr;
555+
return dyn_cast<T>(SimpleV);
533556
}
534557

535558
// Keep a bunch of stats about the cost savings found so we can print them
@@ -921,12 +944,11 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
921944
if (BranchInst *BI = dyn_cast<BranchInst>(&I)) {
922945
// Count a conditional branch as savings if it becomes unconditional.
923946
if (BI->isConditional() &&
924-
isa_and_nonnull<ConstantInt>(
925-
SimplifiedValues.lookup(BI->getCondition()))) {
947+
getSimplifiedValue<ConstantInt>(BI->getCondition())) {
926948
CurrentSavings += InstrCost;
927949
}
928950
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(&I)) {
929-
if (isa_and_present<ConstantInt>(SimplifiedValues.lookup(SI->getCondition())))
951+
if (getSimplifiedValue<ConstantInt>(SI->getCondition()))
930952
CurrentSavings += InstrCost;
931953
} else if (Value *V = dyn_cast<Value>(&I)) {
932954
// Count an instruction as savings if we can fold it.
@@ -1423,10 +1445,17 @@ void InlineCostAnnotationWriter::emitInstructionAnnot(
14231445
if (Record->hasThresholdChanged())
14241446
OS << ", threshold delta = " << Record->getThresholdDelta();
14251447
}
1426-
auto C = ICCA->getSimplifiedValue(const_cast<Instruction *>(I));
1427-
if (C) {
1448+
auto *V = ICCA->getSimplifiedValueUnchecked(const_cast<Instruction *>(I));
1449+
if (V) {
14281450
OS << ", simplified to ";
1429-
(*C)->print(OS, true);
1451+
V->print(OS, true);
1452+
if (auto *VI = dyn_cast<Instruction>(V)) {
1453+
if (VI->getFunction() != I->getFunction())
1454+
OS << " (caller instruction)";
1455+
} else if (auto *VArg = dyn_cast<Argument>(V)) {
1456+
if (VArg->getParent() != I->getFunction())
1457+
OS << " (caller argument)";
1458+
}
14301459
}
14311460
OS << "\n";
14321461
}
@@ -1483,7 +1512,7 @@ bool CallAnalyzer::isGEPFree(GetElementPtrInst &GEP) {
14831512
SmallVector<Value *, 4> Operands;
14841513
Operands.push_back(GEP.getOperand(0));
14851514
for (const Use &Op : GEP.indices())
1486-
if (Constant *SimpleOp = SimplifiedValues.lookup(Op))
1515+
if (Constant *SimpleOp = getSimplifiedValue<Constant>(Op))
14871516
Operands.push_back(SimpleOp);
14881517
else
14891518
Operands.push_back(Op);
@@ -1498,7 +1527,7 @@ bool CallAnalyzer::visitAlloca(AllocaInst &I) {
14981527
// Check whether inlining will turn a dynamic alloca into a static
14991528
// alloca and handle that case.
15001529
if (I.isArrayAllocation()) {
1501-
Constant *Size = SimplifiedValues.lookup(I.getArraySize());
1530+
Constant *Size = getSimplifiedValue<Constant>(I.getArraySize());
15021531
if (auto *AllocSize = dyn_cast_or_null<ConstantInt>(Size)) {
15031532
// Sometimes a dynamic alloca could be converted into a static alloca
15041533
// after this constant prop, and become a huge static alloca on an
@@ -2388,7 +2417,7 @@ bool CallAnalyzer::visitCallBase(CallBase &Call) {
23882417
// Check if this happens to be an indirect function call to a known function
23892418
// in this inline context. If not, we've done all we can.
23902419
Value *Callee = Call.getCalledOperand();
2391-
F = dyn_cast_or_null<Function>(SimplifiedValues.lookup(Callee));
2420+
F = getSimplifiedValue<Function>(Callee);
23922421
if (!F || F->getFunctionType() != Call.getFunctionType()) {
23932422
onCallArgumentSetup(Call);
23942423

@@ -2483,8 +2512,7 @@ bool CallAnalyzer::visitSelectInst(SelectInst &SI) {
24832512

24842513
Constant *TrueC = getDirectOrSimplifiedValue<Constant>(TrueVal);
24852514
Constant *FalseC = getDirectOrSimplifiedValue<Constant>(FalseVal);
2486-
Constant *CondC =
2487-
dyn_cast_or_null<Constant>(SimplifiedValues.lookup(SI.getCondition()));
2515+
Constant *CondC = getSimplifiedValue<Constant>(SI.getCondition());
24882516

24892517
if (!CondC) {
24902518
// Select C, X, X => X
@@ -2833,8 +2861,9 @@ InlineResult CallAnalyzer::analyze() {
28332861
auto CAI = CandidateCall.arg_begin();
28342862
for (Argument &FAI : F.args()) {
28352863
assert(CAI != CandidateCall.arg_end());
2836-
if (Constant *C = dyn_cast<Constant>(CAI))
2837-
SimplifiedValues[&FAI] = C;
2864+
SimplifiedValues[&FAI] = *CAI;
2865+
if (isa<Constant>(*CAI))
2866+
++NumConstantArgs;
28382867

28392868
Value *PtrArg = *CAI;
28402869
if (ConstantInt *C = stripAndComputeInBoundsConstantOffsets(PtrArg)) {
@@ -2849,7 +2878,6 @@ InlineResult CallAnalyzer::analyze() {
28492878
}
28502879
++CAI;
28512880
}
2852-
NumConstantArgs = SimplifiedValues.size();
28532881
NumConstantOffsetPtrArgs = ConstantOffsetPtrs.size();
28542882
NumAllocaArgs = SROAArgValues.size();
28552883

@@ -2911,8 +2939,7 @@ InlineResult CallAnalyzer::analyze() {
29112939
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
29122940
if (BI->isConditional()) {
29132941
Value *Cond = BI->getCondition();
2914-
if (ConstantInt *SimpleCond =
2915-
dyn_cast_or_null<ConstantInt>(SimplifiedValues.lookup(Cond))) {
2942+
if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(Cond)) {
29162943
BasicBlock *NextBB = BI->getSuccessor(SimpleCond->isZero() ? 1 : 0);
29172944
BBWorklist.insert(NextBB);
29182945
KnownSuccessors[BB] = NextBB;
@@ -2922,8 +2949,7 @@ InlineResult CallAnalyzer::analyze() {
29222949
}
29232950
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
29242951
Value *Cond = SI->getCondition();
2925-
if (ConstantInt *SimpleCond =
2926-
dyn_cast_or_null<ConstantInt>(SimplifiedValues.lookup(Cond))) {
2952+
if (ConstantInt *SimpleCond = getSimplifiedValue<ConstantInt>(Cond)) {
29272953
BasicBlock *NextBB = SI->findCaseValue(SimpleCond)->getCaseSuccessor();
29282954
BBWorklist.insert(NextBB);
29292955
KnownSuccessors[BB] = NextBB;

0 commit comments

Comments
 (0)