forked from OSchip/llvm-project
[mlir][Interfaces] Generate a struct containing function pointers instead of a class with vtables
When compiling for code size, the use of a vtable causes a destructor(and constructor in certain cases) to be generated for the class. Interface models don't need a complex constructor or a destructor, so this can lead to many megabytes of code size increase(even in opt). This revision switches to a simpler struct of function pointers approach that accomplishes the same API requirements as before. This change requires no updates to user code, or any other code aside from the generator, as the user facing API is still exactly the same. Differential Revision: https://reviews.llvm.org/D90085
This commit is contained in:
parent
d989ae9069
commit
ef728eaf6e
|
@ -189,17 +189,19 @@ bool InterfaceGenerator::emitInterfaceDefs() {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void InterfaceGenerator::emitConceptDecl(Interface &interface) {
|
||||
os << " class Concept {\n"
|
||||
<< " public:\n"
|
||||
<< " virtual ~Concept() = default;\n";
|
||||
os << " struct Concept {\n";
|
||||
|
||||
// Insert each of the pure virtual concept methods.
|
||||
for (auto &method : interface.getMethods()) {
|
||||
os << " virtual ";
|
||||
os << " ";
|
||||
emitCPPType(method.getReturnType(), os);
|
||||
emitMethodNameAndArgs(method, os, valueType,
|
||||
/*addThisArg=*/!method.isStatic(), /*addConst=*/true);
|
||||
os << " = 0;\n";
|
||||
os << "(*" << method.getName() << ")(";
|
||||
if (!method.isStatic())
|
||||
emitCPPType(valueType, os) << (method.arg_empty() ? "" : ", ");
|
||||
llvm::interleaveComma(
|
||||
method.getArguments(), os,
|
||||
[&](const InterfaceMethod::Argument &arg) { os << arg.type; });
|
||||
os << ");\n";
|
||||
}
|
||||
os << " };\n";
|
||||
}
|
||||
|
@ -207,13 +209,19 @@ void InterfaceGenerator::emitConceptDecl(Interface &interface) {
|
|||
void InterfaceGenerator::emitModelDecl(Interface &interface) {
|
||||
os << " template<typename " << valueTemplate << ">\n";
|
||||
os << " class Model : public Concept {\n public:\n";
|
||||
os << " Model() : Concept{";
|
||||
llvm::interleaveComma(
|
||||
interface.getMethods(), os,
|
||||
[&](const InterfaceMethod &method) { os << method.getName(); });
|
||||
os << "} {}\n\n";
|
||||
|
||||
// Insert each of the virtual method overrides.
|
||||
for (auto &method : interface.getMethods()) {
|
||||
emitCPPType(method.getReturnType(), os << " ");
|
||||
emitCPPType(method.getReturnType(), os << " static ");
|
||||
emitMethodNameAndArgs(method, os, valueType,
|
||||
/*addThisArg=*/!method.isStatic(), /*addConst=*/true);
|
||||
os << " final {\n ";
|
||||
/*addThisArg=*/!method.isStatic(),
|
||||
/*addConst=*/false);
|
||||
os << " {\n ";
|
||||
|
||||
// Check for a provided body to the function.
|
||||
if (Optional<StringRef> body = method.getBody()) {
|
||||
|
|
Loading…
Reference in New Issue