Skip to content

Commit 61c2f2c

Browse files
authored
Merge pull request #9625 from slavapestov/load-expr-fix-and-cleanups
Fix for nested LoadExprs fix and cleanups
2 parents 7ad9cbe + 159807d commit 61c2f2c

File tree

3 files changed

+69
-16
lines changed

3 files changed

+69
-16
lines changed

lib/SILGen/SILGenFunction.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1416,7 +1416,13 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
14161416

14171417
/// Mapping from active opaque value expressions to their values,
14181418
/// along with a bit for each indicating whether it has been consumed yet.
1419-
llvm::DenseMap<OpaqueValueExpr *, OpaqueValueState> OpaqueValues;
1419+
llvm::SmallDenseMap<OpaqueValueExpr *, OpaqueValueState>
1420+
OpaqueValues;
1421+
1422+
/// A mapping from opaque value expressions to the open-existential
1423+
/// expression that determines them, used while lowering lvalues.
1424+
llvm::SmallDenseMap<OpaqueValueExpr *, OpenExistentialExpr *>
1425+
OpaqueValueExprs;
14201426

14211427
/// RAII object that introduces a temporary binding for an opaque value.
14221428
///

lib/SILGen/SILGenLValue.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,6 @@ SILGenFunction::getUnknownEnforcement(VarDecl *var) {
167167
class LLVM_LIBRARY_VISIBILITY SILGenLValue
168168
: public Lowering::ExprVisitor<SILGenLValue, LValue, AccessKind>
169169
{
170-
/// A mapping from opaque value expressions to the open-existential
171-
/// expression that determines them.
172-
llvm::SmallDenseMap<OpaqueValueExpr *, OpenExistentialExpr *>
173-
openedExistentials;
174170

175171
public:
176172
SILGenFunction &SGF;
@@ -591,6 +587,8 @@ namespace {
591587
"base for open existential component must be an existential");
592588
assert(base.getType().isAddress() &&
593589
"base value of open-existential component was not an address?");
590+
assert(base.getType().getPreferredExistentialRepresentation(SGF.SGM.M)
591+
== ExistentialRepresentation::Opaque);
594592

595593
SILValue addr = SGF.B.createOpenExistentialAddr(
596594
loc, base.getValue(), getTypeOfRValue().getAddressType(),
@@ -1909,11 +1907,11 @@ LValue SILGenLValue::visitDeclRefExpr(DeclRefExpr *e, AccessKind accessKind) {
19091907
LValue SILGenLValue::visitOpaqueValueExpr(OpaqueValueExpr *e,
19101908
AccessKind accessKind) {
19111909
// Handle an opaque lvalue that refers to an opened existential.
1912-
auto known = openedExistentials.find(e);
1913-
if (known != openedExistentials.end()) {
1910+
auto known = SGF.OpaqueValueExprs.find(e);
1911+
if (known != SGF.OpaqueValueExprs.end()) {
19141912
// Dig the open-existential expression out of the list.
19151913
OpenExistentialExpr *opened = known->second;
1916-
openedExistentials.erase(known);
1914+
SGF.OpaqueValueExprs.erase(known);
19171915

19181916
// Do formal evaluation of the underlying existential lvalue.
19191917
LValue lv = visitRec(opened->getExistentialValue(), accessKind);
@@ -2206,15 +2204,15 @@ LValue SILGenLValue::visitOpenExistentialExpr(OpenExistentialExpr *e,
22062204

22072205
// Record the fact that we're opening this existential. The actual
22082206
// opening operation will occur when we see the OpaqueValueExpr.
2209-
bool inserted = openedExistentials.insert({e->getOpaqueValue(), e}).second;
2207+
bool inserted = SGF.OpaqueValueExprs.insert({e->getOpaqueValue(), e}).second;
22102208
(void)inserted;
22112209
assert(inserted && "already have this opened existential?");
22122210

22132211
// Visit the subexpression.
22142212
LValue lv = visitRec(e->getSubExpr(), accessKind);
22152213

22162214
// Sanity check that we did see the OpaqueValueExpr.
2217-
assert(openedExistentials.count(e->getOpaqueValue()) == 0 &&
2215+
assert(SGF.OpaqueValueExprs.count(e->getOpaqueValue()) == 0 &&
22182216
"opened existential not removed?");
22192217
return lv;
22202218
}
@@ -2731,6 +2729,7 @@ static ManagedValue drillIntoComponent(SILGenFunction &SGF,
27312729
ManagedValue base,
27322730
AccessKind accessKind,
27332731
TSanKind tsanKind) {
2732+
bool isRValue = component.isRValue();
27342733
ManagedValue addr;
27352734
if (component.isPhysical()) {
27362735
addr = std::move(component.asPhysical()).offset(SGF, loc, base, accessKind);
@@ -2741,7 +2740,7 @@ static ManagedValue drillIntoComponent(SILGenFunction &SGF,
27412740

27422741
if (!SGF.getASTContext().LangOpts.DisableTsanInoutInstrumentation &&
27432742
SGF.getModule().getOptions().Sanitize == SanitizerKind::Thread &&
2744-
tsanKind == TSanKind::InoutAccess && !component.isRValue()) {
2743+
tsanKind == TSanKind::InoutAccess && !isRValue) {
27452744
emitTsanInoutAccess(SGF, loc, addr);
27462745
}
27472746

@@ -2781,6 +2780,9 @@ RValue SILGenFunction::emitLoadOfLValue(SILLocation loc, LValue &&src,
27812780
// Any writebacks should be scoped to after the load.
27822781
FormalEvaluationScope scope(*this);
27832782

2783+
auto substFormalType = src.getSubstFormalType();
2784+
auto &rvalueTL = getTypeLowering(src.getTypeOfRValue());
2785+
27842786
ManagedValue addr;
27852787
PathComponent &&component =
27862788
drillToLastComponent(*this, loc, std::move(src), addr, AccessKind::Read);
@@ -2789,9 +2791,9 @@ RValue SILGenFunction::emitLoadOfLValue(SILLocation loc, LValue &&src,
27892791
if (component.isPhysical()) {
27902792
addr = std::move(component.asPhysical())
27912793
.offset(*this, loc, addr, AccessKind::Read);
2792-
return RValue(*this, loc, src.getSubstFormalType(),
2794+
return RValue(*this, loc, substFormalType,
27932795
emitLoad(loc, addr.getValue(),
2794-
getTypeLowering(src.getTypeOfRValue()), C, IsNotTake,
2796+
rvalueTL, C, IsNotTake,
27952797
isGuaranteedValid));
27962798
}
27972799

@@ -2890,6 +2892,8 @@ void SILGenFunction::emitAssignLValueToLValue(SILLocation loc, LValue &&src,
28902892
return;
28912893
}
28922894

2895+
auto &rvalueTL = getTypeLowering(src.getTypeOfRValue());
2896+
28932897
auto srcAddr = emitAddressOfLValue(loc, std::move(src), AccessKind::Read)
28942898
.getUnmanagedValue();
28952899
auto destAddr = emitAddressOfLValue(loc, std::move(dest), AccessKind::Write)
@@ -2899,9 +2903,7 @@ void SILGenFunction::emitAssignLValueToLValue(SILLocation loc, LValue &&src,
28992903
B.createCopyAddr(loc, srcAddr, destAddr, IsNotTake, IsNotInitialization);
29002904
} else {
29012905
// If there's a semantic conversion necessary, do a load then assign.
2902-
auto loaded = emitLoad(loc, srcAddr, getTypeLowering(src.getTypeOfRValue()),
2903-
SGFContext(),
2904-
IsNotTake);
2906+
auto loaded = emitLoad(loc, srcAddr, rvalueTL, SGFContext(), IsNotTake);
29052907
loaded.assignInto(*this, loc, destAddr);
29062908
}
29072909
}

test/SILGen/properties.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,3 +1111,48 @@ public class DerivedClassWithPublicProperty : BaseClassWithInternalProperty {
11111111
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SUPER]]) : $@convention(method) (@guaranteed BaseClassWithInternalProperty) -> ()
11121112
// CHECK-NEXT: destroy_value [[SUPER]] : $BaseClassWithInternalProperty
11131113
// CHECK: } // end sil function '_T010properties30DerivedClassWithPublicPropertyC1xytfg'
1114+
1115+
// Make sure that we can handle this AST:
1116+
// (load_expr
1117+
// (open_existential_expr
1118+
// (opaque_expr A)
1119+
// ...
1120+
// (load_expr
1121+
// (opaque_expr ))))
1122+
1123+
class ReferenceType {
1124+
var p: NonmutatingProtocol
1125+
init(p: NonmutatingProtocol) { self.p = p }
1126+
}
1127+
1128+
protocol NonmutatingProtocol {
1129+
var x: Int { get nonmutating set }
1130+
}
1131+
1132+
// sil hidden @_T010properties19overlappingLoadExpryAA13ReferenceTypeCz1c_tF : $@convention(thin) (@inout ReferenceType) -> () {
1133+
// CHECK: [[RESULT:%.*]] = alloc_stack $Int
1134+
// CHECK-NEXT: [[UNINIT:%.*]] = mark_uninitialized [var] [[RESULT]] : $*Int
1135+
// CHECK-NEXT: [[C_INOUT:%.*]] = begin_access [read] [unknown] %0 : $*ReferenceType
1136+
// CHECK-NEXT: [[C:%.*]] = load [copy] [[C_INOUT:%.*]] : $*ReferenceType
1137+
// CHECK-NEXT: end_access [[C_INOUT]] : $*ReferenceType
1138+
// CHECK-NEXT: [[C_FIELD_BOX:%.*]] = alloc_stack $NonmutatingProtocol
1139+
// CHECK-NEXT: [[GETTER:%.*]] = class_method [[C]] : $ReferenceType, #ReferenceType.p!getter.1 : (ReferenceType) -> () -> NonmutatingProtocol, $@convention(method) (@guaranteed ReferenceType) -> @out NonmutatingProtocol
1140+
// CHECK-NEXT: apply [[GETTER]]([[C_FIELD_BOX]], [[C]]) : $@convention(method) (@guaranteed ReferenceType) -> @out NonmutatingProtocol
1141+
// CHECK-NEXT: destroy_value [[C]] : $ReferenceType
1142+
// CHECK-NEXT: [[C_FIELD_PAYLOAD:%.*]] = open_existential_addr immutable_access [[C_FIELD_BOX]] : $*NonmutatingProtocol to $*@opened("{{.*}}") NonmutatingProtocol
1143+
// CHECK-NEXT: [[C_FIELD_COPY:%.*]] = alloc_stack $@opened("{{.*}}") NonmutatingProtocol
1144+
// CHECK-NEXT: copy_addr [[C_FIELD_PAYLOAD]] to [initialization] [[C_FIELD_COPY]] : $*@opened("{{.*}}") NonmutatingProtocol
1145+
// CHECK-NEXT: destroy_addr [[C_FIELD_BOX]] : $*NonmutatingProtocol
1146+
// CHECK-NEXT: [[GETTER:%.*]] = witness_method $@opened("{{.*}}") NonmutatingProtocol, #NonmutatingProtocol.x!getter.1 : <Self where Self : NonmutatingProtocol> (Self) -> () -> Int, %11 : $*@opened("{{.*}}") NonmutatingProtocol : $@convention(witness_method) <τ_0_0 where τ_0_0 : NonmutatingProtocol> (@in_guaranteed τ_0_0) -> Int
1147+
// CHECK-NEXT: [[RESULT_VALUE:%.*]] = apply [[GETTER]]<@opened("{{.*}}") NonmutatingProtocol>([[C_FIELD_COPY]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : NonmutatingProtocol> (@in_guaranteed τ_0_0) -> Int
1148+
// CHECK-NEXT: destroy_addr [[C_FIELD_COPY]] : $*@opened("{{.*}}") NonmutatingProtocol
1149+
// CHECK-NEXT: assign [[RESULT_VALUE]] to [[UNINIT]] : $*Int
1150+
// CHECK-NEXT: dealloc_stack [[C_FIELD_COPY]] : $*@opened("{{.*}}") NonmutatingProtocol
1151+
// CHECK-NEXT: dealloc_stack [[C_FIELD_BOX]] : $*NonmutatingProtocol
1152+
// CHECK-NEXT: dealloc_stack [[RESULT]] : $*Int
1153+
// CHECK-NEXT: tuple ()
1154+
// CHECK-NEXT: return
1155+
1156+
func overlappingLoadExpr(c: inout ReferenceType) {
1157+
_ = c.p.x
1158+
}

0 commit comments

Comments
 (0)