[embedded] Perform VTable specialization iteratively as part of MandatoryPerformanceOptimizations

This commit is contained in:
Kuba Mracek
2023-09-18 22:15:24 -07:00
parent fca24bd5c8
commit 03f927eca1
7 changed files with 155 additions and 26 deletions

View File

@@ -38,10 +38,6 @@ namespace {
class VTableSpecializer : public SILModuleTransform {
bool specializeVTables(SILModule &module);
bool specializeVTableFor(SILType classTy, SILModule &module);
SILFunction *specializeVTableMethod(SILFunction *origMethod,
SubstitutionMap subs, SILModule &module);
bool specializeClassMethodInst(ClassMethodInst *cm);
/// The entry point to the transformation.
void run() override {
@@ -57,23 +53,39 @@ class VTableSpecializer : public SILModuleTransform {
} // end anonymous namespace
static bool specializeVTableFor(SILType classTy, SILModule &module,
SILTransform *transform);
static SILFunction *specializeVTableMethod(SILFunction *origMethod,
SubstitutionMap subs,
SILModule &module,
SILTransform *transform);
static bool specializeClassMethodInst(ClassMethodInst *cm);
static bool specializeVTablesInFunction(SILFunction &func, SILModule &module,
SILTransform *transform) {
bool changed = false;
if (func.getLoweredFunctionType()->isPolymorphic()) return changed;
for (SILBasicBlock &block : func) {
for (SILInstruction &inst : block) {
if (auto *allocRef = dyn_cast<AllocRefInst>(&inst)) {
changed |= specializeVTableFor(allocRef->getType(), module, transform);
} else if (auto *metatype = dyn_cast<MetatypeInst>(&inst)) {
changed |= specializeVTableFor(
metatype->getType().getInstanceTypeOfMetatype(&func), module, transform);
} else if (auto *cm = dyn_cast<ClassMethodInst>(&inst)) {
changed |= specializeClassMethodInst(cm);
}
}
}
return changed;
}
bool VTableSpecializer::specializeVTables(SILModule &module) {
bool changed = false;
for (SILFunction &func : module) {
if (func.getLoweredFunctionType()->isPolymorphic()) continue;
for (SILBasicBlock &block : func) {
for (SILInstruction &inst : block) {
if (auto *allocRef = dyn_cast<AllocRefInst>(&inst)) {
changed |= specializeVTableFor(allocRef->getType(), module);
} else if (auto *metatype = dyn_cast<MetatypeInst>(&inst)) {
changed |= specializeVTableFor(
metatype->getType().getInstanceTypeOfMetatype(&func), module);
} else if (auto *cm = dyn_cast<ClassMethodInst>(&inst)) {
changed |= specializeClassMethodInst(cm);
}
}
}
specializeVTablesInFunction(func, module, this);
}
for (SILVTable *vtable : module.getVTables()) {
@@ -92,8 +104,8 @@ bool VTableSpecializer::specializeVTables(SILModule &module) {
return changed;
}
bool VTableSpecializer::specializeVTableFor(SILType classTy,
SILModule &module) {
static bool specializeVTableFor(SILType classTy, SILModule &module,
SILTransform *transform) {
CanType astType = classTy.getASTType();
BoundGenericClassType *genClassTy = dyn_cast<BoundGenericClassType>(astType);
if (!genClassTy) return false;
@@ -120,7 +132,7 @@ bool VTableSpecializer::specializeVTableFor(SILType classTy,
for (const SILVTableEntry &entry : origVtable->getEntries()) {
SILFunction *origMethod = entry.getImplementation();
SILFunction *specializedMethod =
specializeVTableMethod(origMethod, subs, module);
specializeVTableMethod(origMethod, subs, module, transform);
newEntries.push_back(SILVTableEntry(entry.getMethod(), specializedMethod,
entry.getKind(),
entry.isNonOverridden()));
@@ -130,9 +142,10 @@ bool VTableSpecializer::specializeVTableFor(SILType classTy,
return true;
}
SILFunction *VTableSpecializer::specializeVTableMethod(SILFunction *origMethod,
SubstitutionMap subs,
SILModule &module) {
static SILFunction *specializeVTableMethod(SILFunction *origMethod,
SubstitutionMap subs,
SILModule &module,
SILTransform *transform) {
LLVM_DEBUG(llvm::errs() << "specializeVTableMethod " << origMethod->getName()
<< '\n');
@@ -149,7 +162,7 @@ SILFunction *VTableSpecializer::specializeVTableMethod(SILFunction *origMethod,
llvm::report_fatal_error("cannot specialize vtable method");
}
SILOptFunctionBuilder FunctionBuilder(*this);
SILOptFunctionBuilder FunctionBuilder(*transform);
GenericFuncSpecializer FuncSpecializer(FunctionBuilder, origMethod, subs,
ReInfo, /*isMandatory=*/true);
@@ -172,7 +185,7 @@ SILFunction *VTableSpecializer::specializeVTableMethod(SILFunction *origMethod,
return SpecializedF;
}
bool VTableSpecializer::specializeClassMethodInst(ClassMethodInst *cm) {
static bool specializeClassMethodInst(ClassMethodInst *cm) {
SILValue instance = cm->getOperand();
SILType classTy = instance->getType();
CanType astType = classTy.getASTType();
@@ -217,6 +230,12 @@ bool VTableSpecializer::specializeClassMethodInst(ClassMethodInst *cm) {
return true;
}
bool swift::specializeVTables(SILFunction *fn, SILTransform *transform) {
if (!fn->getModule.getASTContext().LangOpts.hasFeature(Feature::Embedded))
return false;
return specializeVTablesInFunction(*fn, fn->getModule(), transform);
}
SILTransform *swift::createVTableSpecializer() {
return new VTableSpecializer();
}