LoadableByAddress: Handle substituted SILFunctionTypes

This commit is contained in:
Joe Groff
2020-02-04 15:52:34 -08:00
parent 35560321b7
commit 79a8081a96

View File

@@ -36,8 +36,15 @@
using namespace swift; using namespace swift;
using namespace swift::irgen; using namespace swift::irgen;
static GenericEnvironment *getGenericEnvironment(CanSILFunctionType loweredTy) { static GenericEnvironment *getSubstGenericEnvironment(CanSILFunctionType fnTy) {
return loweredTy->getSubstGenericSignature()->getGenericEnvironment(); auto sig = fnTy->getSubstGenericSignature();
return sig ? sig->getGenericEnvironment() : nullptr;
}
static GenericEnvironment *getSubstGenericEnvironment(SILFunction *F) {
if (F->getLoweredFunctionType()->isPolymorphic())
return F->getGenericEnvironment();
return getSubstGenericEnvironment(F->getLoweredFunctionType());
} }
class LargeSILTypeMapper { class LargeSILTypeMapper {
@@ -141,6 +148,12 @@ static bool isFuncOrOptionalFuncType(SILType Ty) {
bool LargeSILTypeMapper::shouldTransformFunctionType(GenericEnvironment *env, bool LargeSILTypeMapper::shouldTransformFunctionType(GenericEnvironment *env,
CanSILFunctionType fnType, CanSILFunctionType fnType,
irgen::IRGenModule &IGM) { irgen::IRGenModule &IGM) {
// Map substituted function types according to their substituted generic
// signature.
if (fnType->getSubstitutions()) {
env = getSubstGenericEnvironment(fnType);
}
if (shouldTransformResults(env, fnType, IGM)) if (shouldTransformResults(env, fnType, IGM))
return true; return true;
@@ -271,6 +284,13 @@ LargeSILTypeMapper::getNewSILFunctionType(GenericEnvironment *env,
if (!modifiableFunction(fnType)) { if (!modifiableFunction(fnType)) {
return fnType; return fnType;
} }
// Map substituted function types according to their substituted generic
// signature.
if (fnType->getSubstitutions()) {
env = getSubstGenericEnvironment(fnType);
}
auto newParams = getNewParameters(env, fnType, IGM); auto newParams = getNewParameters(env, fnType, IGM);
auto newYields = getNewYields(env, fnType, IGM); auto newYields = getNewYields(env, fnType, IGM);
auto newResults = getNewResults(env, fnType, IGM); auto newResults = getNewResults(env, fnType, IGM);
@@ -332,7 +352,7 @@ bool LargeSILTypeMapper::shouldTransformResults(GenericEnvironment *genEnv,
static bool modResultType(SILFunction *F, irgen::IRGenModule &Mod, static bool modResultType(SILFunction *F, irgen::IRGenModule &Mod,
LargeSILTypeMapper &Mapper) { LargeSILTypeMapper &Mapper) {
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto loweredTy = F->getLoweredFunctionType(); auto loweredTy = F->getLoweredFunctionType();
return Mapper.shouldTransformResults(genEnv, loweredTy, Mod); return Mapper.shouldTransformResults(genEnv, loweredTy, Mod);
@@ -357,7 +377,7 @@ static bool shouldTransformYields(GenericEnvironment *genEnv,
static bool modYieldType(SILFunction *F, irgen::IRGenModule &Mod, static bool modYieldType(SILFunction *F, irgen::IRGenModule &Mod,
LargeSILTypeMapper &Mapper) { LargeSILTypeMapper &Mapper) {
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto loweredTy = F->getLoweredFunctionType(); auto loweredTy = F->getLoweredFunctionType();
return shouldTransformYields(genEnv, loweredTy, Mod, Mapper); return shouldTransformYields(genEnv, loweredTy, Mod, Mapper);
@@ -550,24 +570,25 @@ struct StructLoweringState {
LargeSILTypeMapper &Mapper) LargeSILTypeMapper &Mapper)
: F(F), Mod(Mod), Mapper(Mapper) {} : F(F), Mod(Mod), Mapper(Mapper) {}
bool isLargeLoadableType(SILType type) { bool isLargeLoadableType(CanSILFunctionType fnTy, SILType type) {
return ::isLargeLoadableType(F->getGenericEnvironment(), type, Mod); return ::isLargeLoadableType(getSubstGenericEnvironment(fnTy), type, Mod);
} }
SILType getNewSILType(SILType type) { SILType getNewSILType(CanSILFunctionType fnTy, SILType type) {
return Mapper.getNewSILType(F->getGenericEnvironment(), type, Mod); return Mapper.getNewSILType(getSubstGenericEnvironment(fnTy), type, Mod);
} }
bool containsDifferentFunctionSignature(SILType type) { bool containsDifferentFunctionSignature(CanSILFunctionType fnTy,
SILType type) {
return Mapper.containsDifferentFunctionSignature( return Mapper.containsDifferentFunctionSignature(
F->getGenericEnvironment(), Mod, type, getNewSILType(type)); getSubstGenericEnvironment(fnTy), Mod, type, getNewSILType(fnTy, type));
} }
bool hasLargeLoadableYields() { bool hasLargeLoadableYields() {
auto fnType = F->getLoweredFunctionType(); auto fnType = F->getLoweredFunctionType();
if (!fnType->isCoroutine()) return false; if (!fnType->isCoroutine()) return false;
auto env = F->getGenericEnvironment(); auto env = getSubstGenericEnvironment(fnType);
for (auto yield : fnType->getYields()) { for (auto yield : fnType->getYields()) {
if (Mapper.shouldTransformParameter(env, yield, Mod)) if (Mapper.shouldTransformParameter(env, yield, Mod))
return true; return true;
@@ -743,7 +764,8 @@ void LargeValueVisitor::visitApply(ApplySite applySite) {
for (Operand &operand : applySite.getArgumentOperands()) { for (Operand &operand : applySite.getArgumentOperands()) {
SILValue currOperand = operand.get(); SILValue currOperand = operand.get();
SILType silType = currOperand->getType(); SILType silType = currOperand->getType();
SILType newSilType = pass.getNewSILType(silType); SILType newSilType = pass.getNewSILType(applySite.getSubstCalleeType(),
silType);
if (silType != newSilType || if (silType != newSilType ||
std::find(pass.largeLoadableArgs.begin(), pass.largeLoadableArgs.end(), std::find(pass.largeLoadableArgs.begin(), pass.largeLoadableArgs.end(),
currOperand) != pass.largeLoadableArgs.end() || currOperand) != pass.largeLoadableArgs.end() ||
@@ -759,7 +781,8 @@ void LargeValueVisitor::visitApply(ApplySite applySite) {
if (auto beginApply = dyn_cast<BeginApplyInst>(applySite)) { if (auto beginApply = dyn_cast<BeginApplyInst>(applySite)) {
for (auto yield : beginApply->getYieldedValues()) { for (auto yield : beginApply->getYieldedValues()) {
auto oldYieldType = yield->getType(); auto oldYieldType = yield->getType();
auto newYieldType = pass.getNewSILType(oldYieldType); auto newYieldType = pass.getNewSILType(beginApply->getSubstCalleeType(),
oldYieldType);
if (oldYieldType != newYieldType) { if (oldYieldType != newYieldType) {
pass.applies.push_back(applySite.getInstruction()); pass.applies.push_back(applySite.getInstruction());
return; return;
@@ -769,9 +792,11 @@ void LargeValueVisitor::visitApply(ApplySite applySite) {
} }
SILType currType = applySite.getType(); SILType currType = applySite.getType();
SILType newType = pass.getNewSILType(currType); SILType newType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currType);
// We only care about function type results // We only care about function type results
if (!pass.isLargeLoadableType(currType) && if (!pass.isLargeLoadableType(pass.F->getLoweredFunctionType(),
currType) &&
(currType != newType)) { (currType != newType)) {
pass.applies.push_back(applySite.getInstruction()); pass.applies.push_back(applySite.getInstruction());
return; return;
@@ -810,7 +835,7 @@ void LargeValueVisitor::visitMethodInst(MethodInst *instr) {
GenericEnvironment *genEnv = nullptr; GenericEnvironment *genEnv = nullptr;
if (fnType->isPolymorphic()) { if (fnType->isPolymorphic()) {
genEnv = getGenericEnvironment(fnType); genEnv = getSubstGenericEnvironment(fnType);
} }
if (pass.Mapper.shouldTransformFunctionType(genEnv, fnType, pass.Mod)) { if (pass.Mapper.shouldTransformFunctionType(genEnv, fnType, pass.Mod)) {
pass.methodInstsToMod.push_back(instr); pass.methodInstsToMod.push_back(instr);
@@ -833,11 +858,11 @@ bool LargeSILTypeMapper::shouldConvertBBArg(SILArgument *arg,
irgen::IRGenModule &Mod) { irgen::IRGenModule &Mod) {
auto *F = arg->getFunction(); auto *F = arg->getFunction();
SILType storageType = arg->getType(); SILType storageType = arg->getType();
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto currCanType = storageType.getASTType(); auto currCanType = storageType.getASTType();
if (auto funcType = dyn_cast<SILFunctionType>(currCanType)) { if (auto funcType = dyn_cast<SILFunctionType>(currCanType)) {
if (funcType->isPolymorphic()) { if (funcType->isPolymorphic()) {
genEnv = getGenericEnvironment(funcType); genEnv = getSubstGenericEnvironment(funcType);
} }
} }
SILType newSILType = getNewSILType(genEnv, storageType, Mod); SILType newSILType = getNewSILType(genEnv, storageType, Mod);
@@ -866,7 +891,8 @@ void LargeValueVisitor::visitSwitchEnumInst(SwitchEnumInst *instr) {
for (SILArgument *arg : currBB->getArguments()) { for (SILArgument *arg : currBB->getArguments()) {
if (pass.Mapper.shouldConvertBBArg(arg, pass.Mod)) { if (pass.Mapper.shouldConvertBBArg(arg, pass.Mod)) {
SILType storageType = arg->getType(); SILType storageType = arg->getType();
SILType newSILType = pass.getNewSILType(storageType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
storageType);
if (newSILType.isAddress()) { if (newSILType.isAddress()) {
pass.switchEnumInstsToMod.push_back(instr); pass.switchEnumInstsToMod.push_back(instr);
return; return;
@@ -924,7 +950,8 @@ void LargeValueVisitor::visitDestroyValueInst(DestroyValueInst *instr) {
void LargeValueVisitor::visitResultTyInst(SingleValueInstruction *instr) { void LargeValueVisitor::visitResultTyInst(SingleValueInstruction *instr) {
SILType currSILType = instr->getType().getObjectType(); SILType currSILType = instr->getType().getObjectType();
SILType newSILType = pass.getNewSILType(currSILType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currSILType);
if (currSILType != newSILType) { if (currSILType != newSILType) {
pass.resultTyInstsToMod.insert(instr); pass.resultTyInstsToMod.insert(instr);
} }
@@ -939,9 +966,9 @@ void LargeValueVisitor::visitResultTyInst(SingleValueInstruction *instr) {
void LargeValueVisitor::visitTupleInst(SingleValueInstruction *instr) { void LargeValueVisitor::visitTupleInst(SingleValueInstruction *instr) {
SILType currSILType = instr->getType().getObjectType(); SILType currSILType = instr->getType().getObjectType();
if (auto funcType = getInnerFunctionType(currSILType)) { if (auto funcType = getInnerFunctionType(currSILType)) {
GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(instr->getFunction());
if (!genEnv && funcType->isPolymorphic()) { if (!genEnv && funcType->isPolymorphic()) {
genEnv = getGenericEnvironment(funcType); genEnv = getSubstGenericEnvironment(funcType);
} }
auto newSILFunctionType = auto newSILFunctionType =
pass.Mapper.getNewSILFunctionType(genEnv, funcType, pass.Mod); pass.Mapper.getNewSILFunctionType(genEnv, funcType, pass.Mod);
@@ -967,7 +994,7 @@ void LargeValueVisitor::visitPointerToAddressInst(PointerToAddressInst *instr) {
} }
static bool modNonFuncTypeResultType(SILFunction *F, irgen::IRGenModule &Mod) { static bool modNonFuncTypeResultType(SILFunction *F, irgen::IRGenModule &Mod) {
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto loweredTy = F->getLoweredFunctionType(); auto loweredTy = F->getLoweredFunctionType();
return modNonFuncTypeResultType(genEnv, loweredTy, Mod); return modNonFuncTypeResultType(genEnv, loweredTy, Mod);
} }
@@ -1177,7 +1204,8 @@ void LoadableStorageAllocation::replaceLoadWithCopyAddr(
static bool isYieldUseRewriteable(StructLoweringState &pass, static bool isYieldUseRewriteable(StructLoweringState &pass,
YieldInst *inst, Operand *operand) { YieldInst *inst, Operand *operand) {
assert(inst == operand->getUser()); assert(inst == operand->getUser());
return pass.isLargeLoadableType(operand->get()->getType()); return pass.isLargeLoadableType(pass.F->getLoweredFunctionType(),
operand->get()->getType());
} }
/// Does the value's uses contain instructions that *must* be rewrites? /// Does the value's uses contain instructions that *must* be rewrites?
@@ -1196,7 +1224,8 @@ static bool hasMandatoryRewriteUse(StructLoweringState &pass,
break; break;
} }
SILType currType = value->getType().getObjectType(); SILType currType = value->getType().getObjectType();
SILType newSILType = pass.getNewSILType(currType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currType);
if (currType == newSILType) { if (currType == newSILType) {
break; break;
} }
@@ -1245,7 +1274,8 @@ void LoadableStorageAllocation::replaceLoadWithCopyAddrForModifiable(
break; break;
} }
SILType currType = unoptimizableLoad->getType().getObjectType(); SILType currType = unoptimizableLoad->getType().getObjectType();
SILType newSILType = pass.getNewSILType(currType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currType);
if (currType == newSILType) { if (currType == newSILType) {
break; break;
} }
@@ -1365,7 +1395,7 @@ SILArgument *LoadableStorageAllocation::replaceArgType(SILBuilder &argBuilder,
} }
void LoadableStorageAllocation::insertIndirectReturnArgs() { void LoadableStorageAllocation::insertIndirectReturnArgs() {
GenericEnvironment *genEnv = pass.F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(pass.F);
auto loweredTy = pass.F->getLoweredFunctionType(); auto loweredTy = pass.F->getLoweredFunctionType();
SILType resultStorageType = loweredTy->getAllResultsInterfaceType(); SILType resultStorageType = loweredTy->getAllResultsInterfaceType();
auto canType = resultStorageType.getASTType(); auto canType = resultStorageType.getASTType();
@@ -1374,7 +1404,7 @@ void LoadableStorageAllocation::insertIndirectReturnArgs() {
canType = genEnv->mapTypeIntoContext(canType)->getCanonicalType(); canType = genEnv->mapTypeIntoContext(canType)->getCanonicalType();
} }
resultStorageType = SILType::getPrimitiveObjectType(canType); resultStorageType = SILType::getPrimitiveObjectType(canType);
auto newResultStorageType = pass.getNewSILType(resultStorageType); auto newResultStorageType = pass.getNewSILType(loweredTy, resultStorageType);
auto &ctx = pass.F->getModule().getASTContext(); auto &ctx = pass.F->getModule().getASTContext();
auto var = new (ctx) ParamDecl( auto var = new (ctx) ParamDecl(
@@ -1393,11 +1423,13 @@ void LoadableStorageAllocation::convertIndirectFunctionArgs() {
for (SILArgument *arg : entry->getArguments()) { for (SILArgument *arg : entry->getArguments()) {
SILType storageType = arg->getType(); SILType storageType = arg->getType();
SILType newSILType = pass.getNewSILType(storageType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
storageType);
if (newSILType != storageType) { if (newSILType != storageType) {
ValueOwnershipKind ownership = arg->getOwnershipKind(); ValueOwnershipKind ownership = arg->getOwnershipKind();
arg = replaceArgType(argBuilder, arg, newSILType); arg = replaceArgType(argBuilder, arg, newSILType);
if (pass.isLargeLoadableType(storageType)) { if (pass.isLargeLoadableType(pass.F->getLoweredFunctionType(),
storageType)) {
// Add to largeLoadableArgs if and only if it wasn't a modified function // Add to largeLoadableArgs if and only if it wasn't a modified function
// signature arg // signature arg
pass.largeLoadableArgs.push_back(arg); pass.largeLoadableArgs.push_back(arg);
@@ -1456,13 +1488,13 @@ void LoadableStorageAllocation::convertApplyResults() {
} }
CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType(); CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
GenericEnvironment *genEnv = nullptr; GenericEnvironment *genEnv = getSubstGenericEnvironment(origSILFunctionType);
if (!pass.Mapper.shouldTransformResults(genEnv, origSILFunctionType, if (!pass.Mapper.shouldTransformResults(genEnv, origSILFunctionType,
pass.Mod)) { pass.Mod)) {
continue; continue;
} }
auto resultStorageType = origSILFunctionType->getAllResultsInterfaceType(); auto resultStorageType = origSILFunctionType->getAllResultsInterfaceType();
if (!pass.isLargeLoadableType(resultStorageType)) { if (!pass.isLargeLoadableType(origSILFunctionType, resultStorageType)) {
// Make sure it contains a function type // Make sure it contains a function type
auto numFuncTy = llvm::count_if(origSILFunctionType->getResults(), auto numFuncTy = llvm::count_if(origSILFunctionType->getResults(),
[](const SILResultInfo &origResult) { [](const SILResultInfo &origResult) {
@@ -1474,7 +1506,8 @@ void LoadableStorageAllocation::convertApplyResults() {
(void)numFuncTy; (void)numFuncTy;
continue; continue;
} }
auto newSILType = pass.getNewSILType(resultStorageType); auto newSILType = pass.getNewSILType(origSILFunctionType,
resultStorageType);
auto *newVal = allocateForApply(currIns, newSILType.getObjectType()); auto *newVal = allocateForApply(currIns, newSILType.getObjectType());
if (auto apply = dyn_cast<ApplyInst>(currIns)) { if (auto apply = dyn_cast<ApplyInst>(currIns)) {
apply->replaceAllUsesWith(newVal); apply->replaceAllUsesWith(newVal);
@@ -1501,8 +1534,10 @@ void LoadableStorageAllocation::
for (SILArgument *arg : entry->getArguments()) { for (SILArgument *arg : entry->getArguments()) {
SILType storageType = arg->getType(); SILType storageType = arg->getType();
SILType newSILType = pass.getNewSILType(storageType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
if (pass.containsDifferentFunctionSignature(storageType)) { storageType);
if (pass.containsDifferentFunctionSignature(pass.F->getLoweredFunctionType(),
storageType)) {
auto *castInstr = argBuilder.createUncheckedBitCast( auto *castInstr = argBuilder.createUncheckedBitCast(
RegularLocation(const_cast<ValueDecl *>(arg->getDecl())), arg, RegularLocation(const_cast<ValueDecl *>(arg->getDecl())), arg,
newSILType); newSILType);
@@ -1525,7 +1560,8 @@ void LoadableStorageAllocation::convertIndirectBasicBlockArgs() {
continue; continue;
} }
SILType storageType = arg->getType(); SILType storageType = arg->getType();
SILType newSILType = pass.getNewSILType(storageType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
storageType);
// We don't change the type from object to address for function args: // We don't change the type from object to address for function args:
// a tuple with both a large type and a function arg should remain // a tuple with both a large type and a function arg should remain
// as an object type for now // as an object type for now
@@ -1784,7 +1820,8 @@ static bool allUsesAreReplaceable(StructLoweringState &pass,
return false; return false;
} }
SILType currType = instr->getType().getObjectType(); SILType currType = instr->getType().getObjectType();
SILType newSILType = pass.getNewSILType(currType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currType);
if (currType == newSILType) { if (currType == newSILType) {
return false; return false;
} }
@@ -1838,7 +1875,8 @@ static void allocateAndSetAll(StructLoweringState &pass,
for (Operand &operand : operands) { for (Operand &operand : operands) {
SILValue value = operand.get(); SILValue value = operand.get();
SILType silType = value->getType(); SILType silType = value->getType();
if (pass.isLargeLoadableType(silType)) { if (pass.isLargeLoadableType(pass.F->getLoweredFunctionType(),
silType)) {
allocateAndSet(pass, allocator, value, user); allocateAndSet(pass, allocator, value, user);
} }
} }
@@ -1849,9 +1887,9 @@ static void castTupleInstr(SingleValueInstruction *instr, IRGenModule &Mod,
SILType currSILType = instr->getType(); SILType currSILType = instr->getType();
auto funcType = getInnerFunctionType(currSILType); auto funcType = getInnerFunctionType(currSILType);
assert(funcType && "Expected a function Type"); assert(funcType && "Expected a function Type");
GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(instr->getFunction());
if (!genEnv && funcType->getSubstGenericSignature()) { if (!genEnv && funcType->getSubstGenericSignature()) {
genEnv = getGenericEnvironment(funcType); genEnv = getSubstGenericEnvironment(funcType);
} }
SILType newSILType = Mapper.getNewSILType(genEnv, currSILType, Mod); SILType newSILType = Mapper.getNewSILType(genEnv, currSILType, Mod);
if (currSILType == newSILType) { if (currSILType == newSILType) {
@@ -1960,7 +1998,8 @@ static void rewriteFunction(StructLoweringState &pass,
EnumElementDecl *decl = currCase.first; EnumElementDecl *decl = currCase.first;
for (SILArgument *arg : currBB->getArguments()) { for (SILArgument *arg : currBB->getArguments()) {
SILType storageType = arg->getType(); SILType storageType = arg->getType();
SILType newSILType = pass.getNewSILType(storageType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
storageType);
if (storageType == newSILType) { if (storageType == newSILType) {
newSILType = newSILType.getAddressType(); newSILType = newSILType.getAddressType();
} }
@@ -2041,7 +2080,8 @@ static void rewriteFunction(StructLoweringState &pass,
auto *instr = pass.allocStackInstsToMod.pop_back_val(); auto *instr = pass.allocStackInstsToMod.pop_back_val();
SILBuilderWithScope allocBuilder(instr); SILBuilderWithScope allocBuilder(instr);
SILType currSILType = instr->getType(); SILType currSILType = instr->getType();
SILType newSILType = pass.getNewSILType(currSILType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currSILType);
auto *newInstr = allocBuilder.createAllocStack(instr->getLoc(), newSILType, auto *newInstr = allocBuilder.createAllocStack(instr->getLoc(), newSILType,
instr->getVarInfo()); instr->getVarInfo());
instr->replaceAllUsesWith(newInstr); instr->replaceAllUsesWith(newInstr);
@@ -2052,7 +2092,8 @@ static void rewriteFunction(StructLoweringState &pass,
auto *instr = pass.pointerToAddrkInstsToMod.pop_back_val(); auto *instr = pass.pointerToAddrkInstsToMod.pop_back_val();
SILBuilderWithScope pointerBuilder(instr); SILBuilderWithScope pointerBuilder(instr);
SILType currSILType = instr->getType(); SILType currSILType = instr->getType();
SILType newSILType = pass.getNewSILType(currSILType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currSILType);
auto *newInstr = pointerBuilder.createPointerToAddress( auto *newInstr = pointerBuilder.createPointerToAddress(
instr->getLoc(), instr->getOperand(), newSILType.getAddressType(), instr->getLoc(), instr->getOperand(), newSILType.getAddressType(),
instr->isStrict()); instr->isStrict());
@@ -2128,7 +2169,8 @@ static void rewriteFunction(StructLoweringState &pass,
// Update the return type of these instrs // Update the return type of these instrs
// Note: The operand was already updated! // Note: The operand was already updated!
SILType currSILType = instr->getType().getObjectType(); SILType currSILType = instr->getType().getObjectType();
SILType newSILType = pass.getNewSILType(currSILType); SILType newSILType = pass.getNewSILType(pass.F->getLoweredFunctionType(),
currSILType);
SILBuilderWithScope resultTyBuilder(instr); SILBuilderWithScope resultTyBuilder(instr);
SILLocation Loc = instr->getLoc(); SILLocation Loc = instr->getLoc();
SingleValueInstruction *newInstr = nullptr; SingleValueInstruction *newInstr = nullptr;
@@ -2195,7 +2237,7 @@ static void rewriteFunction(StructLoweringState &pass,
auto currSILFunctionType = currSILType.castTo<SILFunctionType>(); auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
GenericEnvironment *genEnvForMethod = nullptr; GenericEnvironment *genEnvForMethod = nullptr;
if (currSILFunctionType->isPolymorphic()) { if (currSILFunctionType->isPolymorphic()) {
genEnvForMethod = getGenericEnvironment(currSILFunctionType); genEnvForMethod = getSubstGenericEnvironment(currSILFunctionType);
} }
SILType newSILType = SILType newSILType =
SILType::getPrimitiveObjectType(pass.Mapper.getNewSILFunctionType( SILType::getPrimitiveObjectType(pass.Mapper.getNewSILFunctionType(
@@ -2285,11 +2327,11 @@ static bool rewriteFunctionReturn(StructLoweringState &pass) {
auto loweredTy = pass.F->getLoweredFunctionType(); auto loweredTy = pass.F->getLoweredFunctionType();
SILFunction *F = pass.F; SILFunction *F = pass.F;
SILType resultTy = loweredTy->getAllResultsInterfaceType(); SILType resultTy = loweredTy->getAllResultsInterfaceType();
SILType newSILType = pass.getNewSILType(resultTy); SILType newSILType = pass.getNewSILType(loweredTy, resultTy);
// We (currently) only care about function signatures // We (currently) only care about function signatures
if (pass.isLargeLoadableType(resultTy)) { if (pass.isLargeLoadableType(loweredTy, resultTy)) {
return true; return true;
} else if (pass.containsDifferentFunctionSignature(resultTy)) { } else if (pass.containsDifferentFunctionSignature(loweredTy, resultTy)) {
llvm::SmallVector<SILResultInfo, 2> newSILResultInfo; llvm::SmallVector<SILResultInfo, 2> newSILResultInfo;
if (auto tupleType = newSILType.getAs<TupleType>()) { if (auto tupleType = newSILType.getAs<TupleType>()) {
auto originalResults = loweredTy->getResults(); auto originalResults = loweredTy->getResults();
@@ -2333,10 +2375,10 @@ void LoadableByAddress::runOnFunction(SILFunction *F) {
return; return;
} }
// External function - re-write external declaration - this is ABI! // External function - re-write external declaration - this is ABI!
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto loweredTy = F->getLoweredFunctionType(); auto loweredTy = F->getLoweredFunctionType();
if (!genEnv && loweredTy->getSubstGenericSignature()) { if (!genEnv && loweredTy->getSubstGenericSignature()) {
genEnv = getGenericEnvironment(loweredTy); genEnv = getSubstGenericEnvironment(loweredTy);
} }
if (MapperCache.shouldTransformFunctionType(genEnv, loweredTy, if (MapperCache.shouldTransformFunctionType(genEnv, loweredTy,
*currIRMod)) { *currIRMod)) {
@@ -2394,9 +2436,9 @@ getOperandTypeWithCastIfNecessary(SILInstruction *containingInstr, SILValue op,
} }
if (auto funcType = nonOptionalType.getAs<SILFunctionType>()) { if (auto funcType = nonOptionalType.getAs<SILFunctionType>()) {
GenericEnvironment *genEnv = GenericEnvironment *genEnv =
containingInstr->getFunction()->getGenericEnvironment(); getSubstGenericEnvironment(containingInstr->getFunction());
if (!genEnv && funcType->isPolymorphic()) { if (!genEnv && funcType->isPolymorphic()) {
genEnv = getGenericEnvironment(funcType); genEnv = getSubstGenericEnvironment(funcType);
} }
auto newFnType = Mapper.getNewSILFunctionType(genEnv, funcType, Mod); auto newFnType = Mapper.getNewSILFunctionType(genEnv, funcType, Mod);
SILType newSILType = SILType::getPrimitiveObjectType(newFnType); SILType newSILType = SILType::getPrimitiveObjectType(newFnType);
@@ -2444,7 +2486,7 @@ void LoadableByAddress::recreateSingleApply(
} }
} }
CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType(); CanSILFunctionType origSILFunctionType = applySite.getSubstCalleeType();
GenericEnvironment *genEnv = nullptr; GenericEnvironment *genEnv = getSubstGenericEnvironment(origSILFunctionType);
CanSILFunctionType newSILFunctionType = MapperCache.getNewSILFunctionType( CanSILFunctionType newSILFunctionType = MapperCache.getNewSILFunctionType(
genEnv, origSILFunctionType, *currIRMod); genEnv, origSILFunctionType, *currIRMod);
SILFunctionConventions newSILFunctionConventions(newSILFunctionType, SILFunctionConventions newSILFunctionConventions(newSILFunctionType,
@@ -2589,7 +2631,7 @@ bool LoadableByAddress::recreateUncheckedEnumDataInstr(
SILFunction *F = enumInstr->getFunction(); SILFunction *F = enumInstr->getFunction();
IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F); IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
SILType origType = enumInstr->getType(); SILType origType = enumInstr->getType();
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod); SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod);
auto caseTy = enumInstr->getOperand()->getType().getEnumElementType( auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
enumInstr->getElement(), F->getModule(), TypeExpansionContext(*F)); enumInstr->getElement(), F->getModule(), TypeExpansionContext(*F));
@@ -2622,7 +2664,7 @@ bool LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst(
SILFunction *F = enumInstr->getFunction(); SILFunction *F = enumInstr->getFunction();
IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F); IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
SILType origType = enumInstr->getType(); SILType origType = enumInstr->getType();
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod); SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod);
auto caseTy = enumInstr->getOperand()->getType().getEnumElementType( auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
enumInstr->getElement(), F->getModule(), TypeExpansionContext(*F)); enumInstr->getElement(), F->getModule(), TypeExpansionContext(*F));
@@ -2672,7 +2714,7 @@ bool LoadableByAddress::recreateTupleInstr(
// Check if we need to recreate the tuple: // Check if we need to recreate the tuple:
auto *F = tupleInstr->getFunction(); auto *F = tupleInstr->getFunction();
auto *currIRMod = getIRGenModule()->IRGen.getGenModule(F); auto *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto resultTy = tupleInstr->getType(); auto resultTy = tupleInstr->getType();
auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod); auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod);
if (resultTy == newResultTy) if (resultTy == newResultTy)
@@ -2704,7 +2746,7 @@ bool LoadableByAddress::recreateConvInstr(SILInstruction &I,
} }
auto currSILFunctionType = currSILType.castTo<SILFunctionType>(); auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
GenericEnvironment *genEnv = GenericEnvironment *genEnv =
convInstr->getFunction()->getGenericEnvironment(); getSubstGenericEnvironment(convInstr->getFunction());
CanSILFunctionType newFnType = MapperCache.getNewSILFunctionType( CanSILFunctionType newFnType = MapperCache.getNewSILFunctionType(
genEnv, currSILFunctionType, *currIRMod); genEnv, currSILFunctionType, *currIRMod);
SILType newType = SILType::getPrimitiveObjectType(newFnType); SILType newType = SILType::getPrimitiveObjectType(newFnType);
@@ -2761,7 +2803,7 @@ bool LoadableByAddress::recreateBuiltinInstr(SILInstruction &I,
auto *currIRMod = auto *currIRMod =
getIRGenModule()->IRGen.getGenModule(builtinInstr->getFunction()); getIRGenModule()->IRGen.getGenModule(builtinInstr->getFunction());
auto *F = builtinInstr->getFunction(); auto *F = builtinInstr->getFunction();
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
auto resultTy = builtinInstr->getType(); auto resultTy = builtinInstr->getType();
auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod); auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod);
@@ -2782,9 +2824,9 @@ bool LoadableByAddress::recreateBuiltinInstr(SILInstruction &I,
void LoadableByAddress::updateLoweredTypes(SILFunction *F) { void LoadableByAddress::updateLoweredTypes(SILFunction *F) {
IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F); IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
CanSILFunctionType funcType = F->getLoweredFunctionType(); CanSILFunctionType funcType = F->getLoweredFunctionType();
GenericEnvironment *genEnv = F->getGenericEnvironment(); GenericEnvironment *genEnv = getSubstGenericEnvironment(F);
if (!genEnv && funcType->getSubstGenericSignature()) { if (!genEnv && funcType->getSubstGenericSignature()) {
genEnv = getGenericEnvironment(funcType); genEnv = getSubstGenericEnvironment(funcType);
} }
auto newFuncTy = auto newFuncTy =
MapperCache.getNewSILFunctionType(genEnv, funcType, *currIRMod); MapperCache.getNewSILFunctionType(genEnv, funcType, *currIRMod);