2727#include " swift/SIL/SILBuilder.h"
2828#include " swift/SIL/SILFunction.h"
2929#include " swift/SIL/SILVisitor.h"
30+ #include " swift/SILOptimizer/Analysis/SimplifyInstruction.h"
3031#include " swift/SILOptimizer/PassManager/Transforms.h"
32+ #include " swift/SILOptimizer/Utils/Local.h"
3133#include " llvm/Support/CommandLine.h"
3234
3335using namespace swift ;
@@ -248,6 +250,9 @@ static void splitDestructure(SILBuilder &B, SILInstruction *I, SILValue Op) {
248250 assert ((isa<DestructureStructInst>(I) || isa<DestructureTupleInst>(I)) &&
249251 " Only destructure operations can be passed to splitDestructure" );
250252
253+ // First before we destructure anything, see if we can simplify any of our
254+ // instruction operands.
255+
251256 SILModule &M = I->getModule ();
252257 SILLocation Loc = I->getLoc ();
253258 SILType OpType = Op->getType ();
@@ -256,16 +261,33 @@ static void splitDestructure(SILBuilder &B, SILInstruction *I, SILValue Op) {
256261 Projection::getFirstLevelProjections (OpType, M, Projections);
257262 assert (Projections.size () == I->getNumResults ());
258263
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);
265286 }
266287
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 );
269291}
270292
271293bool OwnershipModelEliminatorVisitor::visitDestructureStructInst (
0 commit comments