27
27
#include " swift/SIL/SILBuilder.h"
28
28
#include " swift/SIL/SILFunction.h"
29
29
#include " swift/SIL/SILVisitor.h"
30
+ #include " swift/SILOptimizer/Analysis/SimplifyInstruction.h"
30
31
#include " swift/SILOptimizer/PassManager/Transforms.h"
32
+ #include " swift/SILOptimizer/Utils/Local.h"
31
33
#include " llvm/Support/CommandLine.h"
32
34
33
35
using namespace swift ;
@@ -248,6 +250,9 @@ static void splitDestructure(SILBuilder &B, SILInstruction *I, SILValue Op) {
248
250
assert ((isa<DestructureStructInst>(I) || isa<DestructureTupleInst>(I)) &&
249
251
" Only destructure operations can be passed to splitDestructure" );
250
252
253
+ // First before we destructure anything, see if we can simplify any of our
254
+ // instruction operands.
255
+
251
256
SILModule &M = I->getModule ();
252
257
SILLocation Loc = I->getLoc ();
253
258
SILType OpType = Op->getType ();
@@ -256,16 +261,33 @@ static void splitDestructure(SILBuilder &B, SILInstruction *I, SILValue Op) {
256
261
Projection::getFirstLevelProjections (OpType, M, Projections);
257
262
assert (Projections.size () == I->getNumResults ());
258
263
259
- llvm::SmallVector<SILValue, 8 > NewValues;
260
- for (unsigned i : indices (Projections)) {
261
- const auto &Proj = Projections[i];
262
- NewValues.push_back (Proj.createObjectProjection (B, Loc, Op).get ());
263
- assert (NewValues.back ()->getType () == I->getResults ()[i]->getType () &&
264
- " Expected created projections and results to be the same types" );
264
+ auto Results = I->getResults ();
265
+ for (unsigned Index : indices (Results)) {
266
+ SILValue Result = Results[Index];
267
+
268
+ // If our result doesnt have any uses, do not emit instructions, just skip
269
+ // it.
270
+ if (Result->use_empty ())
271
+ continue ;
272
+
273
+ // Otherwise, create a projection.
274
+ const auto &Proj = Projections[Index];
275
+ SingleValueInstruction *ProjInst =
276
+ Proj.createObjectProjection (B, Loc, Op).get ();
277
+
278
+ // If we can simplify, do so.
279
+ if (SILValue NewV = simplifyInstruction (ProjInst)) {
280
+ Result->replaceAllUsesWith (NewV);
281
+ ProjInst->eraseFromParent ();
282
+ continue ;
283
+ }
284
+
285
+ Result->replaceAllUsesWith (ProjInst);
265
286
}
266
287
267
- I->replaceAllUsesPairwiseWith (NewValues);
268
- I->eraseFromParent ();
288
+ // We may have exposed trivially dead instructions due to
289
+ // simplifyInstruction... delete I and any such instructions!
290
+ recursivelyDeleteTriviallyDeadInstructions (I, true );
269
291
}
270
292
271
293
bool OwnershipModelEliminatorVisitor::visitDestructureStructInst (
0 commit comments