29
29
#include " swift/SILOptimizer/PassManager/Passes.h"
30
30
#include " swift/SILOptimizer/PassManager/Transforms.h"
31
31
#include " swift/SILOptimizer/Utils/InstructionDeleter.h"
32
+ #include " swift/SILOptimizer/Analysis/ColdBlockInfo.h"
33
+ #include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
32
34
#include " swift/Strings.h"
33
35
34
36
using namespace swift ;
@@ -77,6 +79,58 @@ static bool cleanFunction(SILFunction &fn) {
77
79
return madeChange;
78
80
}
79
81
82
+ // / Embed information about cold edges into the SIL via ProfileCounters
83
+ // / So that it's available in LLVM.
84
+ static bool lowerColdBlockInfo (DominanceAnalysis *DA,
85
+ PostDominanceAnalysis *PDA,
86
+ SILFunction &fn) {
87
+ bool invalidate = false ;
88
+
89
+ ColdBlockInfo CBI (DA, PDA);
90
+ CBI.analyze (&fn);
91
+
92
+ SmallVector<SILSuccessor*, 8 > coldSuccs;
93
+ SmallVector<SILSuccessor*, 8 > warmSuccs;
94
+ for (auto &block : fn) {
95
+ if (CBI.isCold (&block) || block.getNumSuccessors () < 2 )
96
+ continue ;
97
+
98
+ coldSuccs.clear (); warmSuccs.clear ();
99
+
100
+ // Partition the successors.
101
+ bool hasExistingProfileData = false ;
102
+ for (SILSuccessor &succ : block.getSuccessors ()) {
103
+ if (succ.getCount ().hasValue ()) {
104
+ hasExistingProfileData = true ;
105
+ break ;
106
+ }
107
+
108
+ if (CBI.isCold (succ))
109
+ coldSuccs.push_back (&succ);
110
+ else
111
+ warmSuccs.push_back (&succ);
112
+ }
113
+
114
+ if (hasExistingProfileData)
115
+ continue ;
116
+
117
+ // Nothing to annotate if everything's warm.
118
+ if (coldSuccs.empty ())
119
+ continue ;
120
+
121
+ ASSERT (!warmSuccs.empty () && " all succs are cold, yet the block isn't?" );
122
+ invalidate = true ;
123
+
124
+ for (auto *coldSucc : coldSuccs)
125
+ coldSucc->setCount (ProfileCounter (1 ));
126
+
127
+ for (auto *warmSucc : warmSuccs)
128
+ warmSucc->setCount (ProfileCounter (2000 ));
129
+ }
130
+
131
+ return invalidate;
132
+ }
133
+
80
134
// ===----------------------------------------------------------------------===//
81
135
// Top Level Entrypoint
82
136
// ===----------------------------------------------------------------------===//
@@ -86,6 +140,8 @@ namespace {
86
140
class IRGenPrepare : public SILFunctionTransform {
87
141
void run () override {
88
142
SILFunction *F = getFunction ();
143
+ auto *DA = PM->getAnalysis <DominanceAnalysis>();
144
+ auto *PDA = PM->getAnalysis <PostDominanceAnalysis>();
89
145
90
146
if (getOptions ().EmbeddedSwift ) {
91
147
// In embedded swift all the code is generated in the top-level module.
@@ -98,6 +154,9 @@ class IRGenPrepare : public SILFunctionTransform {
98
154
99
155
bool shouldInvalidate = cleanFunction (*F);
100
156
157
+ // FIXME: just for testing...
158
+ // shouldInvalidate |= lowerColdBlockInfo(DA, PDA, *F);
159
+
101
160
if (shouldInvalidate)
102
161
invalidateAnalysis (SILAnalysis::InvalidationKind::Instructions);
103
162
}
0 commit comments