60
60
#include " llvm/Analysis/InlineCost.h"
61
61
#include " llvm/Analysis/InstructionSimplify.h"
62
62
#include " llvm/Analysis/Loads.h"
63
+ #include " llvm/Analysis/OptimizationDiagnosticInfo.h"
63
64
#include " llvm/Analysis/TargetTransformInfo.h"
64
65
#include " llvm/IR/CFG.h"
65
66
#include " llvm/IR/CallSite.h"
@@ -177,7 +178,8 @@ struct AllocaDerivedValueTracker {
177
178
};
178
179
}
179
180
180
- static bool markTails (Function &F, bool &AllCallsAreTailCalls) {
181
+ static bool markTails (Function &F, bool &AllCallsAreTailCalls,
182
+ OptimizationRemarkEmitter *ORE) {
181
183
if (F.callsFunctionThatReturnsTwice ())
182
184
return false ;
183
185
AllCallsAreTailCalls = true ;
@@ -252,9 +254,9 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls) {
252
254
break ;
253
255
}
254
256
if (SafeToTail) {
255
- emitOptimizationRemark (
256
- F. getContext () , " tailcallelim " , F, CI-> getDebugLoc (),
257
- " marked this readnone call a tail call candidate" );
257
+ using namespace ore ;
258
+ ORE-> emit ( OptimizationRemark (DEBUG_TYPE , " tailcall-readnone " , CI)
259
+ << " marked as tail call candidate (readnone) " );
258
260
CI->setTailCall ();
259
261
Modified = true ;
260
262
continue ;
@@ -299,9 +301,8 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls) {
299
301
if (Visited[CI->getParent ()] != ESCAPED) {
300
302
// If the escape point was part way through the block, calls after the
301
303
// escape point wouldn't have been put into DeferredTails.
302
- emitOptimizationRemark (F.getContext (), " tailcallelim" , F,
303
- CI->getDebugLoc (),
304
- " marked this call a tail call candidate" );
304
+ ORE->emit (OptimizationRemark (DEBUG_TYPE, " tailcall" , CI)
305
+ << " marked as tail call candidate" );
305
306
CI->setTailCall ();
306
307
Modified = true ;
307
308
} else {
@@ -491,7 +492,8 @@ static bool eliminateRecursiveTailCall(CallInst *CI, ReturnInst *Ret,
491
492
BasicBlock *&OldEntry,
492
493
bool &TailCallsAreMarkedTail,
493
494
SmallVectorImpl<PHINode *> &ArgumentPHIs,
494
- AliasAnalysis *AA) {
495
+ AliasAnalysis *AA,
496
+ OptimizationRemarkEmitter *ORE) {
495
497
// If we are introducing accumulator recursion to eliminate operations after
496
498
// the call instruction that are both associative and commutative, the initial
497
499
// value for the accumulator is placed in this variable. If this value is set
@@ -551,8 +553,9 @@ static bool eliminateRecursiveTailCall(CallInst *CI, ReturnInst *Ret,
551
553
BasicBlock *BB = Ret->getParent ();
552
554
Function *F = BB->getParent ();
553
555
554
- emitOptimizationRemark (F->getContext (), " tailcallelim" , *F, CI->getDebugLoc (),
555
- " transforming tail recursion to loop" );
556
+ using namespace ore ;
557
+ ORE->emit (OptimizationRemark (DEBUG_TYPE, " tailcall-recursion" , CI)
558
+ << " transforming tail recursion into loop" );
556
559
557
560
// OK! We can transform this tail call. If this is the first one found,
558
561
// create the new entry block, allowing us to branch back to the old entry.
@@ -666,13 +669,11 @@ static bool eliminateRecursiveTailCall(CallInst *CI, ReturnInst *Ret,
666
669
return true ;
667
670
}
668
671
669
- static bool foldReturnAndProcessPred (BasicBlock *BB, ReturnInst *Ret,
670
- BasicBlock *&OldEntry,
671
- bool &TailCallsAreMarkedTail,
672
- SmallVectorImpl<PHINode *> &ArgumentPHIs,
673
- bool CannotTailCallElimCallsMarkedTail,
674
- const TargetTransformInfo *TTI,
675
- AliasAnalysis *AA) {
672
+ static bool foldReturnAndProcessPred (
673
+ BasicBlock *BB, ReturnInst *Ret, BasicBlock *&OldEntry,
674
+ bool &TailCallsAreMarkedTail, SmallVectorImpl<PHINode *> &ArgumentPHIs,
675
+ bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI,
676
+ AliasAnalysis *AA, OptimizationRemarkEmitter *ORE) {
676
677
bool Change = false ;
677
678
678
679
// Make sure this block is a trivial return block.
@@ -708,7 +709,7 @@ static bool foldReturnAndProcessPred(BasicBlock *BB, ReturnInst *Ret,
708
709
BB->eraseFromParent ();
709
710
710
711
eliminateRecursiveTailCall (CI, RI, OldEntry, TailCallsAreMarkedTail,
711
- ArgumentPHIs, AA);
712
+ ArgumentPHIs, AA, ORE );
712
713
++NumRetDuped;
713
714
Change = true ;
714
715
}
@@ -722,23 +723,25 @@ static bool processReturningBlock(ReturnInst *Ret, BasicBlock *&OldEntry,
722
723
SmallVectorImpl<PHINode *> &ArgumentPHIs,
723
724
bool CannotTailCallElimCallsMarkedTail,
724
725
const TargetTransformInfo *TTI,
725
- AliasAnalysis *AA) {
726
+ AliasAnalysis *AA,
727
+ OptimizationRemarkEmitter *ORE) {
726
728
CallInst *CI = findTRECandidate (Ret, CannotTailCallElimCallsMarkedTail, TTI);
727
729
if (!CI)
728
730
return false ;
729
731
730
732
return eliminateRecursiveTailCall (CI, Ret, OldEntry, TailCallsAreMarkedTail,
731
- ArgumentPHIs, AA);
733
+ ArgumentPHIs, AA, ORE );
732
734
}
733
735
734
736
static bool eliminateTailRecursion (Function &F, const TargetTransformInfo *TTI,
735
- AliasAnalysis *AA) {
737
+ AliasAnalysis *AA,
738
+ OptimizationRemarkEmitter *ORE) {
736
739
if (F.getFnAttribute (" disable-tail-calls" ).getValueAsString () == " true" )
737
740
return false ;
738
741
739
742
bool MadeChange = false ;
740
743
bool AllCallsAreTailCalls = false ;
741
- MadeChange |= markTails (F, AllCallsAreTailCalls);
744
+ MadeChange |= markTails (F, AllCallsAreTailCalls, ORE );
742
745
if (!AllCallsAreTailCalls)
743
746
return MadeChange;
744
747
@@ -765,13 +768,13 @@ static bool eliminateTailRecursion(Function &F, const TargetTransformInfo *TTI,
765
768
for (Function::iterator BBI = F.begin (), E = F.end (); BBI != E; /* in loop*/ ) {
766
769
BasicBlock *BB = &*BBI++; // foldReturnAndProcessPred may delete BB.
767
770
if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator ())) {
768
- bool Change =
769
- processReturningBlock (Ret, OldEntry, TailCallsAreMarkedTail ,
770
- ArgumentPHIs, !CanTRETailMarkedCall, TTI, AA);
771
+ bool Change = processReturningBlock (Ret, OldEntry, TailCallsAreMarkedTail,
772
+ ArgumentPHIs, !CanTRETailMarkedCall ,
773
+ TTI, AA, ORE );
771
774
if (!Change && BB->getFirstNonPHIOrDbg () == Ret)
772
775
Change = foldReturnAndProcessPred (BB, Ret, OldEntry,
773
776
TailCallsAreMarkedTail, ArgumentPHIs,
774
- !CanTRETailMarkedCall, TTI, AA);
777
+ !CanTRETailMarkedCall, TTI, AA, ORE );
775
778
MadeChange |= Change;
776
779
}
777
780
}
@@ -802,6 +805,7 @@ struct TailCallElim : public FunctionPass {
802
805
void getAnalysisUsage (AnalysisUsage &AU) const override {
803
806
AU.addRequired <TargetTransformInfoWrapperPass>();
804
807
AU.addRequired <AAResultsWrapperPass>();
808
+ AU.addRequired <OptimizationRemarkEmitterWrapperPass>();
805
809
AU.addPreserved <GlobalsAAWrapperPass>();
806
810
}
807
811
@@ -811,7 +815,8 @@ struct TailCallElim : public FunctionPass {
811
815
812
816
return eliminateTailRecursion (
813
817
F, &getAnalysis<TargetTransformInfoWrapperPass>().getTTI (F),
814
- &getAnalysis<AAResultsWrapperPass>().getAAResults ());
818
+ &getAnalysis<AAResultsWrapperPass>().getAAResults (),
819
+ &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE ());
815
820
}
816
821
};
817
822
}
@@ -820,6 +825,7 @@ char TailCallElim::ID = 0;
820
825
INITIALIZE_PASS_BEGIN (TailCallElim, " tailcallelim" , " Tail Call Elimination" ,
821
826
false , false )
822
827
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
828
+ INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
823
829
INITIALIZE_PASS_END(TailCallElim, " tailcallelim" , " Tail Call Elimination" ,
824
830
false , false )
825
831
@@ -833,8 +839,9 @@ PreservedAnalyses TailCallElimPass::run(Function &F,
833
839
834
840
TargetTransformInfo &TTI = AM.getResult <TargetIRAnalysis>(F);
835
841
AliasAnalysis &AA = AM.getResult <AAManager>(F);
842
+ auto &ORE = AM.getResult <OptimizationRemarkEmitterAnalysis>(F);
836
843
837
- bool Changed = eliminateTailRecursion (F, &TTI, &AA);
844
+ bool Changed = eliminateTailRecursion (F, &TTI, &AA, &ORE );
838
845
839
846
if (!Changed)
840
847
return PreservedAnalyses::all ();
0 commit comments