@@ -1406,200 +1406,6 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite Apply) {
14061406 return createApplyWithConcreteType (Apply, COEIs, BuilderCtx);
14071407}
14081408
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-
16031409// / Should replace a call to `getContiguousArrayStorageType<A>(for:)` by the
16041410// / metadata constructor of the return type.
16051411// / getContiguousArrayStorageType<Int>(for:)
@@ -1708,14 +1514,6 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
17081514 }
17091515 }
17101516
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-
17191517 return nullptr ;
17201518}
17211519
0 commit comments