mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/master' into master-next
This commit is contained in:
@@ -329,9 +329,58 @@ public:
|
||||
delete Dominance;
|
||||
}
|
||||
|
||||
// Address-type block args must be prohibited whenever access markers are
|
||||
// present. Access markers are always present in raw SIL to diagnose exclusive
|
||||
// memory access. In canonical SIL, access markers are only present with
|
||||
// EnforceExclusivityDynamic.
|
||||
//
|
||||
// FIXME: For sanity, address-type block args should be prohibited at all SIL
|
||||
// stages. However, the optimizer currently breaks the invariant in three
|
||||
// places:
|
||||
// 1. Normal Simplify CFG during conditional branch simplification
|
||||
// (sneaky jump threading).
|
||||
// 2. Simplify CFG via Jump Threading.
|
||||
// 3. Loop Rotation.
|
||||
// Once EnforceExclusivityDynamic is performant enough to be enabled by
|
||||
// default at -O, address-type blocks args can be prohibited unconditionally.
|
||||
bool prohibitAddressBlockArgs() {
|
||||
// If this function was deserialized from canonical SIL, this invariant may
|
||||
// already have been violated regardless of this module's SIL stage or
|
||||
// exclusivity enforcement level. Presumably, access markers were already
|
||||
// removed prior to serialization.
|
||||
if (F.wasDeserializedCanonical())
|
||||
return false;
|
||||
|
||||
SILModule &M = F.getModule();
|
||||
if (M.getStage() == SILStage::Raw)
|
||||
return true;
|
||||
|
||||
// If dynamic enforcement is enabled, markers are present at -O so we
|
||||
// prohibit address block args.
|
||||
return M.getOptions().EnforceExclusivityDynamic;
|
||||
}
|
||||
|
||||
void visitSILArgument(SILArgument *arg) {
|
||||
checkLegalType(arg->getFunction(), arg, nullptr);
|
||||
checkValueBaseOwnership(arg);
|
||||
|
||||
if (isa<SILPHIArgument>(arg) && prohibitAddressBlockArgs()) {
|
||||
// As a structural SIL property, we disallow address-type block
|
||||
// arguments. Supporting them would prevent reliably reasoning about the
|
||||
// underlying storage of memory access. This reasoning is important for
|
||||
// diagnosing violations of memory access rules and supporting future
|
||||
// optimizations such as bitfield packing. Address-type block arguments
|
||||
// also create unnecessary complexity for SIL optimization passes that
|
||||
// need to reason about memory aliasing.
|
||||
//
|
||||
// Note: We could allow non-phi block arguments to be addresses, because
|
||||
// the address source would still be uniquely recoverable. But then
|
||||
// we would need to separately ensure that something like begin_access is
|
||||
// never passed as a block argument before being used by end_access. For
|
||||
// now, it simpler to have a strict prohibition.
|
||||
require(!arg->getType().isAddress(),
|
||||
"Block arguments cannot be addresses");
|
||||
}
|
||||
}
|
||||
|
||||
void visitSILInstruction(SILInstruction *I) {
|
||||
|
||||
Reference in New Issue
Block a user