Skip to content

[semantic-arc] Add StoreBorrowInst and BeginBorrowInst. #6230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,11 @@ class SILBuilder {
LoadBorrowInst(getSILDebugLocation(Loc), LV));
}

BeginBorrowInst *createBeginBorrow(SILLocation Loc, SILValue LV) {
return insert(new (F.getModule())
BeginBorrowInst(getSILDebugLocation(Loc), LV));
}

StoreInst *createStore(SILLocation Loc, SILValue Src, SILValue DestAddr,
StoreOwnershipQualifier Qualifier) {
assert((Qualifier != StoreOwnershipQualifier::Unqualified) ||
Expand Down Expand Up @@ -520,6 +525,12 @@ class SILBuilder {
AssignInst(getSILDebugLocation(Loc), Src, DestAddr));
}

StoreBorrowInst *createStoreBorrow(SILLocation Loc, SILValue Src,
SILValue DestAddr) {
return insert(new (F.getModule())
StoreBorrowInst(getSILDebugLocation(Loc), Src, DestAddr));
}

MarkUninitializedInst *
createMarkUninitialized(SILLocation Loc, SILValue src,
MarkUninitializedInst::Kind k) {
Expand Down
17 changes: 17 additions & 0 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,14 @@ void SILCloner<ImplClass>::visitLoadBorrowInst(LoadBorrowInst *Inst) {
getOpValue(Inst->getOperand())));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitBeginBorrowInst(BeginBorrowInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createBeginBorrow(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getOperand())));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitStoreInst(StoreInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
Expand All @@ -682,6 +690,15 @@ void SILCloner<ImplClass>::visitStoreInst(StoreInst *Inst) {
Inst->getOwnershipQualifier()));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitStoreBorrowInst(StoreBorrowInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createStoreBorrow(getOpLocation(Inst->getLoc()),
getOpValue(Inst->getSrc()),
getOpValue(Inst->getDest())));
}

template <typename ImplClass>
void SILCloner<ImplClass>::visitEndBorrowInst(EndBorrowInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
Expand Down
40 changes: 40 additions & 0 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,46 @@ class LoadBorrowInst : public UnaryInstructionBase<ValueKind::LoadBorrowInst> {
LValue->getType().getObjectType()) {}
};

/// Represents the begin scope of a borrowed value. Must be paired with an
/// end_borrow instruction in its use-def list.
class BeginBorrowInst
: public UnaryInstructionBase<ValueKind::BeginBorrowInst> {
friend class SILBuilder;

BeginBorrowInst(SILDebugLocation DebugLoc, SILValue LValue)
: UnaryInstructionBase(DebugLoc, LValue,
LValue->getType().getObjectType()) {}
};

/// Represents a store of a borrowed value into an address. Returns the borrowed
/// address. Must be paired with a end_borrow in its use-def list.
class StoreBorrowInst : public SILInstruction {
friend class SILBuilder;

public:
enum {
/// The source of the value being borrowed.
Src,
/// The destination of the borrowed value.
Dest
};

private:
FixedOperandList<2> Operands;
StoreBorrowInst(SILDebugLocation DebugLoc, SILValue Src, SILValue Dest);

public:
SILValue getSrc() const { return Operands[Src].get(); }
SILValue getDest() const { return Operands[Dest].get(); }

ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }

static bool classof(const ValueBase *V) {
return V->getKind() == ValueKind::StoreBorrowInst;
}
};

/// Represents the end of a borrow scope for a value or address from another
/// value or address.
///
Expand Down
2 changes: 2 additions & 0 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
// Accessing memory
INST(LoadInst, SILInstruction, load, MayRead, DoesNotRelease)
INST(LoadBorrowInst, SILInstruction, load_borrow, MayRead, DoesNotRelease)
INST(BeginBorrowInst, SILInstruction, begin_borrow, MayHaveSideEffects, DoesNotRelease)
INST(EndBorrowInst, SILInstruction, end_borrow, MayHaveSideEffects, DoesNotRelease)
INST(LoadUnownedInst, SILInstruction, load_unowned, MayRead, DoesNotRelease)
INST(LoadWeakInst, SILInstruction, load_weak, MayRead, DoesNotRelease)
INST(StoreInst, SILInstruction, store, MayWrite, DoesNotRelease)
INST(StoreBorrowInst, SILInstruction, store_borrow, MayWrite, DoesNotRelease)
INST(AssignInst, SILInstruction, assign, MayWrite, DoesNotRelease)
INST(MarkUninitializedInst, SILInstruction, mark_uninitialized, None, DoesNotRelease)
INST(MarkUninitializedBehaviorInst, SILInstruction, mark_uninitialized_behavior, None, DoesNotRelease)
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/ModuleFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
const uint16_t VERSION_MINOR = 297; // Last change: typealias underlying interface type
const uint16_t VERSION_MINOR = 298; // Last change: Added {store,begin}_borrow

using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>;
Expand Down
6 changes: 6 additions & 0 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,9 +858,15 @@ class IRGenSILFunction :
void visitInitBlockStorageHeaderInst(InitBlockStorageHeaderInst *i);

void visitFixLifetimeInst(FixLifetimeInst *i);
void visitBeginBorrowInst(BeginBorrowInst *i) {
llvm_unreachable("unimplemented");
}
void visitEndBorrowInst(EndBorrowInst *i) {
llvm_unreachable("unimplemented");
}
void visitStoreBorrowInst(StoreBorrowInst *i) {
llvm_unreachable("unimplemented");
}
void visitMarkDependenceInst(MarkDependenceInst *i);
void visitCopyBlockInst(CopyBlockInst *i);
void visitStrongPinInst(StrongPinInst *i);
Expand Down
18 changes: 18 additions & 0 deletions lib/Parse/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,16 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
break;
}

case ValueKind::BeginBorrowInst: {
SourceLoc AddrLoc;

if (parseTypedValueRef(Val, AddrLoc, B) || parseSILDebugLocation(InstLoc, B))
return true;

ResultVal = B.createBeginBorrow(InstLoc, Val);
break;
}

case ValueKind::LoadUnownedInst:
case ValueKind::LoadWeakInst: {
bool isTake = false;
Expand Down Expand Up @@ -2438,6 +2448,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
break;
}

case ValueKind::StoreBorrowInst:
case ValueKind::AssignInst:
case ValueKind::StoreUnownedInst:
case ValueKind::StoreWeakInst: {
Expand Down Expand Up @@ -2468,6 +2479,13 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
return true;
}

if (Opcode == ValueKind::StoreBorrowInst) {
SILType valueTy = addrVal->getType().getObjectType();
ResultVal = B.createStoreBorrow(
InstLoc, getLocalValue(from, valueTy, InstLoc, B), addrVal);
break;
}

if (Opcode == ValueKind::StoreUnownedInst) {
auto refType = addrVal->getType().getAs<UnownedStorageType>();
if (!refType) {
Expand Down
6 changes: 6 additions & 0 deletions lib/SIL/SILInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ namespace {
bool visitLoadBorrowInst(const LoadBorrowInst *RHS) { return true; }

bool visitEndBorrowInst(const EndBorrowInst *RHS) { return true; }
bool visitBeginBorrowInst(const BeginBorrowInst *BBI) { return true; }

bool visitStoreBorrowInst(const StoreBorrowInst *RHS) {
auto *X = cast<StoreBorrowInst>(LHS);
return X->getSrc() == RHS->getSrc() && X->getDest() == RHS->getDest();
}

bool visitStoreInst(const StoreInst *RHS) {
auto *X = cast<StoreInst>(LHS);
Expand Down
5 changes: 5 additions & 0 deletions lib/SIL/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,11 @@ StoreInst::StoreInst(
: SILInstruction(ValueKind::StoreInst, Loc), Operands(this, Src, Dest),
OwnershipQualifier(Qualifier) {}

StoreBorrowInst::StoreBorrowInst(SILDebugLocation DebugLoc, SILValue Src,
SILValue Dest)
: SILInstruction(ValueKind::StoreBorrowInst, DebugLoc, Dest->getType()),
Operands(this, Src, Dest) {}

EndBorrowInst::EndBorrowInst(SILDebugLocation DebugLoc, SILValue Src,
SILValue Dest)
: SILInstruction(ValueKind::EndBorrowInst, DebugLoc),
Expand Down
9 changes: 9 additions & 0 deletions lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,10 @@ class SILPrinter : public SILVisitor<SILPrinter> {
*this << getIDAndType(LBI->getOperand());
}

void visitBeginBorrowInst(BeginBorrowInst *LBI) {
*this << getIDAndType(LBI->getOperand());
}

void printStoreOwnershipQualifier(StoreOwnershipQualifier Qualifier) {
switch (Qualifier) {
case StoreOwnershipQualifier::Unqualified:
Expand All @@ -1060,6 +1064,11 @@ class SILPrinter : public SILVisitor<SILPrinter> {
*this << getIDAndType(SI->getDest());
}

void visitStoreBorrowInst(StoreBorrowInst *SI) {
*this << getID(SI->getSrc()) << " to ";
*this << getIDAndType(SI->getDest());
}

void visitEndBorrowInst(EndBorrowInst *EBI) {
*this << getID(EBI->getDest()) << " from " << getID(EBI->getSrc()) << " : "
<< EBI->getDest()->getType() << ", " << EBI->getSrc()->getType();
Expand Down
16 changes: 16 additions & 0 deletions lib/SILOptimizer/Transforms/OwnershipModelEliminator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,15 @@ struct OwnershipModelEliminatorVisitor
bool visitValueBase(ValueBase *V) { return false; }
bool visitLoadInst(LoadInst *LI);
bool visitStoreInst(StoreInst *SI);
bool visitStoreBorrowInst(StoreBorrowInst *SI);
bool visitCopyValueInst(CopyValueInst *CVI);
bool visitDestroyValueInst(DestroyValueInst *DVI);
bool visitLoadBorrowInst(LoadBorrowInst *LBI);
bool visitBeginBorrowInst(BeginBorrowInst *BBI) {
BBI->replaceAllUsesWith(BBI->getOperand());
BBI->eraseFromParent();
return true;
}
bool visitEndBorrowInst(EndBorrowInst *EBI) {
EBI->eraseFromParent();
return true;
Expand Down Expand Up @@ -95,6 +101,16 @@ bool OwnershipModelEliminatorVisitor::visitStoreInst(StoreInst *SI) {
return true;
}

bool OwnershipModelEliminatorVisitor::visitStoreBorrowInst(
StoreBorrowInst *SI) {
B.emitStoreValueOperation(SI->getLoc(), SI->getSrc(), SI->getDest(),
StoreOwnershipQualifier::Init);

// Then remove the qualified store.
SI->eraseFromParent();
return true;
}

bool
OwnershipModelEliminatorVisitor::visitLoadBorrowInst(LoadBorrowInst *LBI) {
// Break down the load borrow into an unqualified load.
Expand Down
2 changes: 2 additions & 0 deletions lib/SILOptimizer/Utils/SILInliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
case ValueKind::StringLiteralInst:
case ValueKind::FixLifetimeInst:
case ValueKind::EndBorrowInst:
case ValueKind::BeginBorrowInst:
case ValueKind::MarkDependenceInst:
case ValueKind::FunctionRefInst:
case ValueKind::AllocGlobalInst:
Expand Down Expand Up @@ -366,6 +367,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
case ValueKind::RefToUnmanagedInst:
case ValueKind::RefToUnownedInst:
case ValueKind::StoreInst:
case ValueKind::StoreBorrowInst:
case ValueKind::StoreUnownedInst:
case ValueKind::StoreWeakInst:
case ValueKind::StrongPinInst:
Expand Down
9 changes: 9 additions & 0 deletions lib/Serialization/DeserializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
UNARY_INSTRUCTION(FixLifetime)
UNARY_INSTRUCTION(CopyBlock)
UNARY_INSTRUCTION(LoadBorrow)
UNARY_INSTRUCTION(BeginBorrow)
REFCOUNTING_INSTRUCTION(StrongPin)
REFCOUNTING_INSTRUCTION(StrongUnpin)
REFCOUNTING_INSTRUCTION(StrongRetain)
Expand Down Expand Up @@ -1367,6 +1368,14 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
getLocalValue(ValID2, addrType), Qualifier);
break;
}
case ValueKind::StoreBorrowInst: {
auto Ty = MF->getType(TyID);
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory);
SILType ValType = addrType.getObjectType();
ResultVal = Builder.createStoreBorrow(Loc, getLocalValue(ValID, ValType),
getLocalValue(ValID2, addrType));
break;
}
case ValueKind::EndBorrowInst: {
SILValue BorrowSource, BorrowDest;
BorrowSource = getLocalValue(
Expand Down
8 changes: 7 additions & 1 deletion lib/Serialization/SerializeSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
case ValueKind::IsNonnullInst:
case ValueKind::LoadInst:
case ValueKind::LoadBorrowInst:
case ValueKind::BeginBorrowInst:
case ValueKind::LoadUnownedInst:
case ValueKind::LoadWeakInst:
case ValueKind::MarkUninitializedInst:
Expand Down Expand Up @@ -1292,6 +1293,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
case ValueKind::AssignInst:
case ValueKind::CopyAddrInst:
case ValueKind::StoreInst:
case ValueKind::StoreBorrowInst:
case ValueKind::StoreUnownedInst:
case ValueKind::StoreWeakInst: {
SILValue operand, value;
Expand All @@ -1316,8 +1318,12 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
Attr = (CAI->isInitializationOfDest() << 1) | CAI->isTakeOfSrc();
operand = cast<CopyAddrInst>(&SI)->getDest();
value = cast<CopyAddrInst>(&SI)->getSrc();
} else
} else if (auto *SBI = dyn_cast<StoreBorrowInst>(&SI)) {
operand = SBI->getDest();
value = SBI->getSrc();
} else {
llvm_unreachable("switch out of sync");
}

unsigned abbrCode = SILAbbrCodes[SILOneValueOneOperandLayout::Code];
SILOneValueOneOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
Expand Down
17 changes: 14 additions & 3 deletions test/SIL/Parser/borrow.sil
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,27 @@ import Builtin
// We do not verify here, but just make sure that all of the combinations parse and print correctly.
// CHECK-LABEL: sil @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
// CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : $Builtin.NativeObject):
// CHECK: begin_borrow [[ARG2]]
// CHECK: [[MEM:%.*]] = alloc_stack $Builtin.NativeObject
// CHECK: store_borrow [[ARG2]] to [[MEM]] : $*Builtin.NativeObject
// CHECK: end_borrow [[ARG1]] from [[ARG2]] : $*Builtin.NativeObject, $Builtin.NativeObject
// CHECK: end_borrow [[ARG2]] from [[ARG1]] : $Builtin.NativeObject, $*Builtin.NativeObject
// CHECK: end_borrow [[ARG1]] from [[ARG1]] : $*Builtin.NativeObject, $*Builtin.NativeObject
// CHECK: end_borrow [[ARG2]] from [[ARG2]] : $Builtin.NativeObject, $Builtin.NativeObject
sil @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
bb0(%0 : $*Builtin.NativeObject, %1 : $Builtin.NativeObject):
%2 = begin_borrow %1 : $Builtin.NativeObject
end_borrow %2 from %1 : $Builtin.NativeObject, $Builtin.NativeObject

%3 = alloc_stack $Builtin.NativeObject
store_borrow %1 to %3 : $*Builtin.NativeObject
end_borrow %3 from %1 : $*Builtin.NativeObject, $Builtin.NativeObject
dealloc_stack %3 : $*Builtin.NativeObject

end_borrow %0 from %1 : $*Builtin.NativeObject, $Builtin.NativeObject
end_borrow %1 from %0 : $Builtin.NativeObject, $*Builtin.NativeObject
end_borrow %0 from %0 : $*Builtin.NativeObject, $*Builtin.NativeObject
end_borrow %1 from %1 : $Builtin.NativeObject, $Builtin.NativeObject
%2 = tuple()
return %2 : $()
}
%4 = tuple()
return %4 : $()
}
15 changes: 13 additions & 2 deletions test/SIL/Serialization/borrow.sil
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,27 @@ import Builtin
// We do not verify here, but just make sure that all of the combinations parse and print correctly.
// CHECK-LABEL: sil @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
// CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : $Builtin.NativeObject):
// CHECK: begin_borrow [[ARG2]]
// CHECK: [[MEM:%.*]] = alloc_stack $Builtin.NativeObject
// CHECK: store_borrow [[ARG2]] to [[MEM]] : $*Builtin.NativeObject
// CHECK: end_borrow [[ARG1]] from [[ARG2]] : $*Builtin.NativeObject, $Builtin.NativeObject
// CHECK: end_borrow [[ARG2]] from [[ARG1]] : $Builtin.NativeObject, $*Builtin.NativeObject
// CHECK: end_borrow [[ARG1]] from [[ARG1]] : $*Builtin.NativeObject, $*Builtin.NativeObject
// CHECK: end_borrow [[ARG2]] from [[ARG2]] : $Builtin.NativeObject, $Builtin.NativeObject
sil @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
bb0(%0 : $*Builtin.NativeObject, %1 : $Builtin.NativeObject):
%2 = begin_borrow %1 : $Builtin.NativeObject
end_borrow %2 from %1 : $Builtin.NativeObject, $Builtin.NativeObject

%3 = alloc_stack $Builtin.NativeObject
store_borrow %1 to %3 : $*Builtin.NativeObject
end_borrow %3 from %1 : $*Builtin.NativeObject, $Builtin.NativeObject
dealloc_stack %3 : $*Builtin.NativeObject

end_borrow %0 from %1 : $*Builtin.NativeObject, $Builtin.NativeObject
end_borrow %1 from %0 : $Builtin.NativeObject, $*Builtin.NativeObject
end_borrow %0 from %0 : $*Builtin.NativeObject, $*Builtin.NativeObject
end_borrow %1 from %1 : $Builtin.NativeObject, $Builtin.NativeObject
%2 = tuple()
return %2 : $()
%4 = tuple()
return %4 : $()
}
Loading