17
17
18
18
#include " llvm/ADT/ArrayRef.h"
19
19
#include " llvm/ADT/DenseMap.h"
20
+ #include " llvm/ADT/Optional.h"
20
21
#include " llvm/ADT/STLExtras.h"
21
22
#include " llvm/ADT/SmallPtrSet.h"
22
23
#include " llvm/ADT/SmallVector.h"
48
49
#include " llvm/Transforms/Utils/Local.h"
49
50
#include " llvm/Transforms/Utils/PromoteMemToReg.h"
50
51
#include < algorithm>
51
- # include < cassert >
52
+
52
53
#include < iterator>
53
54
#include < utility>
54
55
#include < vector>
@@ -177,6 +178,16 @@ class RenamePassData {
177
178
ValVector Values;
178
179
};
179
180
181
+ // / \brief Semi-open interval of instructions that are guaranteed to
182
+ // / all execute if the first one does.
183
+ class GuaranteedExecutionRange {
184
+ public:
185
+ unsigned Start;
186
+ unsigned End;
187
+
188
+ GuaranteedExecutionRange (unsigned S, unsigned E): Start(S), End(E) {}
189
+ };
190
+
180
191
// / \brief This assigns and keeps a per-bb relative ordering of load/store
181
192
// / instructions in the block that directly load or store an alloca.
182
193
// /
@@ -190,14 +201,109 @@ class LargeBlockInfo {
190
201
// / the block.
191
202
DenseMap<const Instruction *, unsigned > InstNumbers;
192
203
204
+ // / \brief For each basic block we track, keep track of the intervals
205
+ // / of instruction numbers of instructions that transfer control
206
+ // / to their successors, for propagating metadata.
207
+ DenseMap<const BasicBlock *, Optional<SmallVector<GuaranteedExecutionRange, 4 >>>
208
+ GuaranteedExecutionIntervals;
209
+
193
210
public:
194
211
195
- // / This code only looks at accesses to allocas.
212
+ // / This code looks for stores to allocas, and for loads both for
213
+ // / allocas and for transferring metadata.
196
214
static bool isInterestingInstruction (const Instruction *I) {
197
- return ( isa<LoadInst>(I) && isa<AllocaInst>(I-> getOperand ( 0 )) ) ||
215
+ return isa<LoadInst>(I) ||
198
216
(isa<StoreInst>(I) && isa<AllocaInst>(I->getOperand (1 )));
199
217
}
200
218
219
+ // / Compute the GuaranteedExecutionIntervals for a given BB.
220
+ // /
221
+ // / This is valid and remains valid as long as each interesting
222
+ // / instruction (see isInterestingInstruction) that
223
+ // / A) existed when this LBI was cleared
224
+ // / B) has not been deleted (deleting interesting instructions is fine)
225
+ // / are run in the same program executions and in the same order
226
+ // / as when this LBI was cleared.
227
+ // /
228
+ // / Because `PromoteMemoryToRegister` does not move memory loads at
229
+ // / all, this assumption is satisfied in this pass.
230
+ SmallVector<GuaranteedExecutionRange, 4 > computeGEI (const BasicBlock *BB) {
231
+ SmallVector<GuaranteedExecutionRange, 4 > GuaranteedExecutionIntervals;
232
+
233
+ unsigned InstNo = 0 ;
234
+ bool InRange = false ;
235
+ unsigned FirstInstInRange = 0 ;
236
+ for (const Instruction &BBI : *BB) {
237
+ if (isGuaranteedToTransferExecutionToSuccessor (&BBI)) {
238
+ if (!InRange && isInterestingInstruction (&BBI)) {
239
+ InRange = true ;
240
+ FirstInstInRange = InstNo;
241
+ }
242
+ } else {
243
+ if (InRange) {
244
+ assert (FirstInstInRange < InstNo && " Can't push an empty range here." );
245
+ GuaranteedExecutionIntervals.emplace_back (FirstInstInRange, InstNo);
246
+ }
247
+ InRange = false ;
248
+ }
249
+
250
+ if (isInterestingInstruction (&BBI)) {
251
+ auto It = InstNumbers.find (&BBI);
252
+ assert (It != InstNumbers.end () &&
253
+ InstNo <= It->second &&
254
+ " missing number for interesting instruction" );
255
+ InstNo = It->second + 1 ;
256
+ }
257
+ }
258
+
259
+ if (InRange) {
260
+ assert (FirstInstInRange < InstNo && " Can't push an empty range here." );
261
+ GuaranteedExecutionIntervals.emplace_back (FirstInstInRange, InstNo);
262
+ }
263
+
264
+ return GuaranteedExecutionIntervals;
265
+ }
266
+
267
+ // / Return true if, when CxtI executes, it is guaranteed that either
268
+ // / I had executed already or that I is guaranteed to be later executed.
269
+ // /
270
+ // / The useful property this guarantees is that if I exhibits undefined
271
+ // / behavior under some circumstances, then the whole program will exhibit
272
+ // / undefined behavior at CxtI.
273
+ bool isGuaranteedToBeExecuted (const Instruction *CxtI, const Instruction *I) {
274
+ const BasicBlock *BB = CxtI->getParent ();
275
+
276
+ if (BB != I->getParent ()) {
277
+ // Instructions in different basic blocks, so control flow
278
+ // can diverge between them (we could track this with
279
+ // postdoms, but we don't bother).
280
+ return false ;
281
+ }
282
+
283
+ unsigned Index1 = getInstructionIndex (CxtI);
284
+ unsigned Index2 = getInstructionIndex (I);
285
+
286
+ auto & BBGEI = GuaranteedExecutionIntervals[BB];
287
+ if (!BBGEI.hasValue ()) {
288
+ BBGEI.emplace (computeGEI (BB));
289
+ }
290
+
291
+ // We want to check whether I and CxtI are in the same range. To do that,
292
+ // we notice that CxtI can only be in the first range R where
293
+ // CxtI.end < R.end. If we find that range using binary search,
294
+ // we can check whether I and CxtI are both in it.
295
+ GuaranteedExecutionRange Bound (Index1, Index1);
296
+ auto R = std::upper_bound (
297
+ BBGEI->begin (), BBGEI->end (), Bound,
298
+ [](GuaranteedExecutionRange I_, GuaranteedExecutionRange R) {
299
+ return I_.End < R.End ;
300
+ });
301
+
302
+ return R != BBGEI->end () &&
303
+ R->Start <= Index1 && Index1 < R->End &&
304
+ R->Start <= Index2 && Index2 < R->End ;
305
+ }
306
+
201
307
// / Get or calculate the index of the specified instruction.
202
308
unsigned getInstructionIndex (const Instruction *I) {
203
309
assert (isInterestingInstruction (I) &&
@@ -213,9 +319,11 @@ class LargeBlockInfo {
213
319
// avoid gratuitus rescans.
214
320
const BasicBlock *BB = I->getParent ();
215
321
unsigned InstNo = 0 ;
322
+ GuaranteedExecutionIntervals.erase (BB);
216
323
for (const Instruction &BBI : *BB)
217
324
if (isInterestingInstruction (&BBI))
218
325
InstNumbers[&BBI] = InstNo++;
326
+
219
327
It = InstNumbers.find (I);
220
328
221
329
assert (It != InstNumbers.end () && " Didn't insert instruction?" );
@@ -224,7 +332,10 @@ class LargeBlockInfo {
224
332
225
333
void deleteValue (const Instruction *I) { InstNumbers.erase (I); }
226
334
227
- void clear () { InstNumbers.clear (); }
335
+ void clear () {
336
+ InstNumbers.clear ();
337
+ GuaranteedExecutionIntervals.clear ();
338
+ }
228
339
};
229
340
230
341
struct PromoteMem2Reg {
@@ -303,6 +414,7 @@ struct PromoteMem2Reg {
303
414
SmallPtrSetImpl<BasicBlock *> &LiveInBlocks);
304
415
void RenamePass (BasicBlock *BB, BasicBlock *Pred,
305
416
RenamePassData::ValVector &IncVals,
417
+ LargeBlockInfo &LBI,
306
418
std::vector<RenamePassData> &Worklist);
307
419
bool QueuePhiNode (BasicBlock *BB, unsigned AllocaIdx, unsigned &Version);
308
420
};
@@ -321,6 +433,32 @@ static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) {
321
433
AC->registerAssumption (CI);
322
434
}
323
435
436
+ static void addAssumptionsFromMetadata (LoadInst *LI,
437
+ Value *ReplVal,
438
+ DominatorTree &DT,
439
+ const DataLayout &DL,
440
+ LargeBlockInfo &LBI,
441
+ AssumptionCache *AC)
442
+ {
443
+ if (LI->getMetadata (LLVMContext::MD_nonnull) &&
444
+ !isKnownNonZero (ReplVal, DL, 0 , AC, LI, &DT)) {
445
+ addAssumeNonNull (AC, LI);
446
+ }
447
+
448
+ if (auto *N = LI->getMetadata (LLVMContext::MD_range)) {
449
+ // Range metadata is harder to use as an assumption,
450
+ // so don't try to add one, but *do* try to copy
451
+ // the metadata to a load in the same BB.
452
+ if (LoadInst *NewLI = dyn_cast<LoadInst>(ReplVal)) {
453
+ DEBUG (dbgs () << " trying to move !range metadata from" <<
454
+ *LI << " to" << *NewLI << " \n " );
455
+ if (LBI.isGuaranteedToBeExecuted (LI, NewLI)) {
456
+ copyRangeMetadata (DL, *LI, N, *NewLI);
457
+ }
458
+ }
459
+ }
460
+ }
461
+
324
462
static void removeLifetimeIntrinsicUsers (AllocaInst *AI) {
325
463
// Knowing that this alloca is promotable, we know that it's safe to kill all
326
464
// instructions except for load and store.
@@ -409,9 +547,7 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
409
547
// If the load was marked as nonnull we don't want to lose
410
548
// that information when we erase this Load. So we preserve
411
549
// it with an assume.
412
- if (AC && LI->getMetadata (LLVMContext::MD_nonnull) &&
413
- !isKnownNonZero (ReplVal, DL, 0 , AC, LI, &DT))
414
- addAssumeNonNull (AC, LI);
550
+ addAssumptionsFromMetadata (LI, ReplVal, DT, DL, LBI, AC);
415
551
416
552
LI->replaceAllUsesWith (ReplVal);
417
553
LI->eraseFromParent ();
@@ -505,9 +641,7 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
505
641
// Note, if the load was marked as nonnull we don't want to lose that
506
642
// information when we erase it. So we preserve it with an assume.
507
643
Value *ReplVal = std::prev (I)->second ->getOperand (0 );
508
- if (AC && LI->getMetadata (LLVMContext::MD_nonnull) &&
509
- !isKnownNonZero (ReplVal, DL, 0 , AC, LI, &DT))
510
- addAssumeNonNull (AC, LI);
644
+ addAssumptionsFromMetadata (LI, ReplVal, DT, DL, LBI, AC);
511
645
512
646
LI->replaceAllUsesWith (ReplVal);
513
647
}
@@ -643,7 +777,6 @@ void PromoteMem2Reg::run() {
643
777
644
778
if (Allocas.empty ())
645
779
return ; // All of the allocas must have been trivial!
646
-
647
780
LBI.clear ();
648
781
649
782
// Set the incoming values for the basic block to be null values for all of
@@ -661,9 +794,10 @@ void PromoteMem2Reg::run() {
661
794
RenamePassData RPD = std::move (RenamePassWorkList.back ());
662
795
RenamePassWorkList.pop_back ();
663
796
// RenamePass may add new worklist entries.
664
- RenamePass (RPD.BB , RPD.Pred , RPD.Values , RenamePassWorkList);
797
+ RenamePass (RPD.BB , RPD.Pred , RPD.Values , LBI, RenamePassWorkList);
665
798
} while (!RenamePassWorkList.empty ());
666
799
800
+ LBI.clear ();
667
801
// The renamer uses the Visited set to avoid infinite loops. Clear it now.
668
802
Visited.clear ();
669
803
@@ -875,6 +1009,7 @@ bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo,
875
1009
// / predecessor block Pred.
876
1010
void PromoteMem2Reg::RenamePass (BasicBlock *BB, BasicBlock *Pred,
877
1011
RenamePassData::ValVector &IncomingVals,
1012
+ LargeBlockInfo &LBI,
878
1013
std::vector<RenamePassData> &Worklist) {
879
1014
NextIteration:
880
1015
// If we are inserting any phi nodes into this BB, they will already be in the
@@ -941,13 +1076,12 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
941
1076
// If the load was marked as nonnull we don't want to lose
942
1077
// that information when we erase this Load. So we preserve
943
1078
// it with an assume.
944
- if (AC && LI->getMetadata (LLVMContext::MD_nonnull) &&
945
- !isKnownNonZero (V, SQ.DL , 0 , AC, LI, &DT))
946
- addAssumeNonNull (AC, LI);
1079
+ addAssumptionsFromMetadata (LI, V, DT, SQ.DL , LBI, AC);
947
1080
948
1081
// Anything using the load now uses the current value.
949
1082
LI->replaceAllUsesWith (V);
950
1083
BB->getInstList ().erase (LI);
1084
+ LBI.deleteValue (LI);
951
1085
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
952
1086
// Delete this instruction and mark the name as the current holder of the
953
1087
// value
@@ -965,6 +1099,7 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
965
1099
for (DbgInfoIntrinsic *DII : AllocaDbgDeclares[ai->second ])
966
1100
ConvertDebugDeclareToDebugValue (DII, SI, DIB);
967
1101
BB->getInstList ().erase (SI);
1102
+ LBI.deleteValue (SI);
968
1103
}
969
1104
}
970
1105
0 commit comments