Skip to content

Commit a0aa5b3

Browse files
author
Jessica Paquette
committedSep 6, 2018
Output per-function size-info remarks
This patch adds per-function size information remarks. Previously, passing -Rpass-analysis=size-info would only give you per-module changes. By adding the ability to do this per-function, it's easier to see which functions contributed the most to size changes. https://reviews.llvm.org/D51467 llvm-svn: 341588
1 parent b23648c commit a0aa5b3

File tree

5 files changed

+250
-26
lines changed

5 files changed

+250
-26
lines changed
 

‎llvm/include/llvm/IR/LegacyPassManagers.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -406,14 +406,23 @@ class PMDataManager {
406406
/// Set the initial size of the module if the user has specified that they
407407
/// want remarks for size.
408408
/// Returns 0 if the remark was not requested.
409-
unsigned initSizeRemarkInfo(Module &M);
409+
unsigned initSizeRemarkInfo(
410+
Module &M,
411+
StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount);
410412

411413
/// Emit a remark signifying that the number of IR instructions in the module
412414
/// changed.
413415
/// \p F is optionally passed by passes which run on Functions, and thus
414416
/// always know whether or not a non-empty function is available.
415-
void emitInstrCountChangedRemark(Pass *P, Module &M, int64_t Delta,
416-
unsigned CountBefore, Function *F = nullptr);
417+
///
418+
/// \p FunctionToInstrCount maps the name of a \p Function to a pair. The
419+
/// first member of the pair is the IR count of the \p Function before running
420+
/// \p P, and the second member is the IR count of the \p Function after
421+
/// running \p P.
422+
void emitInstrCountChangedRemark(
423+
Pass *P, Module &M, int64_t Delta, unsigned CountBefore,
424+
StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount,
425+
Function *F = nullptr);
417426

418427
protected:
419428
// Top level manager.

‎llvm/lib/Analysis/CallGraphSCCPass.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,11 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
132132

133133
{
134134
unsigned InstrCount, SCCCount = 0;
135+
StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
135136
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
136137
TimeRegion PassTimer(getPassTimer(CGSP));
137138
if (EmitICRemark)
138-
InstrCount = initSizeRemarkInfo(M);
139+
InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
139140
Changed = CGSP->runOnSCC(CurSCC);
140141

141142
if (EmitICRemark) {
@@ -146,7 +147,8 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
146147
// Yep. Emit a remark and update InstrCount.
147148
int64_t Delta =
148149
static_cast<int64_t>(SCCCount) - static_cast<int64_t>(InstrCount);
149-
emitInstrCountChangedRemark(P, M, Delta, InstrCount);
150+
emitInstrCountChangedRemark(P, M, Delta, InstrCount,
151+
FunctionToInstrCount);
150152
InstrCount = SCCCount;
151153
}
152154
}

‎llvm/lib/Analysis/LoopPass.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,11 @@ bool LPPassManager::runOnFunction(Function &F) {
195195

196196
// Walk Loops
197197
unsigned InstrCount, FunctionSize = 0;
198+
StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
198199
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
199200
// Collect the initial size of the module and the function we're looking at.
200201
if (EmitICRemark) {
201-
InstrCount = initSizeRemarkInfo(M);
202+
InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
202203
FunctionSize = F.getInstructionCount();
203204
}
204205
while (!LQ.empty()) {
@@ -226,7 +227,8 @@ bool LPPassManager::runOnFunction(Function &F) {
226227
if (NewSize != FunctionSize) {
227228
int64_t Delta = static_cast<int64_t>(NewSize) -
228229
static_cast<int64_t>(FunctionSize);
229-
emitInstrCountChangedRemark(P, M, Delta, InstrCount, &F);
230+
emitInstrCountChangedRemark(P, M, Delta, InstrCount,
231+
FunctionToInstrCount, &F);
230232
InstrCount = static_cast<int64_t>(InstrCount) + Delta;
231233
FunctionSize = NewSize;
232234
}

‎llvm/lib/IR/LegacyPassManager.cpp

+111-12
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,32 @@ bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
136136
return PassDebugging >= Executions;
137137
}
138138

139-
unsigned PMDataManager::initSizeRemarkInfo(Module &M) {
139+
unsigned PMDataManager::initSizeRemarkInfo(
140+
Module &M, StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount) {
140141
// Only calculate getInstructionCount if the size-info remark is requested.
141-
return M.getInstructionCount();
142+
unsigned InstrCount = 0;
143+
144+
// Collect instruction counts for every function. We'll use this to emit
145+
// per-function size remarks later.
146+
for (Function &F : M) {
147+
unsigned FCount = F.getInstructionCount();
148+
149+
// Insert a record into FunctionToInstrCount keeping track of the current
150+
// size of the function as the first member of a pair. Set the second
151+
// member to 0; if the function is deleted by the pass, then when we get
152+
// here, we'll be able to let the user know that F no longer contributes to
153+
// the module.
154+
FunctionToInstrCount[F.getName().str()] =
155+
std::pair<unsigned, unsigned>(FCount, 0);
156+
InstrCount += FCount;
157+
}
158+
return InstrCount;
142159
}
143160

144-
void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M,
145-
int64_t Delta,
146-
unsigned CountBefore,
147-
Function *F) {
161+
void PMDataManager::emitInstrCountChangedRemark(
162+
Pass *P, Module &M, int64_t Delta, unsigned CountBefore,
163+
StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount,
164+
Function *F) {
148165
// If it's a pass manager, don't emit a remark. (This hinges on the assumption
149166
// that the only passes that return non-null with getAsPMDataManager are pass
150167
// managers.) The reason we have to do this is to avoid emitting remarks for
@@ -155,6 +172,33 @@ void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M,
155172
// Set to true if this isn't a module pass or CGSCC pass.
156173
bool CouldOnlyImpactOneFunction = (F != nullptr);
157174

175+
// Helper lambda that updates the changes to the size of some function.
176+
auto UpdateFunctionChanges =
177+
[&FunctionToInstrCount](Function &MaybeChangedFn) {
178+
// Update the total module count.
179+
unsigned FnSize = MaybeChangedFn.getInstructionCount();
180+
auto It = FunctionToInstrCount.find(MaybeChangedFn.getName());
181+
182+
// If we created a new function, then we need to add it to the map and
183+
// say that it changed from 0 instructions to FnSize.
184+
if (It == FunctionToInstrCount.end()) {
185+
FunctionToInstrCount[MaybeChangedFn.getName()] =
186+
std::pair<unsigned, unsigned>(0, FnSize);
187+
return;
188+
}
189+
// Insert the new function size into the second member of the pair. This
190+
// tells us whether or not this function changed in size.
191+
It->second.second = FnSize;
192+
};
193+
194+
// We need to initially update all of the function sizes.
195+
// If no function was passed in, then we're either a module pass or an
196+
// CGSCC pass.
197+
if (!CouldOnlyImpactOneFunction)
198+
std::for_each(M.begin(), M.end(), UpdateFunctionChanges);
199+
else
200+
UpdateFunctionChanges(*F);
201+
158202
// Do we have a function we can use to emit a remark?
159203
if (!CouldOnlyImpactOneFunction) {
160204
// We need a function containing at least one basic block in order to output
@@ -185,6 +229,55 @@ void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M,
185229
<< "; Delta: "
186230
<< DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", Delta);
187231
F->getContext().diagnose(R); // Not using ORE for layering reasons.
232+
233+
// Emit per-function size change remarks separately.
234+
std::string PassName = P->getPassName().str();
235+
236+
// Helper lambda that emits a remark when the size of a function has changed.
237+
auto EmitFunctionSizeChangedRemark = [&FunctionToInstrCount, &F, &BB,
238+
&PassName](const std::string &Fname) {
239+
unsigned FnCountBefore, FnCountAfter;
240+
std::pair<unsigned, unsigned> &Change = FunctionToInstrCount[Fname];
241+
std::tie(FnCountBefore, FnCountAfter) = Change;
242+
int64_t FnDelta = static_cast<int64_t>(FnCountAfter) -
243+
static_cast<int64_t>(FnCountBefore);
244+
245+
if (FnDelta == 0)
246+
return;
247+
248+
// FIXME: We shouldn't use BB for the location here. Unfortunately, because
249+
// the function that we're looking at could have been deleted, we can't use
250+
// it for the source location. We *want* remarks when a function is deleted
251+
// though, so we're kind of stuck here as is. (This remark, along with the
252+
// whole-module size change remarks really ought not to have source
253+
// locations at all.)
254+
OptimizationRemarkAnalysis FR("size-info", "FunctionIRSizeChange",
255+
DiagnosticLocation(), &BB);
256+
FR << DiagnosticInfoOptimizationBase::Argument("Pass", PassName)
257+
<< ": Function: "
258+
<< DiagnosticInfoOptimizationBase::Argument("Function", Fname)
259+
<< ": IR instruction count changed from "
260+
<< DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore",
261+
FnCountBefore)
262+
<< " to "
263+
<< DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter",
264+
FnCountAfter)
265+
<< "; Delta: "
266+
<< DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", FnDelta);
267+
F->getContext().diagnose(FR);
268+
269+
// Update the function size.
270+
Change.first = FnCountAfter;
271+
};
272+
273+
// Are we looking at more than one function? If so, emit remarks for all of
274+
// the functions in the module. Otherwise, only emit one remark.
275+
if (!CouldOnlyImpactOneFunction)
276+
std::for_each(FunctionToInstrCount.keys().begin(),
277+
FunctionToInstrCount.keys().end(),
278+
EmitFunctionSizeChangedRemark);
279+
else
280+
EmitFunctionSizeChangedRemark(F->getName().str());
188281
}
189282

190283
void PassManagerPrettyStackEntry::print(raw_ostream &OS) const {
@@ -1284,9 +1377,10 @@ bool BBPassManager::runOnFunction(Function &F) {
12841377
Module &M = *F.getParent();
12851378

12861379
unsigned InstrCount, BBSize = 0;
1380+
StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
12871381
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
12881382
if (EmitICRemark)
1289-
InstrCount = initSizeRemarkInfo(M);
1383+
InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
12901384

12911385
for (BasicBlock &BB : F) {
12921386
// Collect the initial size of the basic block.
@@ -1313,7 +1407,8 @@ bool BBPassManager::runOnFunction(Function &F) {
13131407
if (NewSize != BBSize) {
13141408
int64_t Delta =
13151409
static_cast<int64_t>(NewSize) - static_cast<int64_t>(BBSize);
1316-
emitInstrCountChangedRemark(BP, M, Delta, InstrCount, &F);
1410+
emitInstrCountChangedRemark(BP, M, Delta, InstrCount,
1411+
FunctionToInstrCount, &F);
13171412
InstrCount = static_cast<int64_t>(InstrCount) + Delta;
13181413
BBSize = NewSize;
13191414
}
@@ -1522,10 +1617,11 @@ bool FPPassManager::runOnFunction(Function &F) {
15221617
populateInheritedAnalysis(TPM->activeStack);
15231618

15241619
unsigned InstrCount, FunctionSize = 0;
1620+
StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
15251621
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
15261622
// Collect the initial size of the module.
15271623
if (EmitICRemark) {
1528-
InstrCount = initSizeRemarkInfo(M);
1624+
InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
15291625
FunctionSize = F.getInstructionCount();
15301626
}
15311627

@@ -1550,7 +1646,8 @@ bool FPPassManager::runOnFunction(Function &F) {
15501646
if (NewSize != FunctionSize) {
15511647
int64_t Delta = static_cast<int64_t>(NewSize) -
15521648
static_cast<int64_t>(FunctionSize);
1553-
emitInstrCountChangedRemark(FP, M, Delta, InstrCount, &F);
1649+
emitInstrCountChangedRemark(FP, M, Delta, InstrCount,
1650+
FunctionToInstrCount, &F);
15541651
InstrCount = static_cast<int64_t>(InstrCount) + Delta;
15551652
FunctionSize = NewSize;
15561653
}
@@ -1619,10 +1716,11 @@ MPPassManager::runOnModule(Module &M) {
16191716
Changed |= getContainedPass(Index)->doInitialization(M);
16201717

16211718
unsigned InstrCount, ModuleCount = 0;
1719+
StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
16221720
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
16231721
// Collect the initial size of the module.
16241722
if (EmitICRemark) {
1625-
InstrCount = initSizeRemarkInfo(M);
1723+
InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
16261724
ModuleCount = InstrCount;
16271725
}
16281726

@@ -1646,7 +1744,8 @@ MPPassManager::runOnModule(Module &M) {
16461744
if (ModuleCount != InstrCount) {
16471745
int64_t Delta = static_cast<int64_t>(ModuleCount) -
16481746
static_cast<int64_t>(InstrCount);
1649-
emitInstrCountChangedRemark(MP, M, Delta, InstrCount);
1747+
emitInstrCountChangedRemark(MP, M, Delta, InstrCount,
1748+
FunctionToInstrCount);
16501749
InstrCount = ModuleCount;
16511750
}
16521751
}

0 commit comments

Comments
 (0)
Please sign in to comment.