@@ -1407,200 +1407,6 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite Apply) {
1407
1407
return createApplyWithConcreteType (Apply, COEIs, BuilderCtx);
1408
1408
}
1409
1409
1410
- // / Check that all users of the apply are retain/release ignoring one
1411
- // / user.
1412
- static bool
1413
- hasOnlyRecursiveOwnershipUsers (ApplyInst *ai, SILInstruction *ignoreUser,
1414
- SmallVectorImpl<SILInstruction *> &foundUsers) {
1415
- SmallVector<Operand *, 32 > worklist (getNonDebugUses (ai));
1416
- while (!worklist.empty ()) {
1417
- auto *use = worklist.pop_back_val ();
1418
- auto *user = use->getUser ();
1419
- if (user == ignoreUser)
1420
- continue ;
1421
-
1422
- if (!isa<RetainValueInst>(user) && !isa<ReleaseValueInst>(user) &&
1423
- !isa<StrongRetainInst>(user) && !isa<StrongReleaseInst>(user) &&
1424
- !isa<CopyValueInst>(user) && !isa<DestroyValueInst>(user) &&
1425
- !isa<BeginBorrowInst>(user) && !isa<EndBorrowInst>(user) &&
1426
- !user->isDebugInstruction ())
1427
- return false ;
1428
-
1429
- if (auto *cvi = dyn_cast<CopyValueInst>(user))
1430
- for (auto *use : cvi->getUses ())
1431
- worklist.push_back (use);
1432
- if (auto *bbi = dyn_cast<BeginBorrowInst>(user))
1433
- for (auto *use : bbi->getUses ())
1434
- worklist.push_back (use);
1435
-
1436
- foundUsers.push_back (user);
1437
- }
1438
- return true ;
1439
- }
1440
-
1441
- // / We only know how to simulate reference call effects for unary
1442
- // / function calls that take their argument @owned or @guaranteed and return an
1443
- // / @owned value.
1444
- static bool knowHowToEmitReferenceCountInsts (ApplyInst *Call) {
1445
- if (Call->getNumArguments () != 1 )
1446
- return false ;
1447
-
1448
- // FIXME: We could handle dynamic_function_ref instructions here because the
1449
- // code only looks at the function type.
1450
- FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(Call->getCallee ());
1451
- if (!FRI)
1452
- return false ;
1453
- SILFunction *F = FRI->getReferencedFunction ();
1454
- auto FnTy = F->getLoweredFunctionType ();
1455
-
1456
- // Look at the result type.
1457
- if (FnTy->getNumResults () != 1 )
1458
- return false ;
1459
- auto ResultInfo = FnTy->getResults ()[0 ];
1460
- if (ResultInfo.getConvention () != ResultConvention::Owned)
1461
- return false ;
1462
-
1463
- // Look at the parameter.
1464
- auto Params = FnTy->getParameters ();
1465
- (void ) Params;
1466
- assert (Params.size () == 1 && " Expect one parameter" );
1467
- auto ParamConv = FnTy->getParameters ()[0 ].getConvention ();
1468
-
1469
- return ParamConv == ParameterConvention::Direct_Owned ||
1470
- ParamConv == ParameterConvention::Direct_Guaranteed;
1471
- }
1472
-
1473
- // / Add reference counting operations equal to the effect of the call.
1474
- static void emitMatchingRCAdjustmentsForCall (ApplyInst *Call, SILValue OnX) {
1475
- FunctionRefInst *FRI = cast<FunctionRefInst>(Call->getCallee ());
1476
- SILFunction *F = FRI->getReferencedFunction ();
1477
- auto FnTy = F->getLoweredFunctionType ();
1478
- assert (FnTy->getNumResults () == 1 );
1479
- auto ResultInfo = FnTy->getResults ()[0 ];
1480
- (void ) ResultInfo;
1481
-
1482
- assert (ResultInfo.getConvention () == ResultConvention::Owned &&
1483
- " Expect a @owned return" );
1484
- assert (Call->getNumArguments () == 1 && " Expect a unary call" );
1485
-
1486
- // Emit a copy for the @owned return.
1487
- SILBuilderWithScope Builder (Call);
1488
- OnX = Builder.emitCopyValueOperation (Call->getLoc (), OnX);
1489
-
1490
- // Emit a destroy for the @owned parameter, or none for a @guaranteed
1491
- // parameter.
1492
- auto Params = FnTy->getParameters ();
1493
- (void ) Params;
1494
- assert (Params.size () == 1 && " Expect one parameter" );
1495
- auto ParamInfo = FnTy->getParameters ()[0 ].getConvention ();
1496
- assert (ParamInfo == ParameterConvention::Direct_Owned ||
1497
- ParamInfo == ParameterConvention::Direct_Guaranteed);
1498
-
1499
- if (ParamInfo == ParameterConvention::Direct_Owned)
1500
- Builder.emitDestroyValueOperation (Call->getLoc (), OnX);
1501
- }
1502
-
1503
- // Replace an application of a cast composition f_inverse(f(x)) by x.
1504
- //
1505
- // NOTE: The instruction we are actually folding is f_inverse.
1506
- bool SILCombiner::optimizeIdentityCastComposition (ApplyInst *fInverseApply ,
1507
- StringRef fInverseName ,
1508
- StringRef fName ) {
1509
- // Needs to have a known semantics.
1510
- if (!fInverseApply ->hasSemantics (fInverseName ))
1511
- return false ;
1512
-
1513
- // We need to know how to replace the call by reference counting instructions.
1514
- if (!knowHowToEmitReferenceCountInsts (fInverseApply ))
1515
- return false ;
1516
-
1517
- // Need to have a matching 'f'.
1518
- auto fInverseArg0 = lookThroughOwnershipInsts (fInverseApply ->getArgument (0 ));
1519
- auto *fApply = dyn_cast<ApplyInst>(fInverseArg0 );
1520
- if (!fApply )
1521
- return false ;
1522
- if (!fApply ->hasSemantics (fName ))
1523
- return false ;
1524
- if (!knowHowToEmitReferenceCountInsts (fApply ))
1525
- return false ;
1526
-
1527
- // The types must match.
1528
- if (fApply ->getArgument (0 )->getType () != fInverseApply ->getType ())
1529
- return false ;
1530
-
1531
- // Gather up all retain
1532
- SmallVector<SILInstruction *, 16 > foundOwnershipUsers;
1533
- if (!hasOnlyRecursiveOwnershipUsers (fApply , fInverseApply /* user to ignore*/ ,
1534
- foundOwnershipUsers))
1535
- return false ;
1536
-
1537
- // Okay, now we know we can remove the calls.
1538
- auto arg0 = fApply ->getArgument (0 );
1539
-
1540
- if (fApply ->getFunction ()->hasOwnership ()) {
1541
- // First perform an ownership RAUW+erase of arg0 and inverse apply. The OSSA
1542
- // RAUW helper will copy arg0 if needed. We need to do this before anything
1543
- // else since the utility assumes OSSA is in correct form.
1544
- OwnershipRAUWHelper helper (ownershipFixupContext, fInverseApply , arg0);
1545
- if (!helper)
1546
- return false ;
1547
- helper.perform ();
1548
-
1549
- // Now remove the apply, inserting a destroy_value if we need to it arg0.
1550
- if (fApply ->getArgumentRef (0 ).isLifetimeEnding ()) {
1551
- SILBuilderWithScope b (fApply , Builder);
1552
- if (arg0.getOwnershipKind () == OwnershipKind::Owned) {
1553
- b.emitDestroyValueOperation (fApply ->getLoc (), arg0);
1554
- } else if (arg0.getOwnershipKind () == OwnershipKind::Guaranteed) {
1555
- b.emitEndBorrowOperation (fApply ->getLoc (), arg0);
1556
- }
1557
- }
1558
- eraseInstIncludingUsers (fApply );
1559
-
1560
- return true ;
1561
- }
1562
-
1563
- // Redirect f's result's retains/releases to affect x.
1564
- //
1565
- // NOTE: This part of the code is only used in non-ownership SIL since we
1566
- // represent ARC operations there with copy_value, destroy_value that work
1567
- // with all types.
1568
- for (auto *ownershipUser : foundOwnershipUsers) {
1569
- // X might not be strong_retain/release'able. Replace it by a
1570
- // retain/release_value on X instead.
1571
- if (isa<StrongRetainInst>(ownershipUser)) {
1572
- SILBuilderWithScope b (ownershipUser, Builder);
1573
- b.createRetainValue (
1574
- ownershipUser->getLoc (), arg0,
1575
- cast<StrongRetainInst>(ownershipUser)->getAtomicity ());
1576
- eraseInstFromFunction (*ownershipUser);
1577
- continue ;
1578
- }
1579
- if (isa<StrongReleaseInst>(ownershipUser)) {
1580
- SILBuilderWithScope b (ownershipUser, Builder);
1581
- b.createReleaseValue (
1582
- ownershipUser->getLoc (), arg0,
1583
- cast<StrongReleaseInst>(ownershipUser)->getAtomicity ());
1584
- eraseInstFromFunction (*ownershipUser);
1585
- continue ;
1586
- }
1587
- ownershipUser->setOperand (0 , arg0);
1588
- // Simulate the reference count effects of the calls before removing
1589
- // them.
1590
- emitMatchingRCAdjustmentsForCall (fApply , arg0);
1591
- emitMatchingRCAdjustmentsForCall (fInverseApply , arg0);
1592
- }
1593
-
1594
- // Replace users of f_inverse by x.
1595
- replaceInstUsesWith (*fInverseApply , arg0);
1596
-
1597
- // Remove the calls.
1598
- eraseInstFromFunction (*fInverseApply );
1599
- eraseInstFromFunction (*fApply );
1600
-
1601
- return true ;
1602
- }
1603
-
1604
1410
// / Should replace a call to `getContiguousArrayStorageType<A>(for:)` by the
1605
1411
// / metadata constructor of the return type.
1606
1412
// / getContiguousArrayStorageType<Int>(for:)
@@ -1709,14 +1515,6 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
1709
1515
}
1710
1516
}
1711
1517
1712
- // Optimize f_inverse(f(x)) -> x.
1713
- if (optimizeIdentityCastComposition (AI, " convertFromObjectiveC" ,
1714
- " convertToObjectiveC" ))
1715
- return nullptr ;
1716
- if (optimizeIdentityCastComposition (AI, " convertToObjectiveC" ,
1717
- " convertFromObjectiveC" ))
1718
- return nullptr ;
1719
-
1720
1518
return nullptr ;
1721
1519
}
1722
1520
0 commit comments