Merge pull request #8090 from shajrawi/ConsumptionKind_UnconditionalCheckedCastValue

Add consumption kind to UnconditionalCheckedCastValueInst
This commit is contained in:
Joe Shajrawi
2017-03-14 15:30:26 -07:00
committed by GitHub
17 changed files with 80 additions and 36 deletions

View File

@@ -4489,9 +4489,14 @@ unconditional_checked_cast_value
````````````````````````````````
::
sil-instruction ::= 'unconditional_checked_cast_value' sil-operand 'to' sil-type
sil-instruction ::= 'unconditional_checked_cast_value'
sil-cast-consumption-kind
sil-operand 'to' sil-type
sil-cast-consumption-kind ::= 'take_always'
sil-cast-consumption-kind ::= 'take_on_success'
sil-cast-consumption-kind ::= 'copy_on_success'
%1 = unconditional_checked_cast_value %0 : $A to $B
%1 = unconditional_checked_cast_value take_always %0 : $A to $B
// $A must not be an address
// $B must not be an address
// %1 will be of type $B

View File

@@ -801,10 +801,12 @@ public:
}
UnconditionalCheckedCastValueInst *
createUnconditionalCheckedCastValue(SILLocation Loc, SILValue op,
SILType destTy) {
createUnconditionalCheckedCastValue(SILLocation Loc,
CastConsumptionKind consumption,
SILValue op, SILType destTy) {
return insert(UnconditionalCheckedCastValueInst::create(
getSILDebugLocation(Loc), op, destTy, F, OpenedArchetypes));
getSILDebugLocation(Loc), consumption, op, destTy, F,
OpenedArchetypes));
}
RetainValueInst *createRetainValue(SILLocation Loc, SILValue operand,

View File

@@ -1165,7 +1165,7 @@ void SILCloner<ImplClass>::visitUnconditionalCheckedCastValueInst(
SILType OpType = getOpType(Inst->getType());
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst, getBuilder().createUnconditionalCheckedCastValue(
OpLoc, OpValue, OpType));
OpLoc, Inst->getConsumptionKind(), OpValue, OpType));
}
template <typename ImplClass>

View File

@@ -2862,16 +2862,24 @@ class UnconditionalCheckedCastValueInst final
ValueKind::UnconditionalCheckedCastValueInst,
UnconditionalCheckedCastValueInst, ConversionInst, true> {
friend SILBuilder;
CastConsumptionKind ConsumptionKind;
UnconditionalCheckedCastValueInst(SILDebugLocation DebugLoc, SILValue Operand,
UnconditionalCheckedCastValueInst(SILDebugLocation DebugLoc,
CastConsumptionKind consumption,
SILValue Operand,
ArrayRef<SILValue> TypeDependentOperands,
SILType DestTy)
: UnaryInstructionWithTypeDependentOperandsBase(
DebugLoc, Operand, TypeDependentOperands, DestTy) {}
DebugLoc, Operand, TypeDependentOperands, DestTy),
ConsumptionKind(consumption) {}
static UnconditionalCheckedCastValueInst *
create(SILDebugLocation DebugLoc, SILValue Operand, SILType DestTy,
SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes);
create(SILDebugLocation DebugLoc, CastConsumptionKind consumption,
SILValue Operand, SILType DestTy, SILFunction &F,
SILOpenedArchetypesState &OpenedArchetypes);
public:
CastConsumptionKind getConsumptionKind() const { return ConsumptionKind; }
};
/// StructInst - Represents a constructed loadable struct.

View File

@@ -2481,9 +2481,34 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
break;
}
case ValueKind::UnconditionalCheckedCastValueInst: {
CastConsumptionKind consumptionKind;
Identifier consumptionKindToken;
SourceLoc consumptionKindLoc;
SILType ty;
SILValue destVal;
Identifier toToken;
SourceLoc toLoc;
if (parseSILIdentifier(consumptionKindToken, consumptionKindLoc,
diag::expected_tok_in_sil_instr,
"cast consumption kind") ||
parseCastConsumptionKind(consumptionKindToken, consumptionKindLoc,
consumptionKind))
return true;
if (parseTypedValueRef(Val, B) || parseVerbatim("to") || parseSILType(ty))
return true;
if (parseSILDebugLocation(InstLoc, B))
return true;
ResultVal = B.createUnconditionalCheckedCastValue(InstLoc, consumptionKind,
Val, ty);
break;
}
// Checked Conversion instructions.
case ValueKind::UnconditionalCheckedCastInst:
case ValueKind::UnconditionalCheckedCastValueInst:
case ValueKind::CheckedCastValueBranchInst:
case ValueKind::CheckedCastBranchInst: {
SILType ty;
@@ -2507,11 +2532,6 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
return true;
ResultVal = B.createUnconditionalCheckedCast(InstLoc, Val, ty);
break;
} else if (Opcode == ValueKind::UnconditionalCheckedCastValueInst) {
if (parseSILDebugLocation(InstLoc, B))
return true;
ResultVal = B.createUnconditionalCheckedCastValue(InstLoc, Val, ty);
break;
}
// The conditional cast still needs its branch destinations.
Identifier successBBName, failureBBName;

View File

@@ -1775,7 +1775,8 @@ UnconditionalCheckedCastInst *UnconditionalCheckedCastInst::create(
}
UnconditionalCheckedCastValueInst *UnconditionalCheckedCastValueInst::create(
SILDebugLocation DebugLoc, SILValue Operand, SILType DestTy, SILFunction &F,
SILDebugLocation DebugLoc, CastConsumptionKind consumption,
SILValue Operand, SILType DestTy, SILFunction &F,
SILOpenedArchetypesState &OpenedArchetypes) {
SILModule &Mod = F.getModule();
SmallVector<SILValue, 8> TypeDependentOperands;
@@ -1786,7 +1787,7 @@ UnconditionalCheckedCastValueInst *UnconditionalCheckedCastValueInst::create(
void *Buffer =
Mod.allocateInst(size, alignof(UnconditionalCheckedCastValueInst));
return ::new (Buffer) UnconditionalCheckedCastValueInst(
DebugLoc, Operand, TypeDependentOperands, DestTy);
DebugLoc, consumption, Operand, TypeDependentOperands, DestTy);
}
CheckedCastBranchInst *CheckedCastBranchInst::create(

View File

@@ -1224,7 +1224,8 @@ public:
void visitUnconditionalCheckedCastValueInst(
UnconditionalCheckedCastValueInst *CI) {
*this << getIDAndType(CI->getOperand()) << " to " << CI->getType();
*this << getCastConsumptionKindName(CI->getConsumptionKind()) << ' '
<< getIDAndType(CI->getOperand()) << " to " << CI->getType();
}
void visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CI) {

View File

@@ -546,9 +546,10 @@ ManagedValue SILGenBuilder::createEnum(SILLocation loc, ManagedValue payload,
}
ManagedValue SILGenBuilder::createUnconditionalCheckedCastValue(
SILLocation loc, ManagedValue operand, SILType type) {
SILLocation loc, CastConsumptionKind consumption, ManagedValue operand,
SILType type) {
SILValue result = SILBuilder::createUnconditionalCheckedCastValue(
loc, operand.forward(SGF), type);
loc, consumption, operand.forward(SGF), type);
return SGF.emitManagedRValueWithCleanup(result);
}

View File

@@ -224,9 +224,10 @@ public:
SGFContext context, std::function<void(SILValue)> rvalueEmitter);
using SILBuilder::createUnconditionalCheckedCastValue;
ManagedValue createUnconditionalCheckedCastValue(SILLocation loc,
ManagedValue operand,
SILType type);
ManagedValue
createUnconditionalCheckedCastValue(SILLocation loc,
CastConsumptionKind consumption,
ManagedValue operand, SILType type);
using SILBuilder::createUnconditionalCheckedCast;
ManagedValue createUnconditionalCheckedCast(SILLocation loc,
ManagedValue operand,

View File

@@ -102,7 +102,8 @@ namespace {
ManagedValue result;
if (Strategy == CastStrategy::Address) {
result = SGF.B.createUnconditionalCheckedCastValue(
Loc, operand, origTargetTL.getLoweredType());
Loc, CastConsumptionKind::TakeAlways, operand,
origTargetTL.getLoweredType());
} else {
result = SGF.B.createUnconditionalCheckedCast(
Loc, operand, origTargetTL.getLoweredType());
@@ -388,7 +389,8 @@ namespace {
SILValue resultScalar;
if (Strategy == CastStrategy::Address) {
resultScalar = SGF.B.createUnconditionalCheckedCastValue(
Loc, operand.forward(SGF), origTargetTL.getLoweredType());
Loc, CastConsumptionKind::TakeAlways, operand.forward(SGF),
origTargetTL.getLoweredType());
} else {
resultScalar = SGF.B.createUnconditionalCheckedCast(
Loc, operand.forward(SGF), origTargetTL.getLoweredType());

View File

@@ -2046,7 +2046,7 @@ SILInstruction *CastOptimizer::simplifyCheckedCastValueBranchInst(
if (!CastedValue)
CastedValue = Builder.createUnconditionalCheckedCastValue(
Loc, Op, LoweredTargetType);
Loc, CastConsumptionKind::TakeAlways, Op, LoweredTargetType);
} else {
CastedValue = SILUndef::get(LoweredTargetType, Mod);
}

View File

@@ -1930,10 +1930,12 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB,
break;
}
case ValueKind::UnconditionalCheckedCastValueInst: {
CastConsumptionKind consumption = getCastConsumptionKind(Attr);
SILValue Val = getLocalValue(
ValID, getSILType(MF->getType(TyID2), (SILValueCategory)TyCategory2));
SILType Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory);
ResultVal = Builder.createUnconditionalCheckedCastValue(Loc, Val, Ty);
ResultVal =
Builder.createUnconditionalCheckedCastValue(Loc, consumption, Val, Ty);
break;
}
case ValueKind::UnconditionalCheckedCastAddrInst:

View File

@@ -1313,7 +1313,8 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
auto CI = cast<UnconditionalCheckedCastValueInst>(&SI);
SILInstCastLayout::emitRecord(
Out, ScratchRecord, SILAbbrCodes[SILInstCastLayout::Code],
(unsigned)SI.getKind(), /*attr*/ 0,
(unsigned)SI.getKind(),
toStableCastConsumptionKind(CI->getConsumptionKind()),
S.addTypeRef(CI->getType().getSwiftRValueType()),
(unsigned)CI->getType().getCategory(),
S.addTypeRef(CI->getOperand()->getType().getSwiftRValueType()),

View File

@@ -16,11 +16,11 @@ struct S : Foo {
// CHECK-LABEL: sil @castOpaque : $@convention(thin) (Int) -> () {
// CHECK: bb0([[ARG:%.*]] : $Int):
// CHECK: unconditional_checked_cast_value [[ARG]] : $Int to $Foo
// CHECK: unconditional_checked_cast_value take_always [[ARG]] : $Int to $Foo
// CHECK-LABEL: } // end sil function 'castOpaque'
sil @castOpaque : $@convention(thin) (Int) -> () {
bb0(%0 : $Int):
%c = unconditional_checked_cast_value %0 : $Int to $Foo
%c = unconditional_checked_cast_value take_always %0 : $Int to $Foo
%t = tuple ()
return %t : $()
}

View File

@@ -22,11 +22,11 @@ struct S : Foo {
// CHECK-LABEL: sil @castOpaque : $@convention(thin) (Int) -> () {
// CHECK: bb0([[ARG:%.*]] : $Int):
// CHECK: unconditional_checked_cast_value [[ARG]] : $Int to $Foo
// CHECK: unconditional_checked_cast_value take_always [[ARG]] : $Int to $Foo
// CHECK-LABEL: } // end sil function 'castOpaque'
sil @castOpaque : $@convention(thin) (Int) -> () {
bb0(%0 : $Int):
%c = unconditional_checked_cast_value %0 : $Int to $Foo
%c = unconditional_checked_cast_value take_always %0 : $Int to $Foo
%t = tuple ()
return %t : $()
}

View File

@@ -11,6 +11,6 @@ import Builtin
sil @unconditional_checked_cast_value_test : $@convention(thin) <T> (Builtin.Int32) -> @out T {
bb0(%0 : @trivial $Builtin.Int32):
%1 = unconditional_checked_cast_value %0 : $Builtin.Int32 to $T
%1 = unconditional_checked_cast_value take_always %0 : $Builtin.Int32 to $T
return %1 : $T
}

View File

@@ -258,7 +258,7 @@ func s160_______callAnyArg() {
// CHECK: [[INT_TYPE:%.*]] = metatype $@thin Int.Type
// CHECK: [[INT_LIT:%.*]] = integer_literal $Builtin.Int2048, 42
// CHECK: [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
// CHECK: [[INT_CAST:%.*]] = unconditional_checked_cast_value [[INT_ARG]] : $Int to $T
// CHECK: [[INT_CAST:%.*]] = unconditional_checked_cast_value take_always [[INT_ARG]] : $Int to $T
// CHECK: [[CAST_BORROW:%.*]] = begin_borrow [[INT_CAST]] : $T
// CHECK: [[RETURN_VAL:%.*]] = copy_value [[CAST_BORROW]] : $T
// CHECK: end_borrow [[CAST_BORROW]] from [[INT_CAST]] : $T, $T
@@ -276,7 +276,7 @@ func s170____force_convert<T>() -> T {
// CHECK: bb0:
// CHECK: [[INT_LIT:%.*]] = integer_literal $Builtin.Int2048, 42
// CHECK: [[INT_ARG:%.*]] = apply %{{.*}}([[INT_LIT]], [[INT_TYPE]]) : $@convention(method) (Builtin.Int2048, @thin Int.Type) -> Int
// CHECK: [[INT_CAST:%.*]] = unconditional_checked_cast_value [[INT_ARG]] : $Int to $Foo
// CHECK: [[INT_CAST:%.*]] = unconditional_checked_cast_value take_always [[INT_ARG]] : $Int to $Foo
// CHECK: return [[INT_CAST]] : $Foo
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s180_______return_fooAA3Foo_pyF'
func s180_______return_foo() -> Foo {