@@ -1680,13 +1680,16 @@ static void RemoveAttribute(Function *F, Attribute::AttrKind A) {
1680
1680
// / idea here is that we don't want to mess with the convention if the user
1681
1681
// / explicitly requested something with performance implications like coldcc,
1682
1682
// / GHC, or anyregcc.
1683
- static bool hasChangeableCC (Function *F) {
1683
+ static bool hasChangeableCCImpl (Function *F) {
1684
1684
CallingConv::ID CC = F->getCallingConv ();
1685
1685
1686
1686
// FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
1687
1687
if (CC != CallingConv::C && CC != CallingConv::X86_ThisCall)
1688
1688
return false ;
1689
1689
1690
+ if (F->isVarArg ())
1691
+ return false ;
1692
+
1690
1693
// FIXME: Change CC for the whole chain of musttail calls when possible.
1691
1694
//
1692
1695
// Can't change CC of the function that either has musttail calls, or is a
@@ -1706,7 +1709,16 @@ static bool hasChangeableCC(Function *F) {
1706
1709
if (BB.getTerminatingMustTailCall ())
1707
1710
return false ;
1708
1711
1709
- return true ;
1712
+ return !F->hasAddressTaken ();
1713
+ }
1714
+
1715
+ using ChangeableCCCacheTy = SmallDenseMap<Function *, bool , 8 >;
1716
+ static bool hasChangeableCC (Function *F,
1717
+ ChangeableCCCacheTy &ChangeableCCCache) {
1718
+ auto Res = ChangeableCCCache.try_emplace (F, false );
1719
+ if (Res.second )
1720
+ Res.first ->second = hasChangeableCCImpl (F);
1721
+ return Res.first ->second ;
1710
1722
}
1711
1723
1712
1724
// / Return true if the block containing the call site has a BlockFrequency of
@@ -1760,7 +1772,8 @@ static void changeCallSitesToColdCC(Function *F) {
1760
1772
// coldcc calling convention.
1761
1773
static bool
1762
1774
hasOnlyColdCalls (Function &F,
1763
- function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
1775
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
1776
+ ChangeableCCCacheTy &ChangeableCCCache) {
1764
1777
for (BasicBlock &BB : F) {
1765
1778
for (Instruction &I : BB) {
1766
1779
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
@@ -1779,8 +1792,7 @@ hasOnlyColdCalls(Function &F,
1779
1792
if (!CalledFn->hasLocalLinkage ())
1780
1793
return false ;
1781
1794
// Check if it's valid to use coldcc calling convention.
1782
- if (!hasChangeableCC (CalledFn) || CalledFn->isVarArg () ||
1783
- CalledFn->hasAddressTaken ())
1795
+ if (!hasChangeableCC (CalledFn, ChangeableCCCache))
1784
1796
return false ;
1785
1797
BlockFrequencyInfo &CallerBFI = GetBFI (F);
1786
1798
if (!isColdCallSite (*CI, CallerBFI))
@@ -1905,9 +1917,10 @@ OptimizeFunctions(Module &M,
1905
1917
1906
1918
bool Changed = false ;
1907
1919
1920
+ ChangeableCCCacheTy ChangeableCCCache;
1908
1921
std::vector<Function *> AllCallsCold;
1909
1922
for (Function &F : llvm::make_early_inc_range (M))
1910
- if (hasOnlyColdCalls (F, GetBFI))
1923
+ if (hasOnlyColdCalls (F, GetBFI, ChangeableCCCache ))
1911
1924
AllCallsCold.push_back (&F);
1912
1925
1913
1926
// Optimize functions.
@@ -1969,7 +1982,7 @@ OptimizeFunctions(Module &M,
1969
1982
continue ;
1970
1983
}
1971
1984
1972
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
1985
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
1973
1986
NumInternalFunc++;
1974
1987
TargetTransformInfo &TTI = GetTTI (F);
1975
1988
// Change the calling convention to coldcc if either stress testing is
@@ -1979,14 +1992,15 @@ OptimizeFunctions(Module &M,
1979
1992
if (EnableColdCCStressTest ||
1980
1993
(TTI.useColdCCForColdCall (F) &&
1981
1994
isValidCandidateForColdCC (F, GetBFI, AllCallsCold))) {
1995
+ ChangeableCCCache.erase (&F);
1982
1996
F.setCallingConv (CallingConv::Cold);
1983
1997
changeCallSitesToColdCC (&F);
1984
1998
Changed = true ;
1985
1999
NumColdCC++;
1986
2000
}
1987
2001
}
1988
2002
1989
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2003
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
1990
2004
// If this function has a calling convention worth changing, is not a
1991
2005
// varargs function, and is only called directly, promote it to use the
1992
2006
// Fast calling convention.
0 commit comments