@@ -2001,75 +2001,78 @@ LValue SILGenFunction::emitLValue(Expr *e, AccessKind accessKind) {
2001
2001
2002
2002
LValue SILGenLValue::visitRec (Expr *e, AccessKind accessKind,
2003
2003
AbstractionPattern orig) {
2004
- // Non-lvalue types (references, values, metatypes, etc) form the root of a
2005
- // logical l-value.
2006
- if (!e->getType ()->is <LValueType>() && !e->getType ()->is <InOutType>()) {
2007
- // Decide if we can evaluate this expression at +0 for the rest of the
2008
- // lvalue.
2009
- SGFContext Ctx;
2010
- ManagedValue rv;
2011
-
2012
- // Calls through opaque protocols can be done with +0 rvalues. This allows
2013
- // us to avoid materializing copies of existentials.
2014
- if (SGF.SGM .Types .isIndirectPlusZeroSelfParameter (e->getType ()))
2015
- Ctx = SGFContext::AllowGuaranteedPlusZero;
2016
- else if (auto *DRE = dyn_cast<DeclRefExpr>(e)) {
2017
- // Any reference to "self" can be done at +0 so long as it is a direct
2018
- // access, since we know it is guaranteed.
2019
- // TODO: it would be great to factor this even lower into SILGen to the
2020
- // point where we can see that the parameter is +0 guaranteed. Note that
2021
- // this handles the case in initializers where there is actually a stack
2022
- // allocation for it as well.
2023
- if (isa<ParamDecl>(DRE->getDecl ()) &&
2024
- DRE->getDecl ()->getFullName () == SGF.getASTContext ().Id_self &&
2025
- DRE->getDecl ()->isImplicit ()) {
2026
- Ctx = SGFContext::AllowGuaranteedPlusZero;
2027
- if (SGF.SelfInitDelegationState != SILGenFunction::NormalSelf) {
2028
- // This needs to be inlined since there is a Formal Evaluation Scope
2029
- // in emitRValueForDecl that causing any borrow for this LValue to be
2030
- // popped too soon.
2031
- auto *vd = cast<ParamDecl>(DRE->getDecl ());
2032
- ManagedValue selfLValue = SGF.emitLValueForDecl (
2033
- DRE, vd, DRE->getType ()->getCanonicalType (), AccessKind::Read,
2034
- DRE->getAccessSemantics ());
2035
- rv = SGF.emitRValueForSelfInDelegationInit (
2036
- e, DRE->getType ()->getCanonicalType (),
2037
- selfLValue.getLValueAddress (), Ctx)
2038
- .getScalarValue ();
2039
- }
2040
- } else if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl ())) {
2041
- // All let values are guaranteed to be held alive across their lifetime,
2042
- // and won't change once initialized. Any loaded value is good for the
2043
- // duration of this expression evaluation.
2044
- if (VD->isLet ())
2045
- Ctx = SGFContext::AllowGuaranteedPlusZero;
2046
- }
2004
+ // First see if we have an lvalue type. If we do, then quickly handle that and
2005
+ // return.
2006
+ if (e->getType ()->is <LValueType>() || e->getType ()->is <InOutType>()) {
2007
+ auto lv = visit (e, accessKind);
2008
+ // If necessary, handle reabstraction with a SubstToOrigComponent that
2009
+ // handles
2010
+ // writeback in the original representation.
2011
+ if (orig.isValid ()) {
2012
+ auto &origTL = SGF.getTypeLowering (orig, e->getType ()->getRValueType ());
2013
+ if (lv.getTypeOfRValue () != origTL.getLoweredType ().getObjectType ())
2014
+ lv.addSubstToOrigComponent (orig,
2015
+ origTL.getLoweredType ().getObjectType ());
2047
2016
}
2017
+ return lv;
2018
+ }
2048
2019
2049
- if (!rv) {
2050
- // For an rvalue base, apply the reabstraction (if any) eagerly, since
2051
- // there's no need for writeback.
2052
- if (orig.isValid ())
2053
- rv = SGF.emitRValueAsOrig (e, orig,
2054
- SGF.getTypeLowering (orig, e->getType ()->getRValueType ()));
2055
- else
2056
- rv = SGF.emitRValueAsSingleValue (e, Ctx);
2020
+ // Otherwise we have a non-lvalue type (references, values, metatypes,
2021
+ // etc). These act as the root of a logical lvalue.
2022
+ SGFContext Ctx;
2023
+ ManagedValue rv;
2024
+
2025
+ // Calls through opaque protocols can be done with +0 rvalues. This allows
2026
+ // us to avoid materializing copies of existentials.
2027
+ if (SGF.SGM .Types .isIndirectPlusZeroSelfParameter (e->getType ()))
2028
+ Ctx = SGFContext::AllowGuaranteedPlusZero;
2029
+ else if (auto *DRE = dyn_cast<DeclRefExpr>(e)) {
2030
+ // Any reference to "self" can be done at +0 so long as it is a direct
2031
+ // access, since we know it is guaranteed.
2032
+ // TODO: it would be great to factor this even lower into SILGen to the
2033
+ // point where we can see that the parameter is +0 guaranteed. Note that
2034
+ // this handles the case in initializers where there is actually a stack
2035
+ // allocation for it as well.
2036
+ if (isa<ParamDecl>(DRE->getDecl ()) &&
2037
+ DRE->getDecl ()->getFullName () == SGF.getASTContext ().Id_self &&
2038
+ DRE->getDecl ()->isImplicit ()) {
2039
+ Ctx = SGFContext::AllowGuaranteedPlusZero;
2040
+ if (SGF.SelfInitDelegationState != SILGenFunction::NormalSelf) {
2041
+ // This needs to be inlined since there is a Formal Evaluation Scope
2042
+ // in emitRValueForDecl that causing any borrow for this LValue to be
2043
+ // popped too soon.
2044
+ auto *vd = cast<ParamDecl>(DRE->getDecl ());
2045
+ ManagedValue selfLValue =
2046
+ SGF.emitLValueForDecl (DRE, vd, DRE->getType ()->getCanonicalType (),
2047
+ AccessKind::Read, DRE->getAccessSemantics ());
2048
+ rv = SGF.emitRValueForSelfInDelegationInit (
2049
+ e, DRE->getType ()->getCanonicalType (),
2050
+ selfLValue.getLValueAddress (), Ctx)
2051
+ .getScalarValue ();
2052
+ }
2053
+ } else if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl ())) {
2054
+ // All let values are guaranteed to be held alive across their lifetime,
2055
+ // and won't change once initialized. Any loaded value is good for the
2056
+ // duration of this expression evaluation.
2057
+ if (VD->isLet ())
2058
+ Ctx = SGFContext::AllowGuaranteedPlusZero;
2057
2059
}
2058
- CanType formalType = getSubstFormalRValueType (e);
2059
- auto typeData = getValueTypeData (formalType, rv.getValue ());
2060
- LValue lv;
2061
- lv.add <ValueComponent>(rv, None, typeData, /* isRValue=*/ true );
2062
- return lv;
2063
2060
}
2064
2061
2065
- auto lv = visit (e, accessKind);
2066
- // If necessary, handle reabstraction with a SubstToOrigComponent that handles
2067
- // writeback in the original representation.
2068
- if (orig.isValid ()) {
2069
- auto &origTL = SGF.getTypeLowering (orig, e->getType ()->getRValueType ());
2070
- if (lv.getTypeOfRValue () != origTL.getLoweredType ().getObjectType ())
2071
- lv.addSubstToOrigComponent (orig, origTL.getLoweredType ().getObjectType ());
2062
+ if (!rv) {
2063
+ // For an rvalue base, apply the reabstraction (if any) eagerly, since
2064
+ // there's no need for writeback.
2065
+ if (orig.isValid ())
2066
+ rv = SGF.emitRValueAsOrig (
2067
+ e, orig, SGF.getTypeLowering (orig, e->getType ()->getRValueType ()));
2068
+ else
2069
+ rv = SGF.emitRValueAsSingleValue (e, Ctx);
2072
2070
}
2071
+
2072
+ CanType formalType = getSubstFormalRValueType (e);
2073
+ auto typeData = getValueTypeData (formalType, rv.getValue ());
2074
+ LValue lv;
2075
+ lv.add <ValueComponent>(rv, None, typeData, /* isRValue=*/ true );
2073
2076
return lv;
2074
2077
}
2075
2078
0 commit comments