mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[embedded] Perform VTable specialization iteratively as part of MandatoryPerformanceOptimizations
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user