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