26
26
#include " swift/SIL/DebugUtils.h"
27
27
#include " swift/SIL/SILArgument.h"
28
28
#include " swift/SIL/SILBuilder.h"
29
+ #include " swift/SIL/SILCloner.h"
29
30
#include " swift/SIL/SILUndef.h"
30
31
#include " swift/SILOptimizer/PassManager/Transforms.h"
31
32
#include " swift/SILOptimizer/Utils/InstOptUtils.h"
@@ -1713,6 +1714,8 @@ class LoadableByAddress : public SILModuleTransform {
1713
1714
1714
1715
bool shouldTransformGlobal (SILGlobalVariable *global);
1715
1716
1717
+ bool shouldTransformInitExprOfGlobal (SILGlobalVariable *global);
1718
+
1716
1719
private:
1717
1720
llvm::SetVector<SILFunction *> modFuncs;
1718
1721
llvm::SetVector<SingleValueInstruction *> conversionInstrs;
@@ -1724,6 +1727,8 @@ class LoadableByAddress : public SILModuleTransform {
1724
1727
llvm::SetVector<StoreInst *> storeToBlockStorageInstrs;
1725
1728
llvm::SetVector<SILInstruction *> modApplies;
1726
1729
llvm::MapVector<SILInstruction *, SILValue> allApplyRetToAllocMap;
1730
+
1731
+ public:
1727
1732
LargeSILTypeMapper MapperCache;
1728
1733
};
1729
1734
} // end anonymous namespace
@@ -2940,6 +2945,42 @@ bool LoadableByAddress::shouldTransformGlobal(SILGlobalVariable *global) {
2940
2945
return false ;
2941
2946
}
2942
2947
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
+
2943
2984
// / The entry point to this function transformation.
2944
2985
void LoadableByAddress::run () {
2945
2986
// Set the SIL state before the PassManager has a chance to run
@@ -3078,72 +3119,34 @@ void LoadableByAddress::run() {
3078
3119
updateLoweredTypes (F);
3079
3120
}
3080
3121
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
-
3089
3122
// Update globals' initializer.
3090
3123
SmallVector<SILGlobalVariable *, 16 > deadGlobals;
3091
3124
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
+ }
3110
3140
3111
3141
// Rewrite the init basic block...
3112
3142
SmallVector<SILInstruction *, 8 > initBlockInsts;
3113
3143
for (auto it = global.begin (), end = global.end (); it != end; ++it) {
3114
3144
initBlockInsts.push_back (const_cast <SILInstruction *>(&*it));
3115
3145
}
3146
+ GlobalInitCloner cloner (&global, this , currIRMod);
3116
3147
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 ());
3147
3150
}
3148
3151
}
3149
3152
}
0 commit comments