@@ -82,7 +82,6 @@ STATISTIC(NumNoUnwind, "Number of functions marked as nounwind");
8282STATISTIC (NumNoFree, " Number of functions marked as nofree" );
8383STATISTIC (NumWillReturn, " Number of functions marked as willreturn" );
8484STATISTIC (NumNoSync, " Number of functions marked as nosync" );
85- STATISTIC (NumCold, " Number of functions marked as cold" );
8685
8786STATISTIC (NumThinLinkNoRecurse,
8887 " Number of functions marked as norecurse during thinlink" );
@@ -1746,7 +1745,6 @@ static bool canReturn(Function &F) {
17461745 return false ;
17471746}
17481747
1749-
17501748// Set the noreturn function attribute if possible.
17511749static void addNoReturnAttrs (const SCCNodeSet &SCCNodes,
17521750 SmallSet<Function *, 8 > &Changed) {
@@ -1762,72 +1760,6 @@ static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
17621760 }
17631761}
17641762
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-
18311763static bool functionWillReturn (const Function &F) {
18321764 // We can infer and propagate function attributes only when we know that the
18331765 // definition we'll get at link time is *exactly* the definition we see now.
@@ -1921,7 +1853,6 @@ deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter,
19211853 addArgumentAttrs (Nodes.SCCNodes , Changed);
19221854 inferConvergent (Nodes.SCCNodes , Changed);
19231855 addNoReturnAttrs (Nodes.SCCNodes , Changed);
1924- addColdAttrs (Nodes.SCCNodes , Changed);
19251856 addWillReturn (Nodes.SCCNodes , Changed);
19261857 addNoUndefAttrs (Nodes.SCCNodes , Changed);
19271858
0 commit comments