[specializer] Teach the specializer how to handle indentity {unconditional_checked_cast,checked_cast_br} super_to_archetype.

This is working under the assumption that every class is in a certain
sense its own super class (or we are allowing it to be so for these
casts).

Swift SVN r18020
This commit is contained in:
Michael Gottesman
2014-05-13 20:15:31 +00:00
parent 5d95457efc
commit d866316e04
3 changed files with 46 additions and 6 deletions

View File

@@ -288,16 +288,27 @@ private:
SILCloner<TypeSubCloner>::visitUnconditionalCheckedCastInst(Inst);
return;
case CheckedCastKind::SuperToArchetype: {
// Just change the type of cast to an unconditional_checked_cast downcast
SILLocation OpLoc = getOpLocation(Inst->getLoc());
SILValue OpValue = getOpValue(Inst->getOperand());
SILType OpType = getOpType(Inst->getType());
SILType OpFromTy = OpValue.getType();
SILType OpToTy = getOpType(Inst->getType());
// If the from/to type is the same, just propagate the operand along to
// all uses.
if (OpFromTy == OpToTy) {
auto Pair = std::make_pair(SILValue(Inst),
OpValue);
ValueMap.insert(Pair);
return;
}
// Otherwise we assume this is an unconditional_checked_cast downcast.
SILLocation OpLoc = getOpLocation(Inst->getLoc());
CheckedCastKind OpCastKind = CheckedCastKind::Downcast;
doPostProcess(Inst,
getBuilder().createUnconditionalCheckedCast(OpLoc,
OpCastKind,
OpValue,
OpType));
OpToTy));
return;
}
case CheckedCastKind::ArchetypeToArchetype:
@@ -422,15 +433,28 @@ private:
// Just change the type of cast to a checked_cast_br downcast
SILLocation OpLoc = getOpLocation(Inst->getLoc());
SILValue OpValue = getOpValue(Inst->getOperand());
SILType OpType = getOpType(Inst->getCastType());
SILType OpFromTy = OpValue.getType();
SILType OpToTy = getOpType(Inst->getCastType());
SILBasicBlock *OpSuccBB = getOpBasicBlock(Inst->getSuccessBB());
// If the from/to type is the same, insert a branch to the success basic
// block with the relevant argument.
if (OpFromTy == OpToTy) {
auto Args = ArrayRef<SILValue>(getOpValue(Inst->getOperand()));
auto *Br = Builder.createBranch(OpLoc, OpSuccBB, Args);
doPostProcess(Inst, Br);
return;
}
// Otherwise we assume that we are performing a checked_cast_kind
// downcast.
SILBasicBlock *OpFailBB = getOpBasicBlock(Inst->getFailureBB());
CheckedCastKind OpCastKind = CheckedCastKind::Downcast;
doPostProcess(Inst,
getBuilder().createCheckedCastBranch(OpLoc,
OpCastKind,
OpValue,
OpType,
OpToTy,
OpSuccBB,
OpFailBB));
return;

View File

@@ -304,6 +304,13 @@ SuperToArchetypeCastC(c: c, t: b)
// CHECK: bb1
SuperToArchetypeCastD(d: d, t: c)
// CHECK-LABEL: sil shared @_TTSC30specialize_checked_cast_branch1D___TF30specialize_checked_cast_branch21SuperToArchetypeCastDU__FT1dCS_1D1tQ__Q_ : $@thin (@out D, @owned D, @in D) -> () {
// CHECK: bb0
// CHECK: function_ref @_TTSC30specialize_checked_cast_branch1D___TFSs24_injectValueIntoOptionalU__FQ_GSqQ__ : $@thin (@out Optional<D>, @in D) -> ()
// CHECK-NOT: checked_cast_br super_to_archetype
// CHECK: bb1
SuperToArchetypeCastD(d: d, t: d)
//////////////////////////////
// Existential To Archetype //
//////////////////////////////

View File

@@ -300,6 +300,15 @@ SuperToArchetypeC(c: c, t: b)
// CHECK-NOT: unconditional_checked_cast super_to_archetype
SuperToArchetypeD(d: d, t: c)
// CHECK-LABEL: sil shared @_TTSC37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast17SuperToArchetypeDU__FT1dCS_1D1tQ__Q_ : $@thin (@out D, @owned D, @in D) -> () {
// CHECK: bb0
// CHECK-NEXT: store
// CHECK-NEXT: load
// CHECK-NEXT: strong_release
// CHECK-NEXT: tuple
// CHECK-NEXT: return
SuperToArchetypeD(d: d, t: d)
//////////////////////////////
// Existential To Archetype //
//////////////////////////////