r/Compilers • u/General_Purple3060 • 21h ago
Can better language semantics simplify compilers?
While implementing the OO part of my language (AET), I ran into a performance problem: OO method calls have overhead. So I started looking into devirtualization.
At first, I treated it as a compiler problem: how can the compiler determine that a method call has only one possible target?
But then I started thinking from a different angle: what if the language itself could tell the compiler that the target is unique?
This made me realize that the relationship between language semantics and compiler shouldn't be one-directional. They should influence each other during the design phase:
Language Semantics ↔ Compiler ↔ Optimization
For example, AET has:
private$ foo();
final$ foo();
final$ class A { ... };
These are language semantics that restrict inheritance and overriding. But they also provide the compiler with clear semantic guarantees: the call target is unique.
A final$ method cannot be overridden by subclasses.
A final$ class has no subclasses that could override the method.
A private$ method does not participate in overriding at all.
Different language rules, but from the compiler's perspective, they all provide the same useful fact: the call target is unique. So AET can use this semantic information to transform an OO call into a direct call to the corresponding FUNCTION_DECL in GCC's intermediate representation.
Of course, a compiler could also discover the same information through type analysis, call graph analysis, devirtualization, LTO, etc. But if these facts can be determined directly by language semantics, could it in turn make the compiler simpler?
This led me to a more general question. Essentially, it's a "who does more, who does less" problem. If language semantics provide more explicit guarantees, the compiler may need to do less inference. If the language keeps weaker semantic constraints, more work falls on compiler analysis.
So the question becomes: what should be left to language semantics, and what should be left to compiler analysis? Are there any methods or theories to guide this division of labor, to make it more scientific and reasonable?
I think this is also a boundary worth discussing between language design and compiler design. AET is my exploration of this question while actually implementing it.
Would love to hear your thoughts.
2
u/Repulsive_Gate8657 21h ago edited 21h ago
you talk about language SYNTAX.
it depends mostly what is your language capable to do.
second, user convenience is way more important that difficulty of compiler, what makes compiler "difficult", but it is the right way to do.
i would say Language Syntax -> Parser Ast, then (AST + semantic) -> Compiler.
and final word is used to RESTRICT possibility of subclassing for other CODERS , NOT to inforrm the compiler that you can optimize because this class will have no subclasses.
And about this, i would say according to OOP principies you should structure the clean code so that any class should be extendable. If somebody can extend in the way it breaks working, the design is wrong.
Good language should rather support coder to make good design and restrict him to make bad design.
If you take this in your langauge, you will not have final world, but the compiler still may do optimisations for classes who actually are not extended.
This makes syntax easier, semantic better, but compiler more "difficult".