Merge remote-tracking branch 'origin/master' into master-next

This commit is contained in:
swift-ci
2018-02-27 10:09:46 -08:00
33 changed files with 253 additions and 140 deletions

View File

@@ -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) {