@@ -2030,150 +2030,30 @@ RValue RValueEmitter::visitTupleExpr(TupleExpr *E, SGFContext C) {
20302030 return result;
20312031}
20322032
2033- namespace {
2034-
2035- // / A helper function with context that tries to emit member refs of nominal
2036- // / types avoiding the conservative lvalue logic.
2037- class NominalTypeMemberRefRValueEmitter {
2038- using SelfTy = NominalTypeMemberRefRValueEmitter;
2039-
2040- // / The member ref expression we are emitting.
2041- MemberRefExpr *Expr;
2042-
2043- // / The passed in SGFContext.
2044- SGFContext Context;
2045-
2046- // / The typedecl of the base expression of the member ref expression.
2047- NominalTypeDecl *Base;
2048-
2049- // / The field of the member.
2050- VarDecl *Field;
2051-
2052- public:
2053-
2054- NominalTypeMemberRefRValueEmitter (MemberRefExpr *Expr, SGFContext Context,
2055- NominalTypeDecl *Base)
2056- : Expr(Expr), Context(Context), Base(Base),
2057- Field (cast<VarDecl>(Expr->getMember ().getDecl())) {}
2058-
2059- // / Emit the RValue.
2060- Optional<RValue> emit (SILGenFunction &SGF) {
2061- // If we don't have a class or a struct, bail.
2062- if (!isa<ClassDecl>(Base) && !isa<StructDecl>(Base))
2063- return None;
2064-
2065- // Check that we have a stored access strategy. If we don't bail.
2066- AccessStrategy strategy =
2067- Field->getAccessStrategy (Expr->getAccessSemantics (), AccessKind::Read,
2068- SGF.SGM .M .getSwiftModule (),
2069- SGF.F .getResilienceExpansion ());
2070- if (strategy.getKind () != AccessStrategy::Storage)
2071- return None;
2072-
2073- FormalEvaluationScope scope (SGF);
2074- if (isa<StructDecl>(Base))
2075- return emitStructDecl (SGF);
2076- assert (isa<ClassDecl>(Base) && " Expected class" );
2077- return emitClassDecl (SGF);
2078- }
2079-
2080- NominalTypeMemberRefRValueEmitter (const SelfTy &) = delete;
2081- NominalTypeMemberRefRValueEmitter (SelfTy &&) = delete;
2082- ~NominalTypeMemberRefRValueEmitter () = default ;
2083-
2084- private:
2085- RValue emitStructDecl (SILGenFunction &SGF) {
2086- ManagedValue base =
2087- SGF.emitRValueAsSingleValue (Expr->getBase (),
2088- SGFContext::AllowImmediatePlusZero);
2089- CanType baseFormalType =
2090- Expr->getBase ()->getType ()->getCanonicalType ();
2091- assert (baseFormalType->isMaterializable ());
2092-
2093- RValue result =
2094- SGF.emitRValueForStorageLoad (Expr, base, baseFormalType,
2095- Expr->isSuper (),
2096- Field, {},
2097- Expr->getMember ().getSubstitutions (),
2098- Expr->getAccessSemantics (),
2099- Expr->getType (), Context);
2100- return result;
2101- }
2102-
2103- Optional<RValue> emitClassDecl (SILGenFunction &SGF) {
2104- // If guaranteed plus zero is not ok, we bail.
2105- if (!Context.isGuaranteedPlusZeroOk ())
2106- return None;
2107-
2108- // If the field is not a let, bail. We need to use the lvalue logic.
2109- if (!Field->isLet ())
2110- return None;
2111-
2112- // If we are emitting a delegating init super and we have begun the
2113- // super.init call, since self has been exclusively borrowed, we need to be
2114- // conservative and use the lvalue machinery. This ensures that we properly
2115- // create FormalEvaluationScopes around the access to self.
2116- //
2117- // TODO: This currently turns off this optimization for /all/ classes that
2118- // are accessed as a direct argument to a super.init call. In the future, we
2119- // should be able to be less conservative here by pattern matching if
2120- // something /can not/ be self.
2121- if (SGF.SelfInitDelegationState == SILGenFunction::DidExclusiveBorrowSelf)
2122- return None;
2123-
2124- // Ok, now we know that we are able to emit our base at guaranteed plus zero
2125- // emit base.
2126- ManagedValue base =
2127- SGF.emitRValueAsSingleValue (Expr->getBase (), Context);
2128-
2129- CanType baseFormalType =
2130- Expr->getBase ()->getType ()->getCanonicalType ();
2131- assert (baseFormalType->isMaterializable ());
2132-
2133- // And then emit our property using whether or not base is at +0 to
2134- // discriminate whether or not the base was guaranteed.
2135- RValue result =
2136- SGF.emitRValueForStorageLoad (Expr, base, baseFormalType,
2137- Expr->isSuper (),
2138- Field, {},
2139- Expr->getMember ().getSubstitutions (),
2140- Expr->getAccessSemantics (),
2141- Expr->getType (), Context,
2142- base.isPlusZeroRValueOrTrivial ());
2143- return std::move (result);
2144- }
2145- };
2146-
2147- } // end anonymous namespace
2148-
2149- RValue RValueEmitter::visitMemberRefExpr (MemberRefExpr *E, SGFContext C) {
2150- assert (!E->getType ()->is <LValueType>() &&
2033+ RValue RValueEmitter::visitMemberRefExpr (MemberRefExpr *e,
2034+ SGFContext resultCtx) {
2035+ assert (!e->getType ()->is <LValueType>() &&
21512036 " RValueEmitter shouldn't be called on lvalues" );
21522037
2153- if (isa<TypeDecl>(E ->getMember ().getDecl ())) {
2038+ if (isa<TypeDecl>(e ->getMember ().getDecl ())) {
21542039 // Emit the metatype for the associated type.
2155- visit (E ->getBase ());
2156- SILValue MT =
2157- SGF.B .createMetatype (E , SGF.getLoweredLoadableType (E ->getType ()));
2158- return RValue (SGF, E , ManagedValue::forUnmanaged (MT ));
2040+ visit (e ->getBase ());
2041+ SILValue mt =
2042+ SGF.B .createMetatype (e , SGF.getLoweredLoadableType (e ->getType ()));
2043+ return RValue (SGF, e , ManagedValue::forUnmanaged (mt ));
21592044 }
21602045
2161- // If we have a nominal type decl as our base, try to emit the base rvalue's
2162- // member using special logic that will let us avoid extra retains
2163- // and releases.
2164- if (auto *N = E->getBase ()->getType ()->getNominalOrBoundGenericNominal ())
2165- if (auto RV = NominalTypeMemberRefRValueEmitter (E, C, N).emit (SGF))
2166- return RValue (std::move (RV.getValue ()));
2167-
21682046 // Everything else should use the l-value logic.
21692047
21702048 // Any writebacks for this access are tightly scoped.
21712049 FormalEvaluationScope scope (SGF);
21722050
2173- LValue lv = SGF.emitLValue (E, SGFAccessKind::OwnedObjectRead);
2174- // We can't load at +0 without further analysis, since the formal access into
2175- // the lvalue will end immediately.
2176- return SGF.emitLoadOfLValue (E, std::move (lv), C.withFollowingSideEffects ());
2051+ LValue lv = SGF.emitLValue (e, SGFAccessKind::OwnedObjectRead);
2052+
2053+ // Otherwise, we can't load at +0 without further analysis, since the formal
2054+ // access into the lvalue will end immediately.
2055+ return SGF.emitLoadOfLValue (e, std::move (lv),
2056+ resultCtx.withFollowingSideEffects ());
21772057}
21782058
21792059RValue RValueEmitter::visitDynamicMemberRefExpr (DynamicMemberRefExpr *E,
0 commit comments