Skip to content

Commit 8597eca

Browse files
authored
Merge pull request #65504 from eeckstein/fix-loadablebyaddress-5.9
[5.9] LoadableByAddress: convert types of functions which are contained in structs inside global static initializers
2 parents 50148ce + 2576d7d commit 8597eca

File tree

2 files changed

+75
-57
lines changed

2 files changed

+75
-57
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/SIL/DebugUtils.h"
2727
#include "swift/SIL/SILArgument.h"
2828
#include "swift/SIL/SILBuilder.h"
29+
#include "swift/SIL/SILCloner.h"
2930
#include "swift/SIL/SILUndef.h"
3031
#include "swift/SILOptimizer/PassManager/Transforms.h"
3132
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
@@ -1713,6 +1714,8 @@ class LoadableByAddress : public SILModuleTransform {
17131714

17141715
bool shouldTransformGlobal(SILGlobalVariable *global);
17151716

1717+
bool shouldTransformInitExprOfGlobal(SILGlobalVariable *global);
1718+
17161719
private:
17171720
llvm::SetVector<SILFunction *> modFuncs;
17181721
llvm::SetVector<SingleValueInstruction *> conversionInstrs;
@@ -1724,6 +1727,8 @@ class LoadableByAddress : public SILModuleTransform {
17241727
llvm::SetVector<StoreInst *> storeToBlockStorageInstrs;
17251728
llvm::SetVector<SILInstruction *> modApplies;
17261729
llvm::MapVector<SILInstruction *, SILValue> allApplyRetToAllocMap;
1730+
1731+
public:
17271732
LargeSILTypeMapper MapperCache;
17281733
};
17291734
} // end anonymous namespace
@@ -2940,6 +2945,42 @@ bool LoadableByAddress::shouldTransformGlobal(SILGlobalVariable *global) {
29402945
return false;
29412946
}
29422947

2948+
bool LoadableByAddress::shouldTransformInitExprOfGlobal(SILGlobalVariable *global) {
2949+
for (const SILInstruction &initInst : *global) {
2950+
if (auto *fri = dyn_cast<FunctionRefBaseInst>(&initInst)) {
2951+
SILFunction *refF = fri->getInitiallyReferencedFunction();
2952+
if (modFuncs.count(refF) != 0)
2953+
return true;
2954+
}
2955+
}
2956+
return false;
2957+
}
2958+
2959+
namespace {
2960+
class GlobalInitCloner : public SILCloner<GlobalInitCloner> {
2961+
LoadableByAddress *pass;
2962+
IRGenModule *irgenModule;
2963+
public:
2964+
GlobalInitCloner(SILGlobalVariable *global, LoadableByAddress *pass,
2965+
IRGenModule *irgenModule)
2966+
: SILCloner<GlobalInitCloner>(global), pass(pass), irgenModule(irgenModule) {
2967+
}
2968+
2969+
SILType remapType(SILType ty) {
2970+
if (auto fnType = ty.getAs<SILFunctionType>()) {
2971+
GenericEnvironment *genEnv = getSubstGenericEnvironment(fnType);
2972+
return SILType::getPrimitiveObjectType(
2973+
pass->MapperCache.getNewSILFunctionType(genEnv, fnType, *irgenModule));
2974+
}
2975+
return ty;
2976+
}
2977+
2978+
void clone(SILInstruction *inst) {
2979+
visit(inst);
2980+
}
2981+
};
2982+
}
2983+
29432984
/// The entry point to this function transformation.
29442985
void LoadableByAddress::run() {
29452986
// Set the SIL state before the PassManager has a chance to run
@@ -3078,72 +3119,34 @@ void LoadableByAddress::run() {
30783119
updateLoweredTypes(F);
30793120
}
30803121

3081-
auto computeNewResultType = [&](SILType ty, IRGenModule *mod) -> SILType {
3082-
auto currSILFunctionType = ty.castTo<SILFunctionType>();
3083-
GenericEnvironment *genEnv =
3084-
getSubstGenericEnvironment(currSILFunctionType);
3085-
return SILType::getPrimitiveObjectType(
3086-
MapperCache.getNewSILFunctionType(genEnv, currSILFunctionType, *mod));
3087-
};
3088-
30893122
// Update globals' initializer.
30903123
SmallVector<SILGlobalVariable *, 16> deadGlobals;
30913124
for (SILGlobalVariable &global : getModule()->getSILGlobals()) {
3092-
SILInstruction *init = global.getStaticInitializerValue();
3093-
if (!init)
3094-
continue;
3095-
auto silTy = global.getLoweredType();
3096-
if (!isa<SILFunctionType>(silTy.getASTType()))
3097-
continue;
3098-
auto *decl = global.getDecl();
3099-
IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(
3100-
decl ? decl->getDeclContext() : nullptr);
3101-
auto silFnTy = global.getLoweredFunctionType();
3102-
GenericEnvironment *genEnv = getSubstGenericEnvironment(silFnTy);
3103-
3104-
// Update the global's type.
3105-
if (MapperCache.shouldTransformFunctionType(genEnv, silFnTy, *currIRMod)) {
3106-
auto newSILFnType =
3107-
MapperCache.getNewSILFunctionType(genEnv, silFnTy, *currIRMod);
3108-
global.unsafeSetLoweredType(
3109-
SILType::getPrimitiveObjectType(newSILFnType));
3125+
if (shouldTransformInitExprOfGlobal(&global)) {
3126+
auto *decl = global.getDecl();
3127+
IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(
3128+
decl ? decl->getDeclContext() : nullptr);
3129+
3130+
auto silTy = global.getLoweredType();
3131+
if (isa<SILFunctionType>(silTy.getASTType())) {
3132+
auto silFnTy = global.getLoweredFunctionType();
3133+
GenericEnvironment *genEnv = getSubstGenericEnvironment(silFnTy);
3134+
if (MapperCache.shouldTransformFunctionType(genEnv, silFnTy, *currIRMod)) {
3135+
auto newSILFnType =
3136+
MapperCache.getNewSILFunctionType(genEnv, silFnTy, *currIRMod);
3137+
global.unsafeSetLoweredType(SILType::getPrimitiveObjectType(newSILFnType));
3138+
}
3139+
}
31103140

31113141
// Rewrite the init basic block...
31123142
SmallVector<SILInstruction *, 8> initBlockInsts;
31133143
for (auto it = global.begin(), end = global.end(); it != end; ++it) {
31143144
initBlockInsts.push_back(const_cast<SILInstruction *>(&*it));
31153145
}
3146+
GlobalInitCloner cloner(&global, this, currIRMod);
31163147
for (auto *oldInst : initBlockInsts) {
3117-
if (auto *f = dyn_cast<FunctionRefInst>(oldInst)) {
3118-
SILBuilder builder(&global);
3119-
auto *newInst = builder.createFunctionRef(
3120-
f->getLoc(), f->getInitiallyReferencedFunction(), f->getKind());
3121-
f->replaceAllUsesWith(newInst);
3122-
global.unsafeRemove(f, *getModule());
3123-
} else if (auto *cvt = dyn_cast<ConvertFunctionInst>(oldInst)) {
3124-
auto newType = computeNewResultType(cvt->getType(), currIRMod);
3125-
SILBuilder builder(&global);
3126-
auto *newInst = builder.createConvertFunction(
3127-
cvt->getLoc(), cvt->getOperand(), newType,
3128-
cvt->withoutActuallyEscaping());
3129-
cvt->replaceAllUsesWith(newInst);
3130-
global.unsafeRemove(cvt, *getModule());
3131-
} else if (auto *thinToThick =
3132-
dyn_cast<ThinToThickFunctionInst>(oldInst)) {
3133-
auto newType =
3134-
computeNewResultType(thinToThick->getType(), currIRMod);
3135-
SILBuilder builder(&global);
3136-
auto *newInstr = builder.createThinToThickFunction(
3137-
thinToThick->getLoc(), thinToThick->getOperand(), newType);
3138-
thinToThick->replaceAllUsesWith(newInstr);
3139-
global.unsafeRemove(thinToThick, *getModule());
3140-
} else {
3141-
auto *sv = cast<SingleValueInstruction>(oldInst);
3142-
auto *newInst = cast<SingleValueInstruction>(oldInst->clone());
3143-
global.unsafeAppend(newInst);
3144-
sv->replaceAllUsesWith(newInst);
3145-
global.unsafeRemove(oldInst, *getModule());
3146-
}
3148+
cloner.clone(oldInst);
3149+
global.unsafeRemove(oldInst, *getModule());
31473150
}
31483151
}
31493152
}

test/IRGen/big_types_coroutine.sil renamed to test/IRGen/big_types.sil

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-sil-opt -loadable-address -enable-sil-verify-all %s | %FileCheck %s
22

3-
// REQUIRES: CPU=x86_64
3+
// REQUIRES: PTRSIZE=64
44
// REQUIRES: OS=macosx
55

66
sil_stage canonical
@@ -19,9 +19,24 @@ public struct BigStruct {
1919
var i8 : Int32 = 8
2020
}
2121

22+
public struct ContainsClosure {
23+
let c: () -> BigStruct
24+
}
25+
2226
sil @make_big_struct : $@convention(thin) () -> BigStruct
2327
sil @use_big_struct : $@convention(thin) (BigStruct) -> ()
2428

29+
// CHECK-LABEL: sil_global @globalWithClosureInStruct : $ContainsClosure = {
30+
// CHECK: %0 = function_ref @make_big_struct : $@convention(thin) () -> @out BigStruct
31+
// CHECK-NEXT: %1 = thin_to_thick_function %0 : $@convention(thin) () -> @out BigStruct to $@callee_guaranteed () -> @out BigStruct
32+
// CHECK-NEXT: %initval = struct $ContainsClosure (%1 : $@callee_guaranteed () -> @out BigStruct)
33+
// CHECK-NEXT: }
34+
sil_global @globalWithClosureInStruct : $ContainsClosure = {
35+
%0 = function_ref @make_big_struct : $@convention(thin) () -> BigStruct
36+
%1 = thin_to_thick_function %0 : $@convention(thin) () -> BigStruct to $@callee_guaranteed () -> BigStruct
37+
%initval = struct $ContainsClosure (%1 : $@callee_guaranteed () -> BigStruct)
38+
}
39+
2540
// CHECK-LABEL: sil @test_yield_big : $@yield_once @convention(thin) () -> @yields @in BigStruct {
2641
// CHECK: bb0:
2742
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $BigStruct

0 commit comments

Comments
 (0)