mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[semantic-arc] As staging detail, add a HasQualifiedOwnership flag on all SILFunctions.
Over the past day or so I have been thinking about how we are going to need to manage verification of semantic ARC semantics in the pass pipeline. Specifically the Eliminator pass really needs to be a function pass to ensure that we can transparently put it at any stage of the optimization pipeline. This means that just having a flag on the SILVerifier that states whether or not ownership is enabled is not sufficient for our purposes. Instead, while staging in the SIL ownership model, we need a bit on all SILFunctions to state whether the function has been run through the ownership model eliminator so that the verifier can ensure that we are in a world with "SIL ownership" or in a world without "SIL ownership", never in a world with only some "SIL ownership" instructions. We embed this distinction in SIL by creating the concept of a function with "qualified ownership" and a function with "unqualified ownership". Define a function with "qualified ownership" as a function that contains no instructions with "unqualified ownership" (i.e. unqualified load) and a function with "unqualified ownership" as a function containing such no "ownership qualified" instructions (i.e. load [copy]) and at least 1 unqualified ownership instruction. This commit embeds this distinction into SILFunction in a manner that is transparently ignored when compiling with SIL ownership disabled. This is done by representing qualified or unqualified ownership via an optional Boolean on SILFunction. If the Boolean is None, then SILOwnership is not enabled and the verifier/passes can work as appropriate. If the Boolean is not None, then it states whether or not the function has been run through the Ownership Model Eliminator and thus what invariants the verifier should enforce. How does this concept flow through the compilation pipeline for functions in a given module? When SIL Ownership is enabled, all SILFunctions that are produced in a given module start with "qualified ownership" allowing them to contain SIL ownership instructions. After the Ownership Model eliminator has run, the Ownership Model sets the "unqualified" ownership flag on the SILFunction stating that no more ownership qualified instructions are allowed to be seen in the given function. But what about functions that are parsed or are deserialized from another module? Luckily, given the manner in which we have categories our functions, we can categorize functions directly without needing to add anything to the parser or to the deserializer. This is done by enforcing that it is illegal to have a function with qualified ownership and unqualified ownership instructions and asserting that functions without either are considered qualified. rdar://28685236
This commit is contained in:
@@ -71,35 +71,21 @@ SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
|
||||
return fn;
|
||||
}
|
||||
|
||||
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
|
||||
StringRef Name, CanSILFunctionType LoweredType,
|
||||
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, StringRef Name,
|
||||
CanSILFunctionType LoweredType,
|
||||
GenericEnvironment *genericEnv,
|
||||
Optional<SILLocation> Loc,
|
||||
IsBare_t isBareSILFunction,
|
||||
IsTransparent_t isTrans,
|
||||
IsFragile_t isFragile,
|
||||
IsThunk_t isThunk,
|
||||
ClassVisibility_t classVisibility,
|
||||
Optional<SILLocation> Loc, IsBare_t isBareSILFunction,
|
||||
IsTransparent_t isTrans, IsFragile_t isFragile,
|
||||
IsThunk_t isThunk, ClassVisibility_t classVisibility,
|
||||
Inline_t inlineStrategy, EffectsKind E,
|
||||
SILFunction *InsertBefore,
|
||||
const SILDebugScope *DebugScope,
|
||||
DeclContext *DC)
|
||||
: Module(Module),
|
||||
Name(Name),
|
||||
LoweredType(LoweredType),
|
||||
GenericEnv(genericEnv),
|
||||
DeclCtx(DC),
|
||||
DebugScope(DebugScope),
|
||||
Bare(isBareSILFunction),
|
||||
Transparent(isTrans),
|
||||
Fragile(isFragile),
|
||||
Thunk(isThunk),
|
||||
ClassVisibility(classVisibility),
|
||||
GlobalInitFlag(false),
|
||||
InlineStrategy(inlineStrategy),
|
||||
Linkage(unsigned(Linkage)),
|
||||
KeepAsPublic(false),
|
||||
EffectsKindAttr(E) {
|
||||
const SILDebugScope *DebugScope, DeclContext *DC)
|
||||
: Module(Module), Name(Name), LoweredType(LoweredType),
|
||||
GenericEnv(genericEnv), DeclCtx(DC), DebugScope(DebugScope),
|
||||
Bare(isBareSILFunction), Transparent(isTrans), Fragile(isFragile),
|
||||
Thunk(isThunk), ClassVisibility(classVisibility), GlobalInitFlag(false),
|
||||
InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
|
||||
KeepAsPublic(false), EffectsKindAttr(E), HasQualifiedOwnership() {
|
||||
if (InsertBefore)
|
||||
Module.functions.insert(SILModule::iterator(InsertBefore), this);
|
||||
else
|
||||
@@ -110,6 +96,12 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
|
||||
// Set our BB list to have this function as its parent. This enables us to
|
||||
// splice efficiently basic blocks in between functions.
|
||||
BlockList.Parent = this;
|
||||
|
||||
// If SILOwnership is not enabled, HasQualifiedOwnership is None. If
|
||||
// SILOwnership is enabled, we always initialize functions to have
|
||||
// SILOwnership initially.
|
||||
if (Module.getOptions().EnableSILOwnership)
|
||||
HasQualifiedOwnership = true;
|
||||
}
|
||||
|
||||
SILFunction::~SILFunction() {
|
||||
|
||||
Reference in New Issue
Block a user