Skip to content

Commit 0383253

Browse files
author
Kirill Naumov
committed
[InlineCost] Addressing a very strict assert check in CostAnnotationWriter::emitInstructionAnnot
The assert checks that every instruction must be annotated by this point while it is not necessary. If the inlining process was interrupted because the threshold was reached, the rest of the instructions would not be annotated which triggers the assert. The added test shows the situation in which it can happen. This is a recommit as the original commit fail due to the absence of REQUIRES: assert in the test. Reviewed By: mtrofin Differential Revision: https://reviews.llvm.org/D79107
1 parent 51308ee commit 0383253

File tree

2 files changed

+48
-23
lines changed

2 files changed

+48
-23
lines changed

llvm/lib/Analysis/InlineCost.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ static cl::opt<int>
5454
cl::ZeroOrMore,
5555
cl::desc("Default amount of inlining to perform"));
5656

57-
static cl::opt<bool> PrintDebugInstructionDeltas("print-instruction-deltas",
58-
cl::Hidden, cl::init(false),
57+
static cl::opt<bool> PrintDebugInstructionDeltas(
58+
"print-instruction-deltas", cl::Hidden, cl::init(false),
5959
cl::desc("Prints deltas of cost and threshold per instruction"));
6060

6161
static cl::opt<int> InlineThreshold(
@@ -132,10 +132,10 @@ class CostAnnotationWriter : public AssemblyAnnotationWriter {
132132
public:
133133
// This DenseMap stores the delta change in cost and threshold after
134134
// accounting for the given instruction.
135-
DenseMap <const Instruction *, InstructionCostDetail> CostThresholdMap;
135+
DenseMap<const Instruction *, InstructionCostDetail> CostThresholdMap;
136136

137137
virtual void emitInstructionAnnot(const Instruction *I,
138-
formatted_raw_ostream &OS);
138+
formatted_raw_ostream &OS);
139139
};
140140

141141
class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
@@ -590,7 +590,7 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
590590
// This function is called to store the initial cost of inlining before
591591
// the given instruction was assessed.
592592
if (!PrintDebugInstructionDeltas)
593-
return ;
593+
return;
594594
Writer.CostThresholdMap[I].CostBefore = Cost;
595595
Writer.CostThresholdMap[I].ThresholdBefore = Threshold;
596596
}
@@ -599,7 +599,7 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
599599
// This function is called to find new values of cost and threshold after
600600
// the instruction has been assessed.
601601
if (!PrintDebugInstructionDeltas)
602-
return ;
602+
return;
603603
Writer.CostThresholdMap[I].CostAfter = Cost;
604604
Writer.CostThresholdMap[I].ThresholdAfter = Threshold;
605605
}
@@ -727,22 +727,24 @@ void CallAnalyzer::disableSROAForArg(AllocaInst *SROAArg) {
727727
disableLoadElimination();
728728
}
729729

730-
void CostAnnotationWriter::emitInstructionAnnot(
731-
const Instruction *I, formatted_raw_ostream &OS) {
732-
// The cost of inlining of the given instruction is printed always.
733-
// The threshold delta is printed only when it is non-zero. It happens
734-
// when we decided to give a bonus at a particular instruction.
735-
assert(CostThresholdMap.count(I) > 0 &&
736-
"Expected each instruction to have an instruction annotation");
737-
const auto &Record = CostThresholdMap[I];
738-
OS << "; cost before = " << Record.CostBefore
739-
<< ", cost after = " << Record.CostAfter
740-
<< ", threshold before = " << Record.ThresholdBefore
741-
<< ", threshold after = " << Record.ThresholdAfter << ", ";
742-
OS << "cost delta = " << Record.getCostDelta();
743-
if (Record.hasThresholdChanged())
744-
OS << ", threshold delta = " << Record.getThresholdDelta();
745-
OS << "\n";
730+
void CostAnnotationWriter::emitInstructionAnnot(const Instruction *I,
731+
formatted_raw_ostream &OS) {
732+
// The cost of inlining of the given instruction is printed always.
733+
// The threshold delta is printed only when it is non-zero. It happens
734+
// when we decided to give a bonus at a particular instruction.
735+
if (CostThresholdMap.count(I) == 0) {
736+
OS << "; No analysis for the instruction\n";
737+
return;
738+
}
739+
const auto &Record = CostThresholdMap[I];
740+
OS << "; cost before = " << Record.CostBefore
741+
<< ", cost after = " << Record.CostAfter
742+
<< ", threshold before = " << Record.ThresholdBefore
743+
<< ", threshold after = " << Record.ThresholdAfter << ", ";
744+
OS << "cost delta = " << Record.getCostDelta();
745+
if (Record.hasThresholdChanged())
746+
OS << ", threshold delta = " << Record.getThresholdDelta();
747+
OS << "\n";
746748
}
747749

748750
/// If 'V' maps to a SROA candidate, disable SROA for it.
@@ -804,7 +806,8 @@ bool CallAnalyzer::isGEPFree(GetElementPtrInst &GEP) {
804806
else
805807
Operands.push_back(*I);
806808
return TargetTransformInfo::TCC_Free ==
807-
TTI.getUserCost(&GEP, Operands, TargetTransformInfo::TCK_SizeAndLatency);
809+
TTI.getUserCost(&GEP, Operands,
810+
TargetTransformInfo::TCK_SizeAndLatency);
808811
}
809812

810813
bool CallAnalyzer::visitAlloca(AllocaInst &I) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; Require asserts for -debug-only
2+
; REQUIRES: asserts
3+
4+
; This test ensures that the hadling of instructions which were not analyzed by
5+
; '-print-instruction-deltas' flag due to the early exit was done correctly.
6+
7+
; RUN: opt < %s -inline -debug-only=inline-cost -disable-output -print-instruction-deltas -inline-threshold=0 2>&1 | FileCheck %s
8+
9+
; CHECK: No analysis for the instruction
10+
; CHECK: ret void
11+
12+
declare void @callee1()
13+
14+
define void @bar() {
15+
call void @callee1()
16+
ret void
17+
}
18+
19+
define void @foo() {
20+
call void @bar()
21+
ret void
22+
}

0 commit comments

Comments
 (0)