@@ -82,7 +82,6 @@ STATISTIC(NumNoUnwind, "Number of functions marked as nounwind");
82
82
STATISTIC (NumNoFree, " Number of functions marked as nofree" );
83
83
STATISTIC (NumWillReturn, " Number of functions marked as willreturn" );
84
84
STATISTIC (NumNoSync, " Number of functions marked as nosync" );
85
- STATISTIC (NumCold, " Number of functions marked as cold" );
86
85
87
86
STATISTIC (NumThinLinkNoRecurse,
88
87
" Number of functions marked as norecurse during thinlink" );
@@ -1746,7 +1745,6 @@ static bool canReturn(Function &F) {
1746
1745
return false ;
1747
1746
}
1748
1747
1749
-
1750
1748
// Set the noreturn function attribute if possible.
1751
1749
static void addNoReturnAttrs (const SCCNodeSet &SCCNodes,
1752
1750
SmallSet<Function *, 8 > &Changed) {
@@ -1762,72 +1760,6 @@ static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
1762
1760
}
1763
1761
}
1764
1762
1765
- static bool
1766
- allBBPathsGoThroughCold (BasicBlock *BB,
1767
- SmallDenseMap<BasicBlock *, bool , 16 > &Visited) {
1768
- // If BB contains a cold callsite this path through the CG is cold.
1769
- // Ignore whether the instructions actually are guranteed to transfer
1770
- // execution. Divergent behavior is considered unlikely.
1771
- if (any_of (*BB, [](Instruction &I) {
1772
- if (auto *CB = dyn_cast<CallBase>(&I))
1773
- return CB->hasFnAttr (Attribute::Cold);
1774
- return false ;
1775
- })) {
1776
- Visited[BB] = true ;
1777
- return true ;
1778
- }
1779
-
1780
- auto Succs = successors (BB);
1781
- // We found a path that doesn't go through any cold callsite.
1782
- if (Succs.empty ())
1783
- return false ;
1784
-
1785
- // We didn't find a cold callsite in this BB, so check that all successors
1786
- // contain a cold callsite (or that their successors do).
1787
- // Potential TODO: We could use static branch hints to assume certain
1788
- // successor paths are inherently cold, irrespective of if they contain a cold
1789
- // callsite.
1790
- for (auto *Succ : Succs) {
1791
- // Start with false, this is necessary to ensure we don't turn loops into
1792
- // cold.
1793
- auto R = Visited.try_emplace (Succ, false );
1794
- if (!R.second ) {
1795
- if (R.first ->second )
1796
- continue ;
1797
- return false ;
1798
- }
1799
- if (!allBBPathsGoThroughCold (Succ, Visited))
1800
- return false ;
1801
- Visited[Succ] = true ;
1802
- }
1803
-
1804
- return true ;
1805
- }
1806
-
1807
- static bool allPathsGoThroughCold (Function &F) {
1808
- SmallDenseMap<BasicBlock *, bool , 16 > Visited;
1809
- Visited[&F.front ()] = false ;
1810
- return allBBPathsGoThroughCold (&F.front (), Visited);
1811
- }
1812
-
1813
- // Set the cold function attribute if possible.
1814
- static void addColdAttrs (const SCCNodeSet &SCCNodes,
1815
- SmallSet<Function *, 8 > &Changed) {
1816
- for (Function *F : SCCNodes) {
1817
- if (!F || !F->hasExactDefinition () || F->hasFnAttribute (Attribute::Naked) ||
1818
- F->hasFnAttribute (Attribute::Cold) || F->hasFnAttribute (Attribute::Hot))
1819
- continue ;
1820
-
1821
- // Potential TODO: We could add attribute `cold` on functions with `coldcc`.
1822
- if (allPathsGoThroughCold (*F)) {
1823
- F->addFnAttr (Attribute::Cold);
1824
- ++NumCold;
1825
- Changed.insert (F);
1826
- continue ;
1827
- }
1828
- }
1829
- }
1830
-
1831
1763
static bool functionWillReturn (const Function &F) {
1832
1764
// We can infer and propagate function attributes only when we know that the
1833
1765
// definition we'll get at link time is *exactly* the definition we see now.
@@ -1921,7 +1853,6 @@ deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter,
1921
1853
addArgumentAttrs (Nodes.SCCNodes , Changed);
1922
1854
inferConvergent (Nodes.SCCNodes , Changed);
1923
1855
addNoReturnAttrs (Nodes.SCCNodes , Changed);
1924
- addColdAttrs (Nodes.SCCNodes , Changed);
1925
1856
addWillReturn (Nodes.SCCNodes , Changed);
1926
1857
addNoUndefAttrs (Nodes.SCCNodes , Changed);
1927
1858
0 commit comments