@@ -1523,28 +1523,14 @@ inline Operand *getAccessProjectionOperand(SingleValueInstruction *svi) {
1523
1523
};
1524
1524
}
1525
1525
1526
- // / An address, pointer, or box cast that occurs outside of the formal
1527
- // / access. These convert the base of accessed storage without affecting the
1528
- // / AccessPath. Useful for both use-def and def-use traversal. The source
1529
- // / address must be at operand(0).
1530
- // /
1531
- // / Some of these casts, such as address_to_pointer, may also occur inside of a
1532
- // / formal access.
1533
- // /
1534
- // / TODO: Add stricter structural guarantee such that these never
1535
- // / occur within an access. It's important to be able to get the accessed
1536
- // / address without looking though type casts or pointer_to_address [strict],
1537
- // / which we can't do if those operations are behind access projections.
1538
- inline bool isAccessStorageCast (SingleValueInstruction *svi) {
1526
+ // / A cast for the purposes of AccessStorage which may change the
1527
+ // / underlying type but doesn't affect the AccessPath. See isAccessStorageCast.
1528
+ inline bool isAccessStorageTypeCast (SingleValueInstruction *svi) {
1539
1529
switch (svi->getKind ()) {
1540
1530
default :
1541
1531
return false ;
1542
-
1543
- // Simply pass-thru the incoming address.
1544
- case SILInstructionKind::MarkUninitializedInst:
1532
+ // Simply pass-thru the incoming address. But change its type!
1545
1533
case SILInstructionKind::UncheckedAddrCastInst:
1546
- case SILInstructionKind::MarkDependenceInst:
1547
- case SILInstructionKind::CopyValueInst:
1548
1534
// Casting to RawPointer does not affect the AccessPath. When converting
1549
1535
// between address types, they must be layout compatible (with truncation).
1550
1536
case SILInstructionKind::AddressToPointerInst:
@@ -1574,6 +1560,37 @@ inline bool isAccessStorageCast(SingleValueInstruction *svi) {
1574
1560
}
1575
1561
}
1576
1562
1563
+ // / A cast for the purposes of AccessStorage which doesn't change the
1564
+ // / underlying type and doesn't affect the AccessPath. See isAccessStorageCast.
1565
+ inline bool isAccessStorageIdentityCast (SingleValueInstruction *svi) {
1566
+ switch (svi->getKind ()) {
1567
+ default :
1568
+ return false ;
1569
+
1570
+ // Simply pass-thru the incoming address.
1571
+ case SILInstructionKind::MarkUninitializedInst:
1572
+ case SILInstructionKind::MarkDependenceInst:
1573
+ case SILInstructionKind::CopyValueInst:
1574
+ return true ;
1575
+ }
1576
+ }
1577
+
1578
+ // / An address, pointer, or box cast that occurs outside of the formal
1579
+ // / access. These convert the base of accessed storage without affecting the
1580
+ // / AccessPath. Useful for both use-def and def-use traversal. The source
1581
+ // / address must be at operand(0).
1582
+ // /
1583
+ // / Some of these casts, such as address_to_pointer, may also occur inside of a
1584
+ // / formal access.
1585
+ // /
1586
+ // / TODO: Add stricter structural guarantee such that these never
1587
+ // / occur within an access. It's important to be able to get the accessed
1588
+ // / address without looking though type casts or pointer_to_address [strict],
1589
+ // / which we can't do if those operations are behind access projections.
1590
+ inline bool isAccessStorageCast (SingleValueInstruction *svi) {
1591
+ return isAccessStorageTypeCast (svi) || isAccessStorageIdentityCast (svi);
1592
+ }
1593
+
1577
1594
// / Abstract CRTP class for a visiting instructions that are part of the use-def
1578
1595
// / chain from an accessed address up to the storage base.
1579
1596
// /
0 commit comments