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:
@@ -73,6 +73,48 @@ SILValue stripIndexingInsts(SILValue V);
|
|||||||
/// intrinsic call.
|
/// intrinsic call.
|
||||||
SILValue stripExpectIntrinsic(SILValue V);
|
SILValue stripExpectIntrinsic(SILValue V);
|
||||||
|
|
||||||
|
/// A utility class for evaluating whether a newly parsed or deserialized
|
||||||
|
/// function has qualified or unqualified ownership.
|
||||||
|
///
|
||||||
|
/// The reason that we are using this is that we would like to avoid needing to
|
||||||
|
/// add code to the SILParser or to the Serializer to support this temporary
|
||||||
|
/// staging concept of a function having qualified or unqualified
|
||||||
|
/// ownership. Once SemanticARC is complete, SILFunctions will always have
|
||||||
|
/// qualified ownership, so the notion of an unqualified ownership function will
|
||||||
|
/// no longer exist.
|
||||||
|
///
|
||||||
|
/// Thus we note that there are three sets of instructions in SIL from an
|
||||||
|
/// ownership perspective:
|
||||||
|
///
|
||||||
|
/// a. ownership qualified instructions
|
||||||
|
/// b. ownership unqualified instructions
|
||||||
|
/// c. instructions that do not have ownership semantics (think literals,
|
||||||
|
/// geps, etc).
|
||||||
|
///
|
||||||
|
/// The set of functions can be split into ownership qualified and ownership
|
||||||
|
/// unqualified using the rules that:
|
||||||
|
///
|
||||||
|
/// a. a function can never contain both ownership qualified and ownership
|
||||||
|
/// unqualified instructions.
|
||||||
|
/// b. a function that contains only instructions without ownership semantics
|
||||||
|
/// is considered ownership qualified.
|
||||||
|
///
|
||||||
|
/// Thus we can know when parsing/serializing what category of function we have
|
||||||
|
/// and set the bit appropriately.
|
||||||
|
class FunctionOwnershipEvaluator {
|
||||||
|
NullablePtr<SILFunction> F;
|
||||||
|
bool HasOwnershipQualifiedInstruction = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FunctionOwnershipEvaluator() {}
|
||||||
|
FunctionOwnershipEvaluator(SILFunction *F) : F(F) {}
|
||||||
|
void reset(SILFunction *NewF) {
|
||||||
|
F = NewF;
|
||||||
|
HasOwnershipQualifiedInstruction = false;
|
||||||
|
}
|
||||||
|
bool evaluate(const SILInstruction &I);
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -176,6 +176,17 @@ private:
|
|||||||
/// method itself. In this case we need to create a vtable stub for it.
|
/// method itself. In this case we need to create a vtable stub for it.
|
||||||
bool Zombie = false;
|
bool Zombie = false;
|
||||||
|
|
||||||
|
/// True if SILOwnership is enabled for this function. It is always false when
|
||||||
|
/// the SILOption HasQualifiedOwnership is not set. When the SILOption
|
||||||
|
/// HasQualifiedOwnership /is/ set, this value is initialized to true. Once
|
||||||
|
/// the
|
||||||
|
/// OwnershipModelEliminator runs on the function, it is set to false.
|
||||||
|
///
|
||||||
|
/// This enables the verifier to easily prove that before the Ownership Model
|
||||||
|
/// Eliminator runs on a function, we only see a non-semantic-arc world and
|
||||||
|
/// after the pass runs, we only see a semantic-arc world.
|
||||||
|
Optional<bool> HasQualifiedOwnership;
|
||||||
|
|
||||||
SILFunction(SILModule &module, SILLinkage linkage,
|
SILFunction(SILModule &module, SILLinkage linkage,
|
||||||
StringRef mangledName, CanSILFunctionType loweredType,
|
StringRef mangledName, CanSILFunctionType loweredType,
|
||||||
GenericEnvironment *genericEnv,
|
GenericEnvironment *genericEnv,
|
||||||
@@ -281,6 +292,30 @@ public:
|
|||||||
/// Returns true if this function is dead, but kept in the module's zombie list.
|
/// Returns true if this function is dead, but kept in the module's zombie list.
|
||||||
bool isZombie() const { return Zombie; }
|
bool isZombie() const { return Zombie; }
|
||||||
|
|
||||||
|
/// Returns true if this function has qualified ownership instructions in it.
|
||||||
|
Optional<bool> hasQualifiedOwnership() const {
|
||||||
|
if (HasQualifiedOwnership.hasValue())
|
||||||
|
return HasQualifiedOwnership.getValue();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if this function has unqualified ownership instructions in
|
||||||
|
/// it.
|
||||||
|
Optional<bool> hasUnqualifedOwnership() const {
|
||||||
|
if (HasQualifiedOwnership.hasValue())
|
||||||
|
return !HasQualifiedOwnership.getValue();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the HasQualifiedOwnership flag to false. This signals to SIL that no
|
||||||
|
/// ownership instructions should be in this function any more.
|
||||||
|
void setUnqualifiedOwnership() {
|
||||||
|
assert(
|
||||||
|
HasQualifiedOwnership.hasValue() &&
|
||||||
|
"Should never set unqualified ownership when SILOwnership is disabled");
|
||||||
|
HasQualifiedOwnership = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the calling convention used by this entry point.
|
/// Returns the calling convention used by this entry point.
|
||||||
SILFunctionTypeRepresentation getRepresentation() const {
|
SILFunctionTypeRepresentation getRepresentation() const {
|
||||||
return getLoweredFunctionType()->getRepresentation();
|
return getLoweredFunctionType()->getRepresentation();
|
||||||
|
|||||||
@@ -10,22 +10,23 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "swift/Basic/Defer.h"
|
|
||||||
#include "swift/Basic/Fallthrough.h"
|
|
||||||
#include "swift/AST/ArchetypeBuilder.h"
|
#include "swift/AST/ArchetypeBuilder.h"
|
||||||
#include "swift/AST/GenericEnvironment.h"
|
#include "swift/AST/GenericEnvironment.h"
|
||||||
#include "swift/AST/NameLookup.h"
|
#include "swift/AST/NameLookup.h"
|
||||||
#include "swift/Parse/Parser.h"
|
#include "swift/Basic/Defer.h"
|
||||||
|
#include "swift/Basic/Fallthrough.h"
|
||||||
#include "swift/Parse/Lexer.h"
|
#include "swift/Parse/Lexer.h"
|
||||||
|
#include "swift/Parse/Parser.h"
|
||||||
#include "swift/SIL/AbstractionPattern.h"
|
#include "swift/SIL/AbstractionPattern.h"
|
||||||
|
#include "swift/SIL/InstructionUtils.h"
|
||||||
#include "swift/SIL/SILArgument.h"
|
#include "swift/SIL/SILArgument.h"
|
||||||
#include "swift/SIL/SILBuilder.h"
|
#include "swift/SIL/SILBuilder.h"
|
||||||
#include "swift/SIL/SILDebugScope.h"
|
#include "swift/SIL/SILDebugScope.h"
|
||||||
#include "swift/SIL/SILModule.h"
|
#include "swift/SIL/SILModule.h"
|
||||||
#include "swift/SIL/SILUndef.h"
|
#include "swift/SIL/SILUndef.h"
|
||||||
#include "swift/Subsystems.h"
|
#include "swift/Subsystems.h"
|
||||||
#include "llvm/Support/SaveAndRestore.h"
|
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
#include "llvm/Support/SaveAndRestore.h"
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -103,6 +104,8 @@ namespace {
|
|||||||
SILParserTUState &TUState;
|
SILParserTUState &TUState;
|
||||||
SILFunction *F = nullptr;
|
SILFunction *F = nullptr;
|
||||||
GenericEnvironment *GenericEnv = nullptr;
|
GenericEnvironment *GenericEnv = nullptr;
|
||||||
|
FunctionOwnershipEvaluator OwnershipEvaluator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// HadError - Have we seen an error parsing this function?
|
/// HadError - Have we seen an error parsing this function?
|
||||||
bool HadError = false;
|
bool HadError = false;
|
||||||
@@ -3983,6 +3986,11 @@ bool SILParser::parseSILBasicBlock(SILBuilder &B) {
|
|||||||
do {
|
do {
|
||||||
if (parseSILInstruction(BB, B))
|
if (parseSILInstruction(BB, B))
|
||||||
return true;
|
return true;
|
||||||
|
// Evaluate how the just parsed instruction effects this functions Ownership
|
||||||
|
// Qualification. For more details, see the comment on the
|
||||||
|
// FunctionOwnershipEvaluator class.
|
||||||
|
if (!OwnershipEvaluator.evaluate(*BB->rbegin()))
|
||||||
|
return true;
|
||||||
} while (isStartOfSILInstruction());
|
} while (isStartOfSILInstruction());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -4078,6 +4086,7 @@ bool Parser::parseDeclSIL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the basic block list.
|
// Parse the basic block list.
|
||||||
|
FunctionState.OwnershipEvaluator.reset(FunctionState.F);
|
||||||
SILOpenedArchetypesTracker OpenedArchetypesTracker(*FunctionState.F);
|
SILOpenedArchetypesTracker OpenedArchetypesTracker(*FunctionState.F);
|
||||||
SILBuilder B(*FunctionState.F);
|
SILBuilder B(*FunctionState.F);
|
||||||
// Track the archetypes just like SILGen. This
|
// Track the archetypes just like SILGen. This
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "sil-inst-utils"
|
#define DEBUG_TYPE "sil-inst-utils"
|
||||||
#include "swift/SIL/InstructionUtils.h"
|
#include "swift/SIL/InstructionUtils.h"
|
||||||
|
#include "swift/Basic/NullablePtr.h"
|
||||||
|
#include "swift/SIL/Projection.h"
|
||||||
#include "swift/SIL/SILArgument.h"
|
#include "swift/SIL/SILArgument.h"
|
||||||
#include "swift/SIL/SILBasicBlock.h"
|
#include "swift/SIL/SILBasicBlock.h"
|
||||||
#include "swift/SIL/Projection.h"
|
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
@@ -221,3 +222,86 @@ SILValue swift::stripExpectIntrinsic(SILValue V) {
|
|||||||
return V;
|
return V;
|
||||||
return BI->getArguments()[0];
|
return BI->getArguments()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
enum class OwnershipQualifiedKind {
|
||||||
|
NotApplicable,
|
||||||
|
Qualified,
|
||||||
|
Unqualified,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
static OwnershipQualifiedKind
|
||||||
|
getOwnershipQualifiedKind(const SILInstruction &I) {
|
||||||
|
switch (I.getKind()) {
|
||||||
|
case ValueKind::LoadInst:
|
||||||
|
if (cast<LoadInst>(I).getOwnershipQualifier() ==
|
||||||
|
LoadOwnershipQualifier::Unqualified)
|
||||||
|
return OwnershipQualifiedKind::Unqualified;
|
||||||
|
return OwnershipQualifiedKind::Qualified;
|
||||||
|
case ValueKind::StoreInst:
|
||||||
|
if (cast<StoreInst>(I).getOwnershipQualifier() ==
|
||||||
|
StoreOwnershipQualifier::Unqualified)
|
||||||
|
return OwnershipQualifiedKind::Unqualified;
|
||||||
|
return OwnershipQualifiedKind::Qualified;
|
||||||
|
case ValueKind::LoadBorrowInst:
|
||||||
|
case ValueKind::EndBorrowInst:
|
||||||
|
return OwnershipQualifiedKind::Qualified;
|
||||||
|
default:
|
||||||
|
return OwnershipQualifiedKind::NotApplicable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionOwnershipEvaluator::evaluate(const SILInstruction &I) {
|
||||||
|
assert(I.getFunction() == F.get() && "Can not evaluate function ownership "
|
||||||
|
"implications of an instruction that "
|
||||||
|
"does not belong to the instruction "
|
||||||
|
"that we are evaluating");
|
||||||
|
|
||||||
|
// If SIL ownership is not enabled in this module, just return true. There is
|
||||||
|
// no further work to do here.
|
||||||
|
if (!I.getModule().getOptions().EnableSILOwnership)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (getOwnershipQualifiedKind(I)) {
|
||||||
|
case OwnershipQualifiedKind::Unqualified: {
|
||||||
|
// If we already know that the function has unqualified ownership, just
|
||||||
|
// return early.
|
||||||
|
if (!F.get()->hasQualifiedOwnership().getValue())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Ok, so we know at this point that we have qualified ownership. If we have
|
||||||
|
// seen any instructions with qualified ownership, we have an error since
|
||||||
|
// the function mixes qualified and unqualified instructions.
|
||||||
|
if (HasOwnershipQualifiedInstruction)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Otherwise, set the function to have unqualified ownership. This will
|
||||||
|
// ensure that no more Qualified instructions can be added to the given
|
||||||
|
// function.
|
||||||
|
F.get()->setUnqualifiedOwnership();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OwnershipQualifiedKind::Qualified: {
|
||||||
|
// First check if our function has unqualified ownership. If we already do
|
||||||
|
// have unqualified ownership, then we know that we have already seen an
|
||||||
|
// unqualified ownership instruction. This means the function has both
|
||||||
|
// qualified and unqualified instructions. =><=.
|
||||||
|
if (!F.get()->hasQualifiedOwnership().getValue())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Ok, at this point we know that we are still qualified. Since functions
|
||||||
|
// start as qualified, we need to set the HasOwnershipQualifiedInstructions
|
||||||
|
// so we do not need to look back through the function if we see an
|
||||||
|
// unqualified instruction later on.
|
||||||
|
HasOwnershipQualifiedInstruction = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OwnershipQualifiedKind::NotApplicable: {
|
||||||
|
// Not Applicable instr
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,35 +71,21 @@ SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
|
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, StringRef Name,
|
||||||
StringRef Name, CanSILFunctionType LoweredType,
|
CanSILFunctionType LoweredType,
|
||||||
GenericEnvironment *genericEnv,
|
GenericEnvironment *genericEnv,
|
||||||
Optional<SILLocation> Loc,
|
Optional<SILLocation> Loc, IsBare_t isBareSILFunction,
|
||||||
IsBare_t isBareSILFunction,
|
IsTransparent_t isTrans, IsFragile_t isFragile,
|
||||||
IsTransparent_t isTrans,
|
IsThunk_t isThunk, ClassVisibility_t classVisibility,
|
||||||
IsFragile_t isFragile,
|
|
||||||
IsThunk_t isThunk,
|
|
||||||
ClassVisibility_t classVisibility,
|
|
||||||
Inline_t inlineStrategy, EffectsKind E,
|
Inline_t inlineStrategy, EffectsKind E,
|
||||||
SILFunction *InsertBefore,
|
SILFunction *InsertBefore,
|
||||||
const SILDebugScope *DebugScope,
|
const SILDebugScope *DebugScope, DeclContext *DC)
|
||||||
DeclContext *DC)
|
: Module(Module), Name(Name), LoweredType(LoweredType),
|
||||||
: Module(Module),
|
GenericEnv(genericEnv), DeclCtx(DC), DebugScope(DebugScope),
|
||||||
Name(Name),
|
Bare(isBareSILFunction), Transparent(isTrans), Fragile(isFragile),
|
||||||
LoweredType(LoweredType),
|
Thunk(isThunk), ClassVisibility(classVisibility), GlobalInitFlag(false),
|
||||||
GenericEnv(genericEnv),
|
InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
|
||||||
DeclCtx(DC),
|
KeepAsPublic(false), EffectsKindAttr(E), HasQualifiedOwnership() {
|
||||||
DebugScope(DebugScope),
|
|
||||||
Bare(isBareSILFunction),
|
|
||||||
Transparent(isTrans),
|
|
||||||
Fragile(isFragile),
|
|
||||||
Thunk(isThunk),
|
|
||||||
ClassVisibility(classVisibility),
|
|
||||||
GlobalInitFlag(false),
|
|
||||||
InlineStrategy(inlineStrategy),
|
|
||||||
Linkage(unsigned(Linkage)),
|
|
||||||
KeepAsPublic(false),
|
|
||||||
EffectsKindAttr(E) {
|
|
||||||
if (InsertBefore)
|
if (InsertBefore)
|
||||||
Module.functions.insert(SILModule::iterator(InsertBefore), this);
|
Module.functions.insert(SILModule::iterator(InsertBefore), this);
|
||||||
else
|
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
|
// Set our BB list to have this function as its parent. This enables us to
|
||||||
// splice efficiently basic blocks in between functions.
|
// splice efficiently basic blocks in between functions.
|
||||||
BlockList.Parent = this;
|
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() {
|
SILFunction::~SILFunction() {
|
||||||
|
|||||||
@@ -538,6 +538,7 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID,
|
|||||||
LocalValues.clear();
|
LocalValues.clear();
|
||||||
ForwardLocalValues.clear();
|
ForwardLocalValues.clear();
|
||||||
|
|
||||||
|
FunctionOwnershipEvaluator OwnershipEvaluator(fn);
|
||||||
SILOpenedArchetypesTracker OpenedArchetypesTracker(*fn);
|
SILOpenedArchetypesTracker OpenedArchetypesTracker(*fn);
|
||||||
SILBuilder Builder(*fn);
|
SILBuilder Builder(*fn);
|
||||||
// Track the archetypes just like SILGen. This
|
// Track the archetypes just like SILGen. This
|
||||||
@@ -571,7 +572,8 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID,
|
|||||||
return fn;
|
return fn;
|
||||||
|
|
||||||
// Handle a SILInstruction record.
|
// Handle a SILInstruction record.
|
||||||
if (readSILInstruction(fn, CurrentBB, Builder, kind, scratch)) {
|
if (readSILInstruction(fn, CurrentBB, Builder, OwnershipEvaluator, kind,
|
||||||
|
scratch)) {
|
||||||
DEBUG(llvm::dbgs() << "readSILInstruction returns error.\n");
|
DEBUG(llvm::dbgs() << "readSILInstruction returns error.\n");
|
||||||
MF->error();
|
MF->error();
|
||||||
return fn;
|
return fn;
|
||||||
@@ -657,10 +659,10 @@ static SILDeclRef getSILDeclRef(ModuleFile *MF,
|
|||||||
return DRef;
|
return DRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
bool SILDeserializer::readSILInstruction(
|
||||||
SILBuilder &Builder,
|
SILFunction *Fn, SILBasicBlock *BB, SILBuilder &Builder,
|
||||||
unsigned RecordKind,
|
FunctionOwnershipEvaluator &OwnershipEvaluator, unsigned RecordKind,
|
||||||
SmallVectorImpl<uint64_t> &scratch) {
|
SmallVectorImpl<uint64_t> &scratch) {
|
||||||
// Return error if Basic Block is null.
|
// Return error if Basic Block is null.
|
||||||
if (!BB)
|
if (!BB)
|
||||||
return true;
|
return true;
|
||||||
@@ -1885,6 +1887,12 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
|||||||
case ValueKind::MarkUninitializedBehaviorInst:
|
case ValueKind::MarkUninitializedBehaviorInst:
|
||||||
llvm_unreachable("todo");
|
llvm_unreachable("todo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Evaluate ResultVal's ownership. If we find that as a result of ResultVal,
|
||||||
|
// we are mixing qualified and unqualified ownership instructions, bail.
|
||||||
|
if (!OwnershipEvaluator.evaluate(*ResultVal))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (ResultVal->hasValue()) {
|
if (ResultVal->hasValue()) {
|
||||||
LastValueID = LastValueID + 1;
|
LastValueID = LastValueID + 1;
|
||||||
setLocalValue(ResultVal, LastValueID);
|
setLocalValue(ResultVal, LastValueID);
|
||||||
|
|||||||
@@ -10,9 +10,10 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "swift/Serialization/ModuleFile.h"
|
|
||||||
#include "SILFormat.h"
|
#include "SILFormat.h"
|
||||||
|
#include "swift/SIL/InstructionUtils.h"
|
||||||
#include "swift/SIL/SILModule.h"
|
#include "swift/SIL/SILModule.h"
|
||||||
|
#include "swift/Serialization/ModuleFile.h"
|
||||||
#include "swift/Serialization/SerializedSILLoader.h"
|
#include "swift/Serialization/SerializedSILLoader.h"
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
@@ -83,6 +84,7 @@ namespace swift {
|
|||||||
/// Read a SIL instruction within a given SIL basic block.
|
/// Read a SIL instruction within a given SIL basic block.
|
||||||
bool readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
bool readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
|
||||||
SILBuilder &Builder,
|
SILBuilder &Builder,
|
||||||
|
FunctionOwnershipEvaluator &OwnershipEvaluator,
|
||||||
unsigned RecordKind,
|
unsigned RecordKind,
|
||||||
SmallVectorImpl<uint64_t> &scratch);
|
SmallVectorImpl<uint64_t> &scratch);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user