@@ -59,7 +59,8 @@ using DomTreeLevelMap = llvm::DenseMap<DomTreeNode *, unsigned>;
59
59
// Utilities
60
60
// ===----------------------------------------------------------------------===//
61
61
62
- static void replaceDestroy (DestroyAddrInst *dai, SILValue newValue) {
62
+ static void replaceDestroy (DestroyAddrInst *dai, SILValue newValue,
63
+ SILBuilderContext &ctx) {
63
64
SILFunction *f = dai->getFunction ();
64
65
auto ty = dai->getOperand ()->getType ();
65
66
@@ -68,7 +69,7 @@ static void replaceDestroy(DestroyAddrInst *dai, SILValue newValue) {
68
69
assert (newValue ||
69
70
(ty.is <TupleType>() && ty.getAs <TupleType>()->getNumElements () == 0 ));
70
71
71
- SILBuilderWithScope builder (dai);
72
+ SILBuilderWithScope builder (dai, ctx );
72
73
73
74
auto &typeLowering = f->getTypeLowering (ty);
74
75
@@ -84,21 +85,22 @@ static void replaceDestroy(DestroyAddrInst *dai, SILValue newValue) {
84
85
85
86
// / Promote a DebugValueAddr to a DebugValue of the given value.
86
87
static void promoteDebugValueAddr (DebugValueAddrInst *dvai, SILValue value,
87
- SILBuilder &b ) {
88
+ SILBuilderContext &ctx ) {
88
89
assert (dvai->getOperand ()->getType ().isLoadable (*dvai->getFunction ()) &&
89
90
" Unexpected promotion of address-only type!" );
90
91
assert (value && " Expected valid value" );
91
92
// Avoid inserting the same debug_value twice.
92
- for (auto *use : value->getUses ())
93
- if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser ()))
93
+ for (auto *use : value->getUses ()) {
94
+ if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser ())) {
94
95
if (*dvi->getVarInfo () == *dvai->getVarInfo ()) {
95
96
dvai->eraseFromParent ();
96
97
return ;
97
98
}
98
- b.setInsertionPoint (dvai);
99
- b.setCurrentDebugScope (dvai->getDebugScope ());
100
- b.createDebugValue (dvai->getLoc (), value, *dvai->getVarInfo ());
99
+ }
100
+ }
101
101
102
+ SILBuilderWithScope b (dvai, ctx);
103
+ b.createDebugValue (dvai->getLoc (), value, *dvai->getVarInfo ());
102
104
dvai->eraseFromParent ();
103
105
}
104
106
@@ -135,10 +137,11 @@ static void collectLoads(SILInstruction *i,
135
137
}
136
138
}
137
139
138
- static void replaceLoad (LoadInst *li, SILValue newValue, AllocStackInst *asi) {
140
+ static void replaceLoad (LoadInst *li, SILValue newValue, AllocStackInst *asi,
141
+ SILBuilderContext &ctx) {
139
142
ProjectionPath projections (newValue->getType ());
140
143
SILValue op = li->getOperand ();
141
- SILBuilderWithScope builder (li);
144
+ SILBuilderWithScope builder (li, ctx );
142
145
143
146
while (op != asi) {
144
147
assert (isa<UncheckedAddrCastInst>(op) || isa<StructElementAddrInst>(op) ||
@@ -200,14 +203,16 @@ static void replaceLoad(LoadInst *li, SILValue newValue, AllocStackInst *asi) {
200
203
201
204
// / Create a tuple value for an empty tuple or a tuple of empty tuples.
202
205
static SILValue createValueForEmptyTuple (SILType ty,
203
- SILInstruction *insertionPoint) {
206
+ SILInstruction *insertionPoint,
207
+ SILBuilderContext &ctx) {
204
208
auto tupleTy = ty.castTo <TupleType>();
205
209
SmallVector<SILValue, 4 > elements;
206
210
for (unsigned idx : range (tupleTy->getNumElements ())) {
207
211
SILType elementTy = ty.getTupleElementType (idx);
208
- elements.push_back (createValueForEmptyTuple (elementTy, insertionPoint));
212
+ elements.push_back (
213
+ createValueForEmptyTuple (elementTy, insertionPoint, ctx));
209
214
}
210
- SILBuilderWithScope builder (insertionPoint);
215
+ SILBuilderWithScope builder (insertionPoint, ctx );
211
216
return builder.createTuple (insertionPoint->getLoc (), ty, elements);
212
217
}
213
218
@@ -242,8 +247,9 @@ class StackAllocationPromoter {
242
247
// / Map from dominator tree node to tree level.
243
248
DomTreeLevelMap &domTreeLevels;
244
249
245
- // / The builder used to create new instructions during register promotion.
246
- SILBuilder &b;
250
+ // / The SIL builder used when creating new instructions during register
251
+ // / promotion.
252
+ SILBuilderContext &ctx;
247
253
248
254
// / Records the last store instruction in each block for a specific
249
255
// / AllocStackInst.
@@ -253,9 +259,9 @@ class StackAllocationPromoter {
253
259
// / C'tor.
254
260
StackAllocationPromoter (AllocStackInst *inputASI, DominanceInfo *inputDomInfo,
255
261
DomTreeLevelMap &inputDomTreeLevels,
256
- SILBuilder &inputB )
262
+ SILBuilderContext &inputCtx )
257
263
: asi(inputASI), dsi(nullptr ), domInfo(inputDomInfo),
258
- domTreeLevels (inputDomTreeLevels), b(inputB ) {
264
+ domTreeLevels (inputDomTreeLevels), ctx(inputCtx ) {
259
265
// Scan the users in search of a deallocation instruction.
260
266
for (auto *use : asi->getUses ()) {
261
267
if (auto *foundDealloc = dyn_cast<DeallocStackInst>(use->getUser ())) {
@@ -336,7 +342,7 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
336
342
// If we are loading from the AllocStackInst and we already know the
337
343
// content of the Alloca then use it.
338
344
LLVM_DEBUG (llvm::dbgs () << " *** Promoting load: " << *li);
339
- replaceLoad (li, runningVal, asi);
345
+ replaceLoad (li, runningVal, asi, ctx );
340
346
++NumInstRemoved;
341
347
} else if (li->getOperand () == asi &&
342
348
li->getOwnershipQualifier () != LoadOwnershipQualifier::Copy) {
@@ -361,9 +367,10 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
361
367
// simplifies further processing.
362
368
if (si->getOwnershipQualifier () == StoreOwnershipQualifier::Assign) {
363
369
if (runningVal) {
364
- SILBuilderWithScope (si).createDestroyValue (si->getLoc (), runningVal);
370
+ SILBuilderWithScope (si, ctx).createDestroyValue (si->getLoc (),
371
+ runningVal);
365
372
} else {
366
- SILBuilderWithScope localBuilder (si);
373
+ SILBuilderWithScope localBuilder (si, ctx );
367
374
auto *newLoad = localBuilder.createLoad (si->getLoc (), asi,
368
375
LoadOwnershipQualifier::Take);
369
376
localBuilder.createDestroyValue (si->getLoc (), newLoad);
@@ -395,14 +402,14 @@ StoreInst *StackAllocationPromoter::promoteAllocationInBlock(
395
402
// promote this when we deal with hooking up phis.
396
403
if (auto *dvai = dyn_cast<DebugValueAddrInst>(inst)) {
397
404
if (dvai->getOperand () == asi && runningVal)
398
- promoteDebugValueAddr (dvai, runningVal, b );
405
+ promoteDebugValueAddr (dvai, runningVal, ctx );
399
406
continue ;
400
407
}
401
408
402
409
// Replace destroys with a release of the value.
403
- if (auto *DAI = dyn_cast<DestroyAddrInst>(inst)) {
404
- if (DAI ->getOperand () == asi && runningVal) {
405
- replaceDestroy (DAI , runningVal);
410
+ if (auto *dai = dyn_cast<DestroyAddrInst>(inst)) {
411
+ if (dai ->getOperand () == asi && runningVal) {
412
+ replaceDestroy (dai , runningVal, ctx );
406
413
}
407
414
continue ;
408
415
}
@@ -536,7 +543,7 @@ void StackAllocationPromoter::fixBranchesAndUses(BlockSet &phiBlocks) {
536
543
<< " *** Replacing " << *li << " with Def " << *def);
537
544
538
545
// Replace the load with the definition that we found.
539
- replaceLoad (li, def, asi);
546
+ replaceLoad (li, def, asi, ctx );
540
547
removedUser = true ;
541
548
++NumInstRemoved;
542
549
}
@@ -552,15 +559,15 @@ void StackAllocationPromoter::fixBranchesAndUses(BlockSet &phiBlocks) {
552
559
if (auto *dvai = dyn_cast<DebugValueAddrInst>(user)) {
553
560
// Replace DebugValueAddr with DebugValue.
554
561
SILValue def = getLiveInValue (phiBlocks, userBlock);
555
- promoteDebugValueAddr (dvai, def, b );
562
+ promoteDebugValueAddr (dvai, def, ctx );
556
563
++NumInstRemoved;
557
564
continue ;
558
565
}
559
566
560
567
// Replace destroys with a release of the value.
561
- if (auto *DAI = dyn_cast<DestroyAddrInst>(user)) {
562
- SILValue Def = getLiveInValue (phiBlocks, userBlock);
563
- replaceDestroy (DAI, Def );
568
+ if (auto *dai = dyn_cast<DestroyAddrInst>(user)) {
569
+ SILValue def = getLiveInValue (phiBlocks, userBlock);
570
+ replaceDestroy (dai, def, ctx );
564
571
continue ;
565
572
}
566
573
}
@@ -742,8 +749,9 @@ class MemoryToRegisters {
742
749
// / Dominators.
743
750
DominanceInfo *domInfo;
744
751
745
- // / The builder used to create new instructions during register promotion.
746
- SILBuilder b;
752
+ // / The builder context used when creating new instructions during register
753
+ // / promotion.
754
+ SILBuilderContext ctx;
747
755
748
756
// / Check if the AllocStackInst \p ASI is only written into.
749
757
bool isWriteOnlyAllocation (AllocStackInst *asi);
@@ -763,7 +771,7 @@ class MemoryToRegisters {
763
771
public:
764
772
// / C'tor
765
773
MemoryToRegisters (SILFunction &inputFunc, DominanceInfo *inputDomInfo)
766
- : f(inputFunc), domInfo(inputDomInfo), b (inputFunc) {}
774
+ : f(inputFunc), domInfo(inputDomInfo), ctx (inputFunc.getModule() ) {}
767
775
768
776
// / Promote memory to registers. Return True on change.
769
777
bool run ();
@@ -925,9 +933,9 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
925
933
if (!runningVal) {
926
934
// Loading without a previous store is only acceptable if the type is
927
935
// Void (= empty tuple) or a tuple of Voids.
928
- runningVal = createValueForEmptyTuple (asi->getElementType (), inst);
936
+ runningVal = createValueForEmptyTuple (asi->getElementType (), inst, ctx );
929
937
}
930
- replaceLoad (cast<LoadInst>(inst), runningVal, asi);
938
+ replaceLoad (cast<LoadInst>(inst), runningVal, asi, ctx );
931
939
++NumInstRemoved;
932
940
continue ;
933
941
}
@@ -938,7 +946,8 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
938
946
if (si->getDest () == asi) {
939
947
if (si->getOwnershipQualifier () == StoreOwnershipQualifier::Assign) {
940
948
assert (runningVal);
941
- SILBuilderWithScope (si).createDestroyValue (si->getLoc (), runningVal);
949
+ SILBuilderWithScope (si, ctx).createDestroyValue (si->getLoc (),
950
+ runningVal);
942
951
}
943
952
runningVal = si->getSrc ();
944
953
inst->eraseFromParent ();
@@ -951,7 +960,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
951
960
if (auto *dvai = dyn_cast<DebugValueAddrInst>(inst)) {
952
961
if (dvai->getOperand () == asi) {
953
962
if (runningVal) {
954
- promoteDebugValueAddr (dvai, runningVal, b );
963
+ promoteDebugValueAddr (dvai, runningVal, ctx );
955
964
} else {
956
965
// Drop debug_value_addr of uninitialized void values.
957
966
assert (asi->getElementType ().isVoid () &&
@@ -963,9 +972,9 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *asi) {
963
972
}
964
973
965
974
// Replace destroys with a release of the value.
966
- if (auto *DAI = dyn_cast<DestroyAddrInst>(inst)) {
967
- if (DAI ->getOperand () == asi) {
968
- replaceDestroy (DAI , runningVal);
975
+ if (auto *dai = dyn_cast<DestroyAddrInst>(inst)) {
976
+ if (dai ->getOperand () == asi) {
977
+ replaceDestroy (dai , runningVal, ctx );
969
978
}
970
979
continue ;
971
980
}
@@ -1048,16 +1057,17 @@ bool MemoryToRegisters::promoteSingleAllocation(
1048
1057
// This can come up if the source contains a withUnsafePointer where
1049
1058
// the pointer escapes. It's illegal code but we should not crash.
1050
1059
// Re-insert a dealloc_stack so that the verifier is happy.
1051
- b.setInsertionPoint (std::next (alloc->getIterator ()));
1052
- b.createDeallocStack (alloc->getLoc (), alloc);
1060
+ auto *next = alloc->getNextInstruction ();
1061
+ SILBuilderWithScope b (next, ctx);
1062
+ b.createDeallocStack (next->getLoc (), alloc);
1053
1063
}
1054
1064
return true ;
1055
1065
}
1056
1066
1057
1067
LLVM_DEBUG (llvm::dbgs () << " *** Need to insert BB arguments for " << *alloc);
1058
1068
1059
1069
// Promote this allocation.
1060
- StackAllocationPromoter (alloc, domInfo, domTreeLevels, b ).run ();
1070
+ StackAllocationPromoter (alloc, domInfo, domTreeLevels, ctx ).run ();
1061
1071
1062
1072
// Make sure that all of the allocations were promoted into registers.
1063
1073
assert (isWriteOnlyAllocation (alloc) && " Non-write uses left behind" );
@@ -1106,7 +1116,6 @@ bool MemoryToRegisters::run() {
1106
1116
namespace {
1107
1117
1108
1118
class SILMem2Reg : public SILFunctionTransform {
1109
-
1110
1119
void run () override {
1111
1120
SILFunction *f = getFunction ();
1112
1121
0 commit comments