@@ -1701,13 +1701,16 @@ static void RemoveAttribute(Function *F, Attribute::AttrKind A) {
17011701// / idea here is that we don't want to mess with the convention if the user
17021702// / explicitly requested something with performance implications like coldcc,
17031703// / GHC, or anyregcc.
1704- static bool hasChangeableCC (Function *F) {
1704+ static bool hasChangeableCCImpl (Function *F) {
17051705 CallingConv::ID CC = F->getCallingConv ();
17061706
17071707 // FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
17081708 if (CC != CallingConv::C && CC != CallingConv::X86_ThisCall)
17091709 return false ;
17101710
1711+ if (F->isVarArg ())
1712+ return false ;
1713+
17111714 // FIXME: Change CC for the whole chain of musttail calls when possible.
17121715 //
17131716 // Can't change CC of the function that either has musttail calls, or is a
@@ -1727,7 +1730,16 @@ static bool hasChangeableCC(Function *F) {
17271730 if (BB.getTerminatingMustTailCall ())
17281731 return false ;
17291732
1730- return true ;
1733+ return !F->hasAddressTaken ();
1734+ }
1735+
1736+ using ChangeableCCCacheTy = SmallDenseMap<Function *, bool , 8 >;
1737+ static bool hasChangeableCC (Function *F,
1738+ ChangeableCCCacheTy &ChangeableCCCache) {
1739+ auto Res = ChangeableCCCache.try_emplace (F, false );
1740+ if (Res.second )
1741+ Res.first ->second = hasChangeableCCImpl (F);
1742+ return Res.first ->second ;
17311743}
17321744
17331745// / Return true if the block containing the call site has a BlockFrequency of
@@ -1781,7 +1793,8 @@ static void changeCallSitesToColdCC(Function *F) {
17811793// coldcc calling convention.
17821794static bool
17831795hasOnlyColdCalls (Function &F,
1784- function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
1796+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
1797+ ChangeableCCCacheTy &ChangeableCCCache) {
17851798 for (BasicBlock &BB : F) {
17861799 for (Instruction &I : BB) {
17871800 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
@@ -1800,8 +1813,7 @@ hasOnlyColdCalls(Function &F,
18001813 if (!CalledFn->hasLocalLinkage ())
18011814 return false ;
18021815 // Check if it's valid to use coldcc calling convention.
1803- if (!hasChangeableCC (CalledFn) || CalledFn->isVarArg () ||
1804- CalledFn->hasAddressTaken ())
1816+ if (!hasChangeableCC (CalledFn, ChangeableCCCache))
18051817 return false ;
18061818 BlockFrequencyInfo &CallerBFI = GetBFI (F);
18071819 if (!isColdCallSite (*CI, CallerBFI))
@@ -1931,9 +1943,10 @@ OptimizeFunctions(Module &M,
19311943
19321944 bool Changed = false ;
19331945
1946+ ChangeableCCCacheTy ChangeableCCCache;
19341947 std::vector<Function *> AllCallsCold;
19351948 for (Function &F : llvm::make_early_inc_range (M))
1936- if (hasOnlyColdCalls (F, GetBFI))
1949+ if (hasOnlyColdCalls (F, GetBFI, ChangeableCCCache ))
19371950 AllCallsCold.push_back (&F);
19381951
19391952 // Optimize functions.
@@ -1995,7 +2008,7 @@ OptimizeFunctions(Module &M,
19952008 continue ;
19962009 }
19972010
1998- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2011+ if (hasChangeableCC (&F, ChangeableCCCache )) {
19992012 NumInternalFunc++;
20002013 TargetTransformInfo &TTI = GetTTI (F);
20012014 // Change the calling convention to coldcc if either stress testing is
@@ -2005,14 +2018,15 @@ OptimizeFunctions(Module &M,
20052018 if (EnableColdCCStressTest ||
20062019 (TTI.useColdCCForColdCall (F) &&
20072020 isValidCandidateForColdCC (F, GetBFI, AllCallsCold))) {
2021+ ChangeableCCCache.erase (&F);
20082022 F.setCallingConv (CallingConv::Cold);
20092023 changeCallSitesToColdCC (&F);
20102024 Changed = true ;
20112025 NumColdCC++;
20122026 }
20132027 }
20142028
2015- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2029+ if (hasChangeableCC (&F, ChangeableCCCache )) {
20162030 // If this function has a calling convention worth changing, is not a
20172031 // varargs function, and is only called directly, promote it to use the
20182032 // Fast calling convention.
0 commit comments