@@ -1701,13 +1701,16 @@ static void RemoveAttribute(Function *F, Attribute::AttrKind A) {
1701
1701
// / idea here is that we don't want to mess with the convention if the user
1702
1702
// / explicitly requested something with performance implications like coldcc,
1703
1703
// / GHC, or anyregcc.
1704
- static bool hasChangeableCC (Function *F) {
1704
+ static bool hasChangeableCCImpl (Function *F) {
1705
1705
CallingConv::ID CC = F->getCallingConv ();
1706
1706
1707
1707
// FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
1708
1708
if (CC != CallingConv::C && CC != CallingConv::X86_ThisCall)
1709
1709
return false ;
1710
1710
1711
+ if (F->isVarArg ())
1712
+ return false ;
1713
+
1711
1714
// FIXME: Change CC for the whole chain of musttail calls when possible.
1712
1715
//
1713
1716
// Can't change CC of the function that either has musttail calls, or is a
@@ -1727,7 +1730,16 @@ static bool hasChangeableCC(Function *F) {
1727
1730
if (BB.getTerminatingMustTailCall ())
1728
1731
return false ;
1729
1732
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 ;
1731
1743
}
1732
1744
1733
1745
// / Return true if the block containing the call site has a BlockFrequency of
@@ -1781,7 +1793,8 @@ static void changeCallSitesToColdCC(Function *F) {
1781
1793
// coldcc calling convention.
1782
1794
static bool
1783
1795
hasOnlyColdCalls (Function &F,
1784
- function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
1796
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
1797
+ ChangeableCCCacheTy &ChangeableCCCache) {
1785
1798
for (BasicBlock &BB : F) {
1786
1799
for (Instruction &I : BB) {
1787
1800
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
@@ -1800,8 +1813,7 @@ hasOnlyColdCalls(Function &F,
1800
1813
if (!CalledFn->hasLocalLinkage ())
1801
1814
return false ;
1802
1815
// Check if it's valid to use coldcc calling convention.
1803
- if (!hasChangeableCC (CalledFn) || CalledFn->isVarArg () ||
1804
- CalledFn->hasAddressTaken ())
1816
+ if (!hasChangeableCC (CalledFn, ChangeableCCCache))
1805
1817
return false ;
1806
1818
BlockFrequencyInfo &CallerBFI = GetBFI (F);
1807
1819
if (!isColdCallSite (*CI, CallerBFI))
@@ -1931,9 +1943,10 @@ OptimizeFunctions(Module &M,
1931
1943
1932
1944
bool Changed = false ;
1933
1945
1946
+ ChangeableCCCacheTy ChangeableCCCache;
1934
1947
std::vector<Function *> AllCallsCold;
1935
1948
for (Function &F : llvm::make_early_inc_range (M))
1936
- if (hasOnlyColdCalls (F, GetBFI))
1949
+ if (hasOnlyColdCalls (F, GetBFI, ChangeableCCCache ))
1937
1950
AllCallsCold.push_back (&F);
1938
1951
1939
1952
// Optimize functions.
@@ -1995,7 +2008,7 @@ OptimizeFunctions(Module &M,
1995
2008
continue ;
1996
2009
}
1997
2010
1998
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2011
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
1999
2012
NumInternalFunc++;
2000
2013
TargetTransformInfo &TTI = GetTTI (F);
2001
2014
// Change the calling convention to coldcc if either stress testing is
@@ -2005,14 +2018,15 @@ OptimizeFunctions(Module &M,
2005
2018
if (EnableColdCCStressTest ||
2006
2019
(TTI.useColdCCForColdCall (F) &&
2007
2020
isValidCandidateForColdCC (F, GetBFI, AllCallsCold))) {
2021
+ ChangeableCCCache.erase (&F);
2008
2022
F.setCallingConv (CallingConv::Cold);
2009
2023
changeCallSitesToColdCC (&F);
2010
2024
Changed = true ;
2011
2025
NumColdCC++;
2012
2026
}
2013
2027
}
2014
2028
2015
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2029
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
2016
2030
// If this function has a calling convention worth changing, is not a
2017
2031
// varargs function, and is only called directly, promote it to use the
2018
2032
// Fast calling convention.
0 commit comments