SIL: Give project_box a field index operand.

Allow project_box to get the address of any field in a multi-field box.
This commit is contained in:
Joe Groff
2016-10-21 16:01:06 -07:00
parent 374fa57530
commit e4c67e2d5a
62 changed files with 694 additions and 648 deletions

View File

@@ -294,8 +294,7 @@ public:
case ProjectionKind::Enum:
return BaseType.getEnumElementType(getEnumElementDecl(BaseType), M);
case ProjectionKind::Box:
return SILType::getPrimitiveAddressType(BaseType.castTo<SILBoxType>()->
getBoxedType());
return BaseType.castTo<SILBoxType>()->getFieldType(getIndex());
case ProjectionKind::Tuple:
return BaseType.getTupleElementType(getIndex());
case ProjectionKind::Upcast:

View File

@@ -1226,17 +1226,13 @@ public:
return insert(new (F.getModule()) ProjectValueBufferInst(
getSILDebugLocation(Loc), valueType, operand));
}
ProjectBoxInst *createProjectBox(SILLocation Loc, SILValue boxOperand) {
auto valueTy =
boxOperand->getType().castTo<SILBoxType>()->getBoxedAddressType();
ProjectBoxInst *createProjectBox(SILLocation Loc, SILValue boxOperand,
unsigned index) {
auto boxTy = boxOperand->getType().castTo<SILBoxType>();
auto fieldTy = boxTy->getFieldType(index);
return insert(new (F.getModule()) ProjectBoxInst(
getSILDebugLocation(Loc), valueTy, boxOperand));
}
ProjectBoxInst *createProjectBox(SILLocation Loc, SILType valueTy,
SILValue boxOperand) {
return insert(new (F.getModule()) ProjectBoxInst(
getSILDebugLocation(Loc), valueTy, boxOperand));
getSILDebugLocation(Loc), boxOperand, index, fieldTy));
}
ProjectExistentialBoxInst *createProjectExistentialBox(SILLocation Loc,
SILType valueTy,

View File

@@ -1739,8 +1739,8 @@ void SILCloner<ImplClass>::visitProjectBoxInst(ProjectBoxInst *Inst) {
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createProjectBox(getOpLocation(Inst->getLoc()),
getOpType(Inst->getValueType()),
getOpValue(Inst->getOperand())));
getOpValue(Inst->getOperand()),
Inst->getFieldIndex()));
}
template<typename ImplClass>
@@ -1749,7 +1749,7 @@ void SILCloner<ImplClass>::visitProjectExistentialBoxInst(
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createProjectExistentialBox(getOpLocation(Inst->getLoc()),
getOpType(Inst->getValueType()),
getOpType(Inst->getType()),
getOpValue(Inst->getOperand())));
}

View File

@@ -4409,12 +4409,18 @@ class ProjectBoxInst :
SILInstruction, /*HasResult*/ true> {
friend SILBuilder;
ProjectBoxInst(SILDebugLocation DebugLoc, SILType valueType,
SILValue operand)
: UnaryInstructionBase(DebugLoc, operand, valueType.getAddressType()) {}
unsigned Index;
ProjectBoxInst(SILDebugLocation DebugLoc,
SILValue operand,
unsigned fieldIndex,
SILType fieldTy)
: UnaryInstructionBase(DebugLoc, operand, fieldTy.getAddressType()),
Index(fieldIndex) {}
public:
SILType getValueType() const { return getType().getObjectType(); }
unsigned getFieldIndex() const { return Index; }
};
/// Project out the address of the value in an existential box.
@@ -4426,9 +4432,6 @@ class ProjectExistentialBoxInst :
ProjectExistentialBoxInst(SILDebugLocation DebugLoc, SILType valueType,
SILValue operand)
: UnaryInstructionBase(DebugLoc, operand, valueType.getAddressType()) {}
public:
SILType getValueType() const { return getType().getObjectType(); }
};
//===----------------------------------------------------------------------===//

View File

@@ -149,6 +149,17 @@ public:
}
};
inline SILType SILBoxType::getFieldType(unsigned index) const {
auto fieldTy = getLayout()->getFields()[index].getLoweredType();
// Apply generic arguments if the layout is generic.
if (!getGenericArgs().empty()) {
auto substMap =
getLayout()->getGenericSignature()->getSubstitutionMap(getGenericArgs());
fieldTy = fieldTy.subst(substMap)->getCanonicalType();
}
return SILType::getPrimitiveAddressType(fieldTy);
}
} // end namespace swift
#endif // SWIFT_SIL_LAYOUT_H