@@ -1689,13 +1689,16 @@ static void RemoveAttribute(Function *F, Attribute::AttrKind A) {
1689
1689
// / idea here is that we don't want to mess with the convention if the user
1690
1690
// / explicitly requested something with performance implications like coldcc,
1691
1691
// / GHC, or anyregcc.
1692
- static bool hasChangeableCC (Function *F) {
1692
+ static bool hasChangeableCCImpl (Function *F) {
1693
1693
CallingConv::ID CC = F->getCallingConv ();
1694
1694
1695
1695
// FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
1696
1696
if (CC != CallingConv::C && CC != CallingConv::X86_ThisCall)
1697
1697
return false ;
1698
1698
1699
+ if (F->isVarArg ())
1700
+ return false ;
1701
+
1699
1702
// FIXME: Change CC for the whole chain of musttail calls when possible.
1700
1703
//
1701
1704
// Can't change CC of the function that either has musttail calls, or is a
@@ -1715,7 +1718,16 @@ static bool hasChangeableCC(Function *F) {
1715
1718
if (BB.getTerminatingMustTailCall ())
1716
1719
return false ;
1717
1720
1718
- return true ;
1721
+ return !F->hasAddressTaken ();
1722
+ }
1723
+
1724
+ using ChangeableCCCacheTy = SmallDenseMap<Function *, bool , 8 >;
1725
+ static bool hasChangeableCC (Function *F,
1726
+ ChangeableCCCacheTy &ChangeableCCCache) {
1727
+ auto Res = ChangeableCCCache.try_emplace (F, false );
1728
+ if (Res.second )
1729
+ Res.first ->second = hasChangeableCCImpl (F);
1730
+ return Res.first ->second ;
1719
1731
}
1720
1732
1721
1733
// / Return true if the block containing the call site has a BlockFrequency of
@@ -1769,7 +1781,8 @@ static void changeCallSitesToColdCC(Function *F) {
1769
1781
// coldcc calling convention.
1770
1782
static bool
1771
1783
hasOnlyColdCalls (Function &F,
1772
- function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
1784
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
1785
+ ChangeableCCCacheTy &ChangeableCCCache) {
1773
1786
for (BasicBlock &BB : F) {
1774
1787
for (Instruction &I : BB) {
1775
1788
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
@@ -1785,8 +1798,7 @@ hasOnlyColdCalls(Function &F,
1785
1798
if (CalledFn->getIntrinsicID () != Intrinsic::not_intrinsic)
1786
1799
continue ;
1787
1800
// Check if it's valid to use coldcc calling convention.
1788
- if (!hasChangeableCC (CalledFn) || CalledFn->isVarArg () ||
1789
- CalledFn->hasAddressTaken ())
1801
+ if (!hasChangeableCC (CalledFn, ChangeableCCCache))
1790
1802
return false ;
1791
1803
BlockFrequencyInfo &CallerBFI = GetBFI (F);
1792
1804
if (!isColdCallSite (*CI, CallerBFI))
@@ -1914,9 +1926,10 @@ OptimizeFunctions(Module &M,
1914
1926
1915
1927
bool Changed = false ;
1916
1928
1929
+ ChangeableCCCacheTy ChangeableCCCache;
1917
1930
std::vector<Function *> AllCallsCold;
1918
1931
for (Function &F : llvm::make_early_inc_range (M))
1919
- if (hasOnlyColdCalls (F, GetBFI))
1932
+ if (hasOnlyColdCalls (F, GetBFI, ChangeableCCCache ))
1920
1933
AllCallsCold.push_back (&F);
1921
1934
1922
1935
// Optimize functions.
@@ -1980,7 +1993,7 @@ OptimizeFunctions(Module &M,
1980
1993
continue ;
1981
1994
}
1982
1995
1983
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
1996
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
1984
1997
NumInternalFunc++;
1985
1998
TargetTransformInfo &TTI = GetTTI (F);
1986
1999
// Change the calling convention to coldcc if either stress testing is
@@ -1990,14 +2003,15 @@ OptimizeFunctions(Module &M,
1990
2003
if (EnableColdCCStressTest ||
1991
2004
(TTI.useColdCCForColdCall (F) &&
1992
2005
isValidCandidateForColdCC (F, GetBFI, AllCallsCold))) {
2006
+ ChangeableCCCache.erase (&F);
1993
2007
F.setCallingConv (CallingConv::Cold);
1994
2008
changeCallSitesToColdCC (&F);
1995
2009
Changed = true ;
1996
2010
NumColdCC++;
1997
2011
}
1998
2012
}
1999
2013
2000
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2014
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
2001
2015
// If this function has a calling convention worth changing, is not a
2002
2016
// varargs function, and is only called directly, promote it to use the
2003
2017
// Fast calling convention.
0 commit comments