Skip to content

Commit 300d261

Browse files
authored
Merge pull request #13805 from atrick/comment
2 parents 3fa2d4b + abedb19 commit 300d261

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

include/swift/SIL/SILType.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,16 @@ class SILType {
363363
/// pointer.
364364
bool isPointerSizeAndAligned();
365365

366-
/// True if the layout of `fromType` is known to cover the layout of
367-
/// `totype`. This is conservatively imprecise and is not
368-
/// reflexive. `fromType` may be larger than the given type and still be
369-
/// castable. It is the caller's responsibility to ensure that the overlapping
370-
/// fields are layout compatible.
371-
static bool canUnsafeCastValue(SILType fromType, SILType toType,
372-
SILModule &M);
366+
/// Return true if the layout of `toType` is an ABI compatible prefix of
367+
/// `fromType` ignoring reference types. `fromType` may be larger than
368+
/// `toType` and still be unsafe castable. `fromType` may contain references
369+
/// in positions where `toType` does not contain references and still be
370+
/// unsafe castable. This is used solely to determine whether an address cast
371+
/// can be promoted to a cast between aggregates of scalar values without
372+
/// confusing IRGen.
373+
static bool canPerformABICompatibleUnsafeCastValue(SILType fromType,
374+
SILType toType,
375+
SILModule &M);
373376

374377
/// True if `operTy` can be cast by single-reference value into `resultTy`.
375378
static bool canRefCast(SILType operTy, SILType resultTy, SILModule &M);

lib/SIL/SILType.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ static bool canUnsafeCastStruct(SILType fromType, StructDecl *fromStruct,
131131

132132
// Can the first element of fromStruct be cast by value into toType?
133133
SILType fromEltTy = fromType.getFieldType(*fromRange.begin(), M);
134-
if (SILType::canUnsafeCastValue(fromEltTy, toType, M))
134+
if (SILType::canPerformABICompatibleUnsafeCastValue(fromEltTy, toType, M))
135135
return true;
136136

137137
// Otherwise, flatten one level of struct elements on each side.
@@ -149,7 +149,7 @@ static bool canUnsafeCastStruct(SILType fromType, StructDecl *fromStruct,
149149

150150
SILType fromEltTy = fromType.getFieldType(*fromI, M);
151151
SILType toEltTy = toType.getFieldType(*toI, M);
152-
if (!SILType::canUnsafeCastValue(fromEltTy, toEltTy, M))
152+
if (!SILType::canPerformABICompatibleUnsafeCastValue(fromEltTy, toEltTy, M))
153153
return false;
154154
}
155155
// fromType's overlapping elements are compatible.
@@ -162,8 +162,9 @@ static bool canUnsafeCastTuple(SILType fromType, CanTupleType fromTupleTy,
162162
SILType toType, SILModule &M) {
163163
unsigned numFromElts = fromTupleTy->getNumElements();
164164
// Can the first element of fromTupleTy be cast by value into toType?
165-
if (numFromElts != 0 && SILType::canUnsafeCastValue(
166-
fromType.getTupleElementType(0), toType, M)) {
165+
if (numFromElts != 0
166+
&& SILType::canPerformABICompatibleUnsafeCastValue(
167+
fromType.getTupleElementType(0), toType, M)) {
167168
return true;
168169
}
169170
// Otherwise, flatten one level of tuple elements on each side.
@@ -176,8 +177,9 @@ static bool canUnsafeCastTuple(SILType fromType, CanTupleType fromTupleTy,
176177
return false;
177178

178179
for (unsigned i = 0; i != numToElts; ++i) {
179-
if (!SILType::canUnsafeCastValue(fromType.getTupleElementType(i),
180-
toType.getTupleElementType(i), M)) {
180+
if (!SILType::canPerformABICompatibleUnsafeCastValue(
181+
fromType.getTupleElementType(i), toType.getTupleElementType(i),
182+
M)) {
181183
return false;
182184
}
183185
}
@@ -221,7 +223,8 @@ static bool canUnsafeCastEnum(SILType fromType, EnumDecl *fromEnum,
221223
continue;
222224

223225
auto fromElementTy = fromType.getEnumElementType(fromElement, M);
224-
if (SILType::canUnsafeCastValue(fromElementTy, toElementTy, M))
226+
if (SILType::canPerformABICompatibleUnsafeCastValue(fromElementTy,
227+
toElementTy, M))
225228
return true;
226229
}
227230
return false;
@@ -263,8 +266,9 @@ static bool canUnsafeCastScalars(SILType fromType, SILType toType,
263266
return LeastFromWidth >= GreatestToWidth;
264267
}
265268

266-
bool SILType::canUnsafeCastValue(SILType fromType, SILType toType,
267-
SILModule &M) {
269+
bool SILType::canPerformABICompatibleUnsafeCastValue(SILType fromType,
270+
SILType toType,
271+
SILModule &M) {
268272
if (fromType == toType)
269273
return true;
270274

lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,10 @@ SILCombiner::visitUncheckedAddrCastInst(UncheckedAddrCastInst *UADCI) {
236236
// larger OutputType (the actual memory object must be large enough to hold
237237
// both types). However, such address casts cannot be converted to value
238238
// casts.
239-
if (!SILType::canUnsafeCastValue(InputTy, OutputTy, UADCI->getModule()))
239+
if (!SILType::canPerformABICompatibleUnsafeCastValue(InputTy, OutputTy,
240+
UADCI->getModule())) {
240241
return nullptr;
241-
242+
}
242243
// For each user U of the unchecked_addr_cast...
243244
for (auto U : getNonDebugUses(UADCI))
244245
// Check if it is load. If it is not a load, bail...

0 commit comments

Comments
 (0)