@@ -1732,13 +1732,16 @@ static void RemoveAttribute(Function *F, Attribute::AttrKind A) {
1732
1732
// / idea here is that we don't want to mess with the convention if the user
1733
1733
// / explicitly requested something with performance implications like coldcc,
1734
1734
// / GHC, or anyregcc.
1735
- static bool hasChangeableCC (Function *F) {
1735
+ static bool hasChangeableCCImpl (Function *F) {
1736
1736
CallingConv::ID CC = F->getCallingConv ();
1737
1737
1738
1738
// FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
1739
1739
if (CC != CallingConv::C && CC != CallingConv::X86_ThisCall)
1740
1740
return false ;
1741
1741
1742
+ if (F->isVarArg ())
1743
+ return false ;
1744
+
1742
1745
// FIXME: Change CC for the whole chain of musttail calls when possible.
1743
1746
//
1744
1747
// Can't change CC of the function that either has musttail calls, or is a
@@ -1758,7 +1761,16 @@ static bool hasChangeableCC(Function *F) {
1758
1761
if (BB.getTerminatingMustTailCall ())
1759
1762
return false ;
1760
1763
1761
- return true ;
1764
+ return !F->hasAddressTaken ();
1765
+ }
1766
+
1767
+ using ChangeableCCCacheTy = SmallDenseMap<Function *, bool , 8 >;
1768
+ static bool hasChangeableCC (Function *F,
1769
+ ChangeableCCCacheTy &ChangeableCCCache) {
1770
+ auto Res = ChangeableCCCache.try_emplace (F, false );
1771
+ if (Res.second )
1772
+ Res.first ->second = hasChangeableCCImpl (F);
1773
+ return Res.first ->second ;
1762
1774
}
1763
1775
1764
1776
// / Return true if the block containing the call site has a BlockFrequency of
@@ -1812,7 +1824,8 @@ static void changeCallSitesToColdCC(Function *F) {
1812
1824
// coldcc calling convention.
1813
1825
static bool
1814
1826
hasOnlyColdCalls (Function &F,
1815
- function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
1827
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI,
1828
+ ChangeableCCCacheTy &ChangeableCCCache) {
1816
1829
for (BasicBlock &BB : F) {
1817
1830
for (Instruction &I : BB) {
1818
1831
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
@@ -1831,8 +1844,7 @@ hasOnlyColdCalls(Function &F,
1831
1844
if (!CalledFn->hasLocalLinkage ())
1832
1845
return false ;
1833
1846
// Check if it's valid to use coldcc calling convention.
1834
- if (!hasChangeableCC (CalledFn) || CalledFn->isVarArg () ||
1835
- CalledFn->hasAddressTaken ())
1847
+ if (!hasChangeableCC (CalledFn, ChangeableCCCache))
1836
1848
return false ;
1837
1849
BlockFrequencyInfo &CallerBFI = GetBFI (F);
1838
1850
if (!isColdCallSite (*CI, CallerBFI))
@@ -1962,9 +1974,10 @@ OptimizeFunctions(Module &M,
1962
1974
1963
1975
bool Changed = false ;
1964
1976
1977
+ ChangeableCCCacheTy ChangeableCCCache;
1965
1978
std::vector<Function *> AllCallsCold;
1966
1979
for (Function &F : llvm::make_early_inc_range (M))
1967
- if (hasOnlyColdCalls (F, GetBFI))
1980
+ if (hasOnlyColdCalls (F, GetBFI, ChangeableCCCache ))
1968
1981
AllCallsCold.push_back (&F);
1969
1982
1970
1983
// Optimize functions.
@@ -2026,7 +2039,7 @@ OptimizeFunctions(Module &M,
2026
2039
continue ;
2027
2040
}
2028
2041
2029
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2042
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
2030
2043
NumInternalFunc++;
2031
2044
TargetTransformInfo &TTI = GetTTI (F);
2032
2045
// Change the calling convention to coldcc if either stress testing is
@@ -2036,14 +2049,15 @@ OptimizeFunctions(Module &M,
2036
2049
if (EnableColdCCStressTest ||
2037
2050
(TTI.useColdCCForColdCall (F) &&
2038
2051
isValidCandidateForColdCC (F, GetBFI, AllCallsCold))) {
2052
+ ChangeableCCCache.erase (&F);
2039
2053
F.setCallingConv (CallingConv::Cold);
2040
2054
changeCallSitesToColdCC (&F);
2041
2055
Changed = true ;
2042
2056
NumColdCC++;
2043
2057
}
2044
2058
}
2045
2059
2046
- if (hasChangeableCC (&F) && !F. isVarArg () && !F. hasAddressTaken ( )) {
2060
+ if (hasChangeableCC (&F, ChangeableCCCache )) {
2047
2061
// If this function has a calling convention worth changing, is not a
2048
2062
// varargs function, and is only called directly, promote it to use the
2049
2063
// Fast calling convention.
0 commit comments