@@ -136,15 +136,32 @@ bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
136
136
return PassDebugging >= Executions;
137
137
}
138
138
139
- unsigned PMDataManager::initSizeRemarkInfo (Module &M) {
139
+ unsigned PMDataManager::initSizeRemarkInfo (
140
+ Module &M, StringMap<std::pair<unsigned , unsigned >> &FunctionToInstrCount) {
140
141
// 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;
142
159
}
143
160
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) {
148
165
// If it's a pass manager, don't emit a remark. (This hinges on the assumption
149
166
// that the only passes that return non-null with getAsPMDataManager are pass
150
167
// 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,
155
172
// Set to true if this isn't a module pass or CGSCC pass.
156
173
bool CouldOnlyImpactOneFunction = (F != nullptr );
157
174
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
+
158
202
// Do we have a function we can use to emit a remark?
159
203
if (!CouldOnlyImpactOneFunction) {
160
204
// 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,
185
229
<< " ; Delta: "
186
230
<< DiagnosticInfoOptimizationBase::Argument (" DeltaInstrCount" , Delta);
187
231
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 ());
188
281
}
189
282
190
283
void PassManagerPrettyStackEntry::print (raw_ostream &OS) const {
@@ -1284,9 +1377,10 @@ bool BBPassManager::runOnFunction(Function &F) {
1284
1377
Module &M = *F.getParent ();
1285
1378
1286
1379
unsigned InstrCount, BBSize = 0 ;
1380
+ StringMap<std::pair<unsigned , unsigned >> FunctionToInstrCount;
1287
1381
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark ();
1288
1382
if (EmitICRemark)
1289
- InstrCount = initSizeRemarkInfo (M);
1383
+ InstrCount = initSizeRemarkInfo (M, FunctionToInstrCount );
1290
1384
1291
1385
for (BasicBlock &BB : F) {
1292
1386
// Collect the initial size of the basic block.
@@ -1313,7 +1407,8 @@ bool BBPassManager::runOnFunction(Function &F) {
1313
1407
if (NewSize != BBSize) {
1314
1408
int64_t Delta =
1315
1409
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);
1317
1412
InstrCount = static_cast <int64_t >(InstrCount) + Delta;
1318
1413
BBSize = NewSize;
1319
1414
}
@@ -1522,10 +1617,11 @@ bool FPPassManager::runOnFunction(Function &F) {
1522
1617
populateInheritedAnalysis (TPM->activeStack );
1523
1618
1524
1619
unsigned InstrCount, FunctionSize = 0 ;
1620
+ StringMap<std::pair<unsigned , unsigned >> FunctionToInstrCount;
1525
1621
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark ();
1526
1622
// Collect the initial size of the module.
1527
1623
if (EmitICRemark) {
1528
- InstrCount = initSizeRemarkInfo (M);
1624
+ InstrCount = initSizeRemarkInfo (M, FunctionToInstrCount );
1529
1625
FunctionSize = F.getInstructionCount ();
1530
1626
}
1531
1627
@@ -1550,7 +1646,8 @@ bool FPPassManager::runOnFunction(Function &F) {
1550
1646
if (NewSize != FunctionSize) {
1551
1647
int64_t Delta = static_cast <int64_t >(NewSize) -
1552
1648
static_cast <int64_t >(FunctionSize);
1553
- emitInstrCountChangedRemark (FP, M, Delta, InstrCount, &F);
1649
+ emitInstrCountChangedRemark (FP, M, Delta, InstrCount,
1650
+ FunctionToInstrCount, &F);
1554
1651
InstrCount = static_cast <int64_t >(InstrCount) + Delta;
1555
1652
FunctionSize = NewSize;
1556
1653
}
@@ -1619,10 +1716,11 @@ MPPassManager::runOnModule(Module &M) {
1619
1716
Changed |= getContainedPass (Index)->doInitialization (M);
1620
1717
1621
1718
unsigned InstrCount, ModuleCount = 0 ;
1719
+ StringMap<std::pair<unsigned , unsigned >> FunctionToInstrCount;
1622
1720
bool EmitICRemark = M.shouldEmitInstrCountChangedRemark ();
1623
1721
// Collect the initial size of the module.
1624
1722
if (EmitICRemark) {
1625
- InstrCount = initSizeRemarkInfo (M);
1723
+ InstrCount = initSizeRemarkInfo (M, FunctionToInstrCount );
1626
1724
ModuleCount = InstrCount;
1627
1725
}
1628
1726
@@ -1646,7 +1744,8 @@ MPPassManager::runOnModule(Module &M) {
1646
1744
if (ModuleCount != InstrCount) {
1647
1745
int64_t Delta = static_cast <int64_t >(ModuleCount) -
1648
1746
static_cast <int64_t >(InstrCount);
1649
- emitInstrCountChangedRemark (MP, M, Delta, InstrCount);
1747
+ emitInstrCountChangedRemark (MP, M, Delta, InstrCount,
1748
+ FunctionToInstrCount);
1650
1749
InstrCount = ModuleCount;
1651
1750
}
1652
1751
}
0 commit comments