21
21
#include " llvm/Analysis/GlobalsModRef.h"
22
22
#include " llvm/Analysis/IndirectCallPromotionAnalysis.h"
23
23
#include " llvm/Analysis/IndirectCallSiteVisitor.h"
24
+ #include " llvm/Analysis/OptimizationDiagnosticInfo.h"
24
25
#include " llvm/IR/BasicBlock.h"
25
26
#include " llvm/IR/CallSite.h"
26
27
#include " llvm/IR/DerivedTypes.h"
@@ -160,9 +161,7 @@ class ICallPromotionFunc {
160
161
161
162
bool SamplePGO;
162
163
163
- // Test if we can legally promote this direct-call of Target.
164
- bool isPromotionLegal (Instruction *Inst, uint64_t Target, Function *&F,
165
- const char **Reason = nullptr );
164
+ OptimizationRemarkEmitter &ORE;
166
165
167
166
// A struct that records the direct target and it's call count.
168
167
struct PromotionCandidate {
@@ -192,8 +191,8 @@ class ICallPromotionFunc {
192
191
193
192
public:
194
193
ICallPromotionFunc (Function &Func, Module *Modu, InstrProfSymtab *Symtab,
195
- bool SamplePGO)
196
- : F(Func), M(Modu), Symtab(Symtab), SamplePGO(SamplePGO) {}
194
+ bool SamplePGO, OptimizationRemarkEmitter &ORE )
195
+ : F(Func), M(Modu), Symtab(Symtab), SamplePGO(SamplePGO), ORE(ORE) {}
197
196
198
197
bool processFunction ();
199
198
};
@@ -242,17 +241,6 @@ bool llvm::isLegalToPromote(Instruction *Inst, Function *F,
242
241
return true ;
243
242
}
244
243
245
- bool ICallPromotionFunc::isPromotionLegal (Instruction *Inst, uint64_t Target,
246
- Function *&TargetFunction,
247
- const char **Reason) {
248
- TargetFunction = Symtab->getFunction (Target);
249
- if (TargetFunction == nullptr ) {
250
- *Reason = " Cannot find the target" ;
251
- return false ;
252
- }
253
- return isLegalToPromote (Inst, TargetFunction, Reason);
254
- }
255
-
256
244
// Indirect-call promotion heuristic. The direct targets are sorted based on
257
245
// the count. Stop at the first target that is not promoted.
258
246
std::vector<ICallPromotionFunc::PromotionCandidate>
@@ -279,28 +267,41 @@ ICallPromotionFunc::getPromotionCandidatesForCallSite(
279
267
280
268
if (ICPInvokeOnly && dyn_cast<CallInst>(Inst)) {
281
269
DEBUG (dbgs () << " Not promote: User options.\n " );
270
+ ORE.emit (OptimizationRemarkMissed (DEBUG_TYPE, " UserOptions" , Inst)
271
+ << " Not promote: User options" );
282
272
break ;
283
273
}
284
274
if (ICPCallOnly && dyn_cast<InvokeInst>(Inst)) {
285
275
DEBUG (dbgs () << " Not promote: User option.\n " );
276
+ ORE.emit (OptimizationRemarkMissed (DEBUG_TYPE, " UserOptions" , Inst)
277
+ << " Not promote: User options" );
286
278
break ;
287
279
}
288
280
if (ICPCutOff != 0 && NumOfPGOICallPromotion >= ICPCutOff) {
289
281
DEBUG (dbgs () << " Not promote: Cutoff reached.\n " );
282
+ ORE.emit (OptimizationRemarkMissed (DEBUG_TYPE, " CutOffReached" , Inst)
283
+ << " Not promote: Cutoff reached" );
284
+ break ;
285
+ }
286
+
287
+ Function *TargetFunction = Symtab->getFunction (Target);
288
+ if (TargetFunction == nullptr ) {
289
+ DEBUG (dbgs () << " Not promote: Cannot find the target\n " );
290
+ ORE.emit (OptimizationRemarkMissed (DEBUG_TYPE, " UnableToFindTarget" , Inst)
291
+ << " Cannot promote indirect call: target not found" );
290
292
break ;
291
293
}
292
- Function *TargetFunction = nullptr ;
294
+
293
295
const char *Reason = nullptr ;
294
- if (!isPromotionLegal (Inst, Target, TargetFunction, &Reason)) {
295
- StringRef TargetFuncName = Symtab->getFuncName (Target);
296
- DEBUG (dbgs () << " Not promote: " << Reason << " \n " );
297
- emitOptimizationRemarkMissed (
298
- F.getContext (), " pgo-icall-prom" , F, Inst->getDebugLoc (),
299
- Twine (" Cannot promote indirect call to " ) +
300
- (TargetFuncName.empty () ? Twine (Target) : Twine (TargetFuncName)) +
301
- Twine (" with count of " ) + Twine (Count) + " : " + Reason);
296
+ if (!isLegalToPromote (Inst, TargetFunction, &Reason)) {
297
+ using namespace ore ;
298
+ ORE.emit (OptimizationRemarkMissed (DEBUG_TYPE, " UnableToPromote" , Inst)
299
+ << " Cannot promote indirect call to "
300
+ << NV (" TargetFunction" , TargetFunction) << " with count of "
301
+ << NV (" Count" , Count) << " : " << Reason);
302
302
break ;
303
303
}
304
+
304
305
Ret.push_back (PromotionCandidate (TargetFunction, Count));
305
306
TotalCount -= Count;
306
307
}
@@ -532,7 +533,8 @@ static void insertCallRetPHI(Instruction *Inst, Instruction *CallResult,
532
533
Instruction *llvm::promoteIndirectCall (Instruction *Inst,
533
534
Function *DirectCallee, uint64_t Count,
534
535
uint64_t TotalCount,
535
- bool AttachProfToDirectCall) {
536
+ bool AttachProfToDirectCall,
537
+ OptimizationRemarkEmitter *ORE) {
536
538
assert (DirectCallee != nullptr );
537
539
BasicBlock *BB = Inst->getParent ();
538
540
// Just to suppress the non-debug build warning.
@@ -582,10 +584,12 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst,
582
584
DEBUG (dbgs () << " \n == Basic Blocks After ==\n " );
583
585
DEBUG (dbgs () << *BB << *DirectCallBB << *IndirectCallBB << *MergeBB << " \n " );
584
586
585
- emitOptimizationRemark (
586
- BB->getContext (), " pgo-icall-prom" , *BB->getParent (), Inst->getDebugLoc (),
587
- Twine (" Promote indirect call to " ) + DirectCallee->getName () +
588
- " with count " + Twine (Count) + " out of " + Twine (TotalCount));
587
+ using namespace ore ;
588
+ if (ORE)
589
+ ORE->emit (OptimizationRemark (DEBUG_TYPE, " Promoted" , Inst)
590
+ << " Promote indirect call to " << NV (" DirectCallee" , DirectCallee)
591
+ << " with count " << NV (" Count" , Count) << " out of "
592
+ << NV (" TotalCount" , TotalCount));
589
593
return NewInst;
590
594
}
591
595
@@ -597,7 +601,8 @@ uint32_t ICallPromotionFunc::tryToPromote(
597
601
598
602
for (auto &C : Candidates) {
599
603
uint64_t Count = C.Count ;
600
- promoteIndirectCall (Inst, C.TargetFunction , Count, TotalCount, SamplePGO);
604
+ promoteIndirectCall (Inst, C.TargetFunction , Count, TotalCount, SamplePGO,
605
+ &ORE);
601
606
assert (TotalCount >= Count);
602
607
TotalCount -= Count;
603
608
NumOfPGOICallPromotion++;
@@ -638,7 +643,8 @@ bool ICallPromotionFunc::processFunction() {
638
643
}
639
644
640
645
// A wrapper function that does the actual work.
641
- static bool promoteIndirectCalls (Module &M, bool InLTO, bool SamplePGO) {
646
+ static bool promoteIndirectCalls (Module &M, bool InLTO, bool SamplePGO,
647
+ ModuleAnalysisManager *AM = nullptr ) {
642
648
if (DisableICP)
643
649
return false ;
644
650
InstrProfSymtab Symtab;
@@ -654,7 +660,19 @@ static bool promoteIndirectCalls(Module &M, bool InLTO, bool SamplePGO) {
654
660
continue ;
655
661
if (F.hasFnAttribute (Attribute::OptimizeNone))
656
662
continue ;
657
- ICallPromotionFunc ICallPromotion (F, &M, &Symtab, SamplePGO);
663
+
664
+ std::unique_ptr<OptimizationRemarkEmitter> OwnedORE;
665
+ OptimizationRemarkEmitter *ORE;
666
+ if (AM) {
667
+ auto &FAM =
668
+ AM->getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
669
+ ORE = &FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
670
+ } else {
671
+ OwnedORE = make_unique<OptimizationRemarkEmitter>(&F);
672
+ ORE = OwnedORE.get ();
673
+ }
674
+
675
+ ICallPromotionFunc ICallPromotion (F, &M, &Symtab, SamplePGO, *ORE);
658
676
bool FuncChanged = ICallPromotion.processFunction ();
659
677
if (ICPDUMPAFTER && FuncChanged) {
660
678
DEBUG (dbgs () << " \n == IR Dump After ==" ; F.print (dbgs ()));
@@ -677,8 +695,8 @@ bool PGOIndirectCallPromotionLegacyPass::runOnModule(Module &M) {
677
695
678
696
PreservedAnalyses PGOIndirectCallPromotion::run (Module &M,
679
697
ModuleAnalysisManager &AM) {
680
- if (!promoteIndirectCalls (M, InLTO | ICPLTOMode,
681
- SamplePGO | ICPSamplePGOMode ))
698
+ if (!promoteIndirectCalls (M, InLTO | ICPLTOMode, SamplePGO | ICPSamplePGOMode,
699
+ &AM ))
682
700
return PreservedAnalyses::all ();
683
701
684
702
return PreservedAnalyses::none ();
0 commit comments