Builtins to support copy-on-write SIL instructions

* Builtin.COWBufferForReading -> ref_element_addr [immutable] / ref_tail_addr [immutable]
* Builtin.beginCOWmutation -> begin_cow_mutation
* Builtin.endCOWmutation -> end_cow_mutation
This commit is contained in:
Erik Eckstein
2019-12-01 15:37:01 +01:00
parent d57ee1316b
commit 8f2632939a
12 changed files with 219 additions and 3 deletions

View File

@@ -431,13 +431,26 @@ createGenericParam(ASTContext &ctx, const char *name, unsigned index) {
/// Create a generic parameter list with multiple generic parameters.
static GenericParamList *getGenericParams(ASTContext &ctx,
unsigned numParameters) {
unsigned numParameters,
bool isAnyObject) {
assert(numParameters <= llvm::array_lengthof(GenericParamNames));
SmallVector<GenericTypeParamDecl*, 2> genericParams;
for (unsigned i = 0; i != numParameters; ++i)
genericParams.push_back(createGenericParam(ctx, GenericParamNames[i], i));
if (isAnyObject) {
CanType ao = ctx.getAnyObjectType();
SmallVector<RequirementRepr, 1> req;
req.push_back(RequirementRepr::getTypeConstraint(TypeLoc::withoutLoc(genericParams[0]->getInterfaceType()), SourceLoc(),
TypeLoc::withoutLoc(ao)));
auto paramList = GenericParamList::create(ctx, SourceLoc(), genericParams,
SourceLoc(), req, SourceLoc());
return paramList;
}
auto paramList = GenericParamList::create(ctx, SourceLoc(), genericParams,
SourceLoc());
return paramList;
@@ -460,9 +473,10 @@ namespace {
SmallVector<Requirement, 2> addedRequirements;
public:
BuiltinFunctionBuilder(ASTContext &ctx, unsigned numGenericParams = 1)
BuiltinFunctionBuilder(ASTContext &ctx, unsigned numGenericParams = 1,
bool isAnyObject = false)
: Context(ctx) {
TheGenericParamList = getGenericParams(ctx, numGenericParams);
TheGenericParamList = getGenericParams(ctx, numGenericParams, isAnyObject);
for (auto gp : TheGenericParamList->getParams()) {
genericParamTypes.push_back(
gp->getDeclaredInterfaceType()->castTo<GenericTypeParamType>());
@@ -645,6 +659,14 @@ static ValueDecl *getIsUniqueOperation(ASTContext &Context, Identifier Id) {
return builder.build(Id);
}
static ValueDecl *getEndCOWMutation(ASTContext &Context, Identifier Id) {
// <T> (@inout T) -> ()
BuiltinFunctionBuilder builder(Context);
builder.addParameter(makeGenericParam(), ValueOwnership::InOut);
builder.setResult(makeConcrete(TupleType::getEmpty(Context)));
return builder.build(Id);
}
static ValueDecl *getBindMemoryOperation(ASTContext &Context, Identifier Id) {
BuiltinFunctionBuilder builder(Context);
builder.addParameter(makeConcrete(Context.TheRawPointerType));
@@ -908,6 +930,16 @@ static ValueDecl *getValueToBridgeObject(ASTContext &C, Identifier Id) {
return builder.build(Id);
}
static ValueDecl *getCOWBufferForReading(ASTContext &C, Identifier Id) {
// <T : AnyObject> T -> T
//
BuiltinFunctionBuilder builder(C, 1, true);
auto T = makeGenericParam();
builder.addParameter(T);
builder.setResult(T);
return builder.build(Id);
}
static ValueDecl *getUnsafeGuaranteed(ASTContext &C, Identifier Id) {
// <T : AnyObject> T -> (T, Int8Ty)
//
@@ -2249,9 +2281,16 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
case BuiltinValueKind::IsUnique:
case BuiltinValueKind::IsUnique_native:
case BuiltinValueKind::BeginCOWMutation:
case BuiltinValueKind::BeginCOWMutation_native:
if (!Types.empty()) return nullptr;
// BeginCOWMutation has the same signature as IsUnique.
return getIsUniqueOperation(Context, Id);
case BuiltinValueKind::EndCOWMutation:
if (!Types.empty()) return nullptr;
return getEndCOWMutation(Context, Id);
case BuiltinValueKind::BindMemory:
if (!Types.empty()) return nullptr;
return getBindMemoryOperation(Context, Id);
@@ -2380,6 +2419,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
if (!Types.empty())
return nullptr;
return getValueToBridgeObject(Context, Id);
case BuiltinValueKind::COWBufferForReading:
return getCOWBufferForReading(Context, Id);
case BuiltinValueKind::UnsafeGuaranteed:
return getUnsafeGuaranteed(Context, Id);