@@ -53,7 +53,7 @@ void SSAUpdaterBulk::AddAvailableValue(unsigned Var, BasicBlock *BB, Value *V) {
53
53
LLVM_DEBUG (dbgs () << " SSAUpdater: Var=" << Var
54
54
<< " : added new available value " << *V << " in "
55
55
<< BB->getName () << " \n " );
56
- Rewrites[Var].Defines [BB] = V ;
56
+ Rewrites[Var].Defines . emplace_back (BB, V) ;
57
57
}
58
58
59
59
// / Record a use of the symbolic value. This use will be updated with a
@@ -65,21 +65,6 @@ void SSAUpdaterBulk::AddUse(unsigned Var, Use *U) {
65
65
Rewrites[Var].Uses .push_back (U);
66
66
}
67
67
68
- // Compute value at the given block BB. We either should already know it, or we
69
- // should be able to recursively reach it going up dominator tree.
70
- Value *SSAUpdaterBulk::computeValueAt (BasicBlock *BB, RewriteInfo &R,
71
- DominatorTree *DT) {
72
- if (!R.Defines .count (BB)) {
73
- if (DT->isReachableFromEntry (BB) && PredCache.get (BB).size ()) {
74
- BasicBlock *IDom = DT->getNode (BB)->getIDom ()->getBlock ();
75
- Value *V = computeValueAt (IDom, R, DT);
76
- R.Defines [BB] = V;
77
- } else
78
- R.Defines [BB] = UndefValue::get (R.Ty );
79
- }
80
- return R.Defines [BB];
81
- }
82
-
83
68
// / Given sets of UsingBlocks and DefBlocks, compute the set of LiveInBlocks.
84
69
// / This is basically a subgraph limited by DefBlocks and UsingBlocks.
85
70
static void
@@ -117,11 +102,19 @@ ComputeLiveInBlocks(const SmallPtrSetImpl<BasicBlock *> &UsingBlocks,
117
102
}
118
103
}
119
104
105
+ struct BBValueInfo {
106
+ Value *LiveInValue = nullptr ;
107
+ Value *LiveOutValue = nullptr ;
108
+ };
109
+
120
110
// / Perform all the necessary updates, including new PHI-nodes insertion and the
121
111
// / requested uses update.
122
112
void SSAUpdaterBulk::RewriteAllUses (DominatorTree *DT,
123
113
SmallVectorImpl<PHINode *> *InsertedPHIs) {
114
+ DenseMap<BasicBlock *, BBValueInfo> BBInfos;
124
115
for (auto &R : Rewrites) {
116
+ BBInfos.clear ();
117
+
125
118
// Compute locations for new phi-nodes.
126
119
// For that we need to initialize DefBlocks from definitions in R.Defines,
127
120
// UsingBlocks from uses in R.Uses, then compute LiveInBlocks, and then use
@@ -132,8 +125,8 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT,
132
125
<< " use(s)\n " );
133
126
134
127
SmallPtrSet<BasicBlock *, 2 > DefBlocks;
135
- for (auto &Def : R.Defines )
136
- DefBlocks.insert (Def. first );
128
+ for (auto [BB, V] : R.Defines )
129
+ DefBlocks.insert (BB );
137
130
IDF.setDefiningBlocks (DefBlocks);
138
131
139
132
SmallPtrSet<BasicBlock *, 2 > UsingBlocks;
@@ -143,34 +136,82 @@ void SSAUpdaterBulk::RewriteAllUses(DominatorTree *DT,
143
136
SmallVector<BasicBlock *, 32 > IDFBlocks;
144
137
SmallPtrSet<BasicBlock *, 32 > LiveInBlocks;
145
138
ComputeLiveInBlocks (UsingBlocks, DefBlocks, LiveInBlocks, PredCache);
146
- IDF.resetLiveInBlocks ();
147
139
IDF.setLiveInBlocks (LiveInBlocks);
148
140
IDF.calculate (IDFBlocks);
149
141
142
+ // Reserve sufficient buckets to prevent map growth. [1]
143
+ BBInfos.reserve (LiveInBlocks.size () + DefBlocks.size ());
144
+
145
+ for (auto [BB, V] : R.Defines )
146
+ BBInfos[BB].LiveOutValue = V;
147
+
150
148
// We've computed IDF, now insert new phi-nodes there.
151
- SmallVector<PHINode *, 4 > InsertedPHIsForVar;
152
149
for (auto *FrontierBB : IDFBlocks) {
153
150
IRBuilder<> B (FrontierBB, FrontierBB->begin ());
154
151
PHINode *PN = B.CreatePHI (R.Ty , 0 , R.Name );
155
- R.Defines [FrontierBB] = PN;
156
- InsertedPHIsForVar.push_back (PN);
152
+ BBInfos[FrontierBB].LiveInValue = PN;
157
153
if (InsertedPHIs)
158
154
InsertedPHIs->push_back (PN);
159
155
}
160
156
157
+ // IsLiveOut indicates whether we are computing live-out values (true) or
158
+ // live-in values (false).
159
+ auto ComputeValue = [&](BasicBlock *BB, bool IsLiveOut) -> Value * {
160
+ auto *BBInfo = &BBInfos[BB];
161
+
162
+ if (IsLiveOut && BBInfo->LiveOutValue )
163
+ return BBInfo->LiveOutValue ;
164
+
165
+ if (BBInfo->LiveInValue )
166
+ return BBInfo->LiveInValue ;
167
+
168
+ SmallVector<BBValueInfo *, 4 > Stack = {BBInfo};
169
+ Value *V = nullptr ;
170
+
171
+ while (DT->isReachableFromEntry (BB) && !PredCache.get (BB).empty () &&
172
+ (BB = DT->getNode (BB)->getIDom ()->getBlock ())) {
173
+ BBInfo = &BBInfos[BB];
174
+
175
+ if (BBInfo->LiveOutValue ) {
176
+ V = BBInfo->LiveOutValue ;
177
+ break ;
178
+ }
179
+
180
+ if (BBInfo->LiveInValue ) {
181
+ V = BBInfo->LiveInValue ;
182
+ break ;
183
+ }
184
+
185
+ Stack.emplace_back (BBInfo);
186
+ }
187
+
188
+ if (!V)
189
+ V = UndefValue::get (R.Ty );
190
+
191
+ for (auto *BBInfo : Stack)
192
+ // Loop above can insert new entries into the BBInfos map: assume the
193
+ // map shouldn't grow due to [1] and BBInfo references are valid.
194
+ BBInfo->LiveInValue = V;
195
+
196
+ return V;
197
+ };
198
+
161
199
// Fill in arguments of the inserted PHIs.
162
- for (auto *PN : InsertedPHIsForVar ) {
163
- BasicBlock *PBB = PN-> getParent ( );
164
- for (BasicBlock *Pred : PredCache.get (PBB ))
165
- PN ->addIncoming (computeValueAt (Pred, R, DT ), Pred);
200
+ for (auto *BB : IDFBlocks ) {
201
+ auto *PHI = cast<PHINode>(&BB-> front () );
202
+ for (BasicBlock *Pred : PredCache.get (BB ))
203
+ PHI ->addIncoming (ComputeValue (Pred, /* IsLiveOut= */ true ), Pred);
166
204
}
167
205
168
206
// Rewrite actual uses with the inserted definitions.
169
207
SmallPtrSet<Use *, 4 > ProcessedUses;
170
208
for (Use *U : R.Uses ) {
171
209
if (!ProcessedUses.insert (U).second )
172
210
continue ;
173
- Value *V = computeValueAt (getUserBB (U), R, DT);
211
+
212
+ auto *User = cast<Instruction>(U->getUser ());
213
+ BasicBlock *BB = getUserBB (U);
214
+ Value *V = ComputeValue (BB, /* IsLiveOut=*/ BB != User->getParent ());
174
215
Value *OldVal = U->get ();
175
216
assert (OldVal && " Invalid use!" );
176
217
// Notify that users of the existing value that it is being replaced.
0 commit comments