9
9
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
- //
13
- // Simplify aggregate instructions into scalar instructions.
14
- //
12
+ // /
13
+ // / \file
14
+ // /
15
+ // / Simplify aggregate instructions into scalar instructions using simple
16
+ // / peephole transformations.
17
+ // /
15
18
// ===----------------------------------------------------------------------===//
16
19
17
20
#define DEBUG_TYPE " sil-lower-aggregate-instrs"
26
29
#include " swift/SILOptimizer/Utils/InstOptUtils.h"
27
30
#include " llvm/ADT/Statistic.h"
28
31
#include " llvm/Support/Debug.h"
32
+
29
33
using namespace swift ;
30
34
using namespace swift ::Lowering;
31
35
@@ -70,154 +74,156 @@ STATISTIC(NumExpand, "Number of instructions expanded");
70
74
// / // no retain of %new!
71
75
// / // no load/release of %old!
72
76
// / store %new to %1 : $*T
73
- static bool expandCopyAddr (CopyAddrInst *CA ) {
74
- SILModule &M = CA-> getModule ();
75
- SILFunction *F = CA-> getFunction ();
76
- SILValue Source = CA ->getSrc ();
77
+ static bool expandCopyAddr (CopyAddrInst *cai ) {
78
+ SILFunction *fn = cai-> getFunction ();
79
+ SILModule & module = cai-> getModule ();
80
+ SILValue source = cai ->getSrc ();
77
81
78
82
// If we have an address only type don't do anything.
79
- SILType SrcType = Source ->getType ();
80
- if (SrcType .isAddressOnly (*F ))
83
+ SILType srcType = source ->getType ();
84
+ if (srcType .isAddressOnly (*fn ))
81
85
return false ;
82
86
83
- bool expand = shouldExpand (M, SrcType .getObjectType ());
87
+ bool expand = shouldExpand (module , srcType .getObjectType ());
84
88
using TypeExpansionKind = Lowering::TypeLowering::TypeExpansionKind;
85
89
auto expansionKind = expand ? TypeExpansionKind::MostDerivedDescendents
86
90
: TypeExpansionKind::None;
87
91
88
- SILBuilderWithScope Builder (CA );
92
+ SILBuilderWithScope builder (cai );
89
93
90
94
// %new = load %0 : $*T
91
- LoadInst *New = Builder .createLoad (CA ->getLoc (), Source ,
92
- LoadOwnershipQualifier::Unqualified);
95
+ LoadInst *newValue = builder .createLoad (cai ->getLoc (), source ,
96
+ LoadOwnershipQualifier::Unqualified);
93
97
94
- SILValue Destination = CA ->getDest ();
98
+ SILValue destAddr = cai ->getDest ();
95
99
96
100
// If our object type is not trivial, we may need to release the old value and
97
101
// retain the new one.
98
102
99
- auto &TL = F ->getTypeLowering (SrcType );
103
+ auto &typeLowering = fn ->getTypeLowering (srcType );
100
104
101
105
// If we have a non-trivial type...
102
- if (!TL.isTrivial ()) {
103
-
106
+ if (!typeLowering.isTrivial ()) {
104
107
// If we are not initializing:
105
108
// %old = load %1 : $*T
106
- IsInitialization_t IsInit = CA ->isInitializationOfDest ();
107
- LoadInst *Old = nullptr ;
108
- if (IsInitialization_t::IsNotInitialization == IsInit ) {
109
- Old = Builder .createLoad (CA ->getLoc (), Destination ,
110
- LoadOwnershipQualifier::Unqualified);
109
+ auto isInit = cai ->isInitializationOfDest ();
110
+ LoadInst *oldValue = nullptr ;
111
+ if (IsInitialization_t::IsNotInitialization == isInit ) {
112
+ oldValue = builder .createLoad (cai ->getLoc (), destAddr ,
113
+ LoadOwnershipQualifier::Unqualified);
111
114
}
112
115
113
116
// If we are not taking and have a reference type:
114
117
// strong_retain %new : $*T
115
118
// or if we have a non-trivial non-reference type.
116
119
// retain_value %new : $*T
117
- IsTake_t IsTake = CA ->isTakeOfSrc ();
118
- if (IsTake_t::IsNotTake == IsTake) {
119
- TL. emitLoweredCopyValue (Builder, CA-> getLoc (), New, expansionKind);
120
+ if ( IsTake_t::IsNotTake == cai ->isTakeOfSrc ()) {
121
+ typeLowering. emitLoweredCopyValue (builder, cai-> getLoc (), newValue,
122
+ expansionKind);
120
123
}
121
124
122
125
// If we are not initializing:
123
126
// strong_release %old : $*T
124
127
// *or*
125
128
// release_value %old : $*T
126
- if (Old) {
127
- TL.emitLoweredDestroyValue (Builder, CA->getLoc (), Old, expansionKind);
129
+ if (oldValue) {
130
+ typeLowering.emitLoweredDestroyValue (builder, cai->getLoc (), oldValue,
131
+ expansionKind);
128
132
}
129
133
}
130
134
131
135
// Create the store.
132
- Builder .createStore (CA ->getLoc (), New, Destination ,
136
+ builder .createStore (cai ->getLoc (), newValue, destAddr ,
133
137
StoreOwnershipQualifier::Unqualified);
134
138
135
139
++NumExpand;
136
140
return true ;
137
141
}
138
142
139
- static bool expandDestroyAddr (DestroyAddrInst *DA ) {
140
- SILFunction *F = DA ->getFunction ();
141
- SILModule &Module = DA ->getModule ();
142
- SILBuilderWithScope Builder (DA );
143
+ static bool expandDestroyAddr (DestroyAddrInst *dai ) {
144
+ SILFunction *fn = dai ->getFunction ();
145
+ SILModule &module = dai ->getModule ();
146
+ SILBuilderWithScope builder (dai );
143
147
144
148
// Strength reduce destroy_addr inst into release/store if
145
149
// we have a non-address only type.
146
- SILValue Addr = DA ->getOperand ();
150
+ SILValue addr = dai ->getOperand ();
147
151
148
152
// If we have an address only type, do nothing.
149
- SILType Type = Addr ->getType ();
150
- if (Type .isAddressOnly (*F ))
153
+ SILType type = addr ->getType ();
154
+ if (type .isAddressOnly (*fn ))
151
155
return false ;
152
156
153
- bool expand = shouldExpand (Module, Type .getObjectType ());
157
+ bool expand = shouldExpand (module , type .getObjectType ());
154
158
155
159
// If we have a non-trivial type...
156
- if (!Type .isTrivial (*F )) {
160
+ if (!type .isTrivial (*fn )) {
157
161
// If we have a type with reference semantics, emit a load/strong release.
158
- LoadInst *LI = Builder .createLoad (DA ->getLoc (), Addr ,
162
+ LoadInst *li = builder .createLoad (dai ->getLoc (), addr ,
159
163
LoadOwnershipQualifier::Unqualified);
160
- auto &TL = F ->getTypeLowering (Type );
164
+ auto &typeLowering = fn ->getTypeLowering (type );
161
165
using TypeExpansionKind = Lowering::TypeLowering::TypeExpansionKind;
162
166
auto expansionKind = expand ? TypeExpansionKind::MostDerivedDescendents
163
167
: TypeExpansionKind::None;
164
- TL.emitLoweredDestroyValue (Builder, DA->getLoc (), LI, expansionKind);
168
+ typeLowering.emitLoweredDestroyValue (builder, dai->getLoc (), li,
169
+ expansionKind);
165
170
}
166
171
167
172
++NumExpand;
168
173
return true ;
169
174
}
170
175
171
- static bool expandReleaseValue (ReleaseValueInst *DV ) {
172
- SILFunction *F = DV ->getFunction ();
173
- SILModule &Module = DV ->getModule ();
174
- SILBuilderWithScope Builder (DV );
176
+ static bool expandReleaseValue (ReleaseValueInst *rvi ) {
177
+ SILFunction *fn = rvi ->getFunction ();
178
+ SILModule &module = rvi ->getModule ();
179
+ SILBuilderWithScope builder (rvi );
175
180
176
181
// Strength reduce destroy_addr inst into release/store if
177
182
// we have a non-address only type.
178
- SILValue Value = DV ->getOperand ();
183
+ SILValue value = rvi ->getOperand ();
179
184
180
185
// If we have an address only type, do nothing.
181
- SILType Type = Value ->getType ();
182
- assert (!SILModuleConventions (Module ).useLoweredAddresses ()
183
- || Type .isLoadable (*F ) &&
184
- " release_value should never be called on a non-loadable type." );
186
+ SILType type = value ->getType ();
187
+ assert (!SILModuleConventions (module ).useLoweredAddresses () ||
188
+ type .isLoadable (*fn ) &&
189
+ " release_value should never be called on a non-loadable type." );
185
190
186
- if (!shouldExpand (Module, Type .getObjectType ()))
191
+ if (!shouldExpand (module , type .getObjectType ()))
187
192
return false ;
188
193
189
- auto &TL = F ->getTypeLowering (Type );
190
- TL.emitLoweredDestroyValueMostDerivedDescendents (Builder, DV ->getLoc (),
191
- Value );
194
+ auto &TL = fn ->getTypeLowering (type );
195
+ TL.emitLoweredDestroyValueMostDerivedDescendents (builder, rvi ->getLoc (),
196
+ value );
192
197
193
- LLVM_DEBUG (llvm::dbgs () << " Expanding Destroy Value : " << *DV );
198
+ LLVM_DEBUG (llvm::dbgs () << " Expanding: " << *rvi );
194
199
195
200
++NumExpand;
196
201
return true ;
197
202
}
198
203
199
- static bool expandRetainValue (RetainValueInst *CV ) {
200
- SILFunction *F = CV ->getFunction ();
201
- SILModule &Module = CV ->getModule ();
202
- SILBuilderWithScope Builder (CV );
204
+ static bool expandRetainValue (RetainValueInst *rvi ) {
205
+ SILFunction *fn = rvi ->getFunction ();
206
+ SILModule &module = rvi ->getModule ();
207
+ SILBuilderWithScope builder (rvi );
203
208
204
209
// Strength reduce destroy_addr inst into release/store if
205
210
// we have a non-address only type.
206
- SILValue Value = CV ->getOperand ();
211
+ SILValue value = rvi ->getOperand ();
207
212
208
213
// If we have an address only type, do nothing.
209
- SILType Type = Value ->getType ();
210
- assert (!SILModuleConventions (Module ).useLoweredAddresses ()
211
- || Type .isLoadable (*F ) &&
212
- " Copy Value can only be called on loadable types." );
214
+ SILType type = value ->getType ();
215
+ assert (!SILModuleConventions (module ).useLoweredAddresses () ||
216
+ type .isLoadable (*fn ) &&
217
+ " Copy Value can only be called on loadable types." );
213
218
214
- if (!shouldExpand (Module, Type .getObjectType ()))
219
+ if (!shouldExpand (module , type .getObjectType ()))
215
220
return false ;
216
221
217
- auto &TL = F->getTypeLowering (Type);
218
- TL.emitLoweredCopyValueMostDerivedDescendents (Builder, CV->getLoc (), Value);
222
+ auto &typeLowering = fn->getTypeLowering (type);
223
+ typeLowering.emitLoweredCopyValueMostDerivedDescendents (builder,
224
+ rvi->getLoc (), value);
219
225
220
- LLVM_DEBUG (llvm::dbgs () << " Expanding Copy Value : " << *CV );
226
+ LLVM_DEBUG (llvm::dbgs () << " Expanding: " << *rvi );
221
227
222
228
++NumExpand;
223
229
return true ;
@@ -227,73 +233,77 @@ static bool expandRetainValue(RetainValueInst *CV) {
227
233
// Top Level Driver
228
234
// ===----------------------------------------------------------------------===//
229
235
230
- static bool processFunction (SILFunction &Fn ) {
231
- bool Changed = false ;
232
- for (auto BI = Fn. begin (), BE = Fn. end (); BI != BE; ++BI ) {
233
- auto II = BI-> begin (), IE = BI-> end ();
234
- while (II != IE ) {
235
- SILInstruction *Inst = &*II ;
236
+ static bool processFunction (SILFunction &fn ) {
237
+ bool changed = false ;
238
+ for (auto &block : fn ) {
239
+ auto ii = block. begin (), ie = block. end ();
240
+ while (ii != ie ) {
241
+ SILInstruction *inst = &*ii ;
236
242
237
- LLVM_DEBUG (llvm::dbgs () << " Visiting: " << *Inst );
243
+ LLVM_DEBUG (llvm::dbgs () << " Visiting: " << *inst );
238
244
239
- if (auto *CA = dyn_cast<CopyAddrInst>(Inst ))
240
- if (expandCopyAddr (CA )) {
241
- ++II ;
242
- CA ->eraseFromParent ();
243
- Changed = true ;
245
+ if (auto *cai = dyn_cast<CopyAddrInst>(inst ))
246
+ if (expandCopyAddr (cai )) {
247
+ ++ii ;
248
+ cai ->eraseFromParent ();
249
+ changed = true ;
244
250
continue ;
245
251
}
246
252
247
- if (auto *DA = dyn_cast<DestroyAddrInst>(Inst ))
248
- if (expandDestroyAddr (DA )) {
249
- ++II ;
250
- DA ->eraseFromParent ();
251
- Changed = true ;
253
+ if (auto *dai = dyn_cast<DestroyAddrInst>(inst ))
254
+ if (expandDestroyAddr (dai )) {
255
+ ++ii ;
256
+ dai ->eraseFromParent ();
257
+ changed = true ;
252
258
continue ;
253
259
}
254
260
255
- if (auto *CV = dyn_cast<RetainValueInst>(Inst ))
256
- if (expandRetainValue (CV )) {
257
- ++II ;
258
- CV ->eraseFromParent ();
259
- Changed = true ;
261
+ if (auto *rvi = dyn_cast<RetainValueInst>(inst ))
262
+ if (expandRetainValue (rvi )) {
263
+ ++ii ;
264
+ rvi ->eraseFromParent ();
265
+ changed = true ;
260
266
continue ;
261
267
}
262
268
263
- if (auto *DV = dyn_cast<ReleaseValueInst>(Inst ))
264
- if (expandReleaseValue (DV )) {
265
- ++II ;
266
- DV ->eraseFromParent ();
267
- Changed = true ;
269
+ if (auto *rvi = dyn_cast<ReleaseValueInst>(inst ))
270
+ if (expandReleaseValue (rvi )) {
271
+ ++ii ;
272
+ rvi ->eraseFromParent ();
273
+ changed = true ;
268
274
continue ;
269
275
}
270
276
271
- ++II ;
277
+ ++ii ;
272
278
}
273
279
}
274
- return Changed ;
280
+ return changed ;
275
281
}
276
282
283
+ // ===----------------------------------------------------------------------===//
284
+ // Top Level Entrypoint
285
+ // ===----------------------------------------------------------------------===//
286
+
277
287
namespace {
288
+
278
289
class SILLowerAggregate : public SILFunctionTransform {
279
290
280
291
// / The entry point to the transformation.
281
292
void run () override {
282
- SILFunction *F = getFunction ();
293
+ SILFunction *f = getFunction ();
283
294
// FIXME: Can we support ownership?
284
- if (F ->hasOwnership ())
295
+ if (f ->hasOwnership ())
285
296
return ;
286
- LLVM_DEBUG (llvm::dbgs () << " ***** LowerAggregate on function: " <<
287
- F ->getName () << " *****\n " );
288
- bool Changed = processFunction (*F );
289
- if (Changed ) {
297
+ LLVM_DEBUG (llvm::dbgs () << " ***** LowerAggregate on function: "
298
+ << f ->getName () << " *****\n " );
299
+ bool changed = processFunction (*f );
300
+ if (changed ) {
290
301
invalidateAnalysis (SILAnalysis::InvalidationKind::CallsAndInstructions);
291
302
}
292
303
}
293
-
294
304
};
295
- } // end anonymous namespace
296
305
306
+ } // end anonymous namespace
297
307
298
308
SILTransform *swift::createLowerAggregateInstrs () {
299
309
return new SILLowerAggregate ();
0 commit comments