AFAIK, there's no C++ syntax for letting know the compiler that the
operators in your classes exactly match the same meaning as some
built-in type. So, if for example you write a class that implements
IEEE fp math in software, the compiler won't have the chance of
transforming the expression into a different one that has the same
result with a lower computation cost (*).
Given that LLVM is hackable by nature, is there some workaround by
which I could tell clang "consider the operators for this class with
the same optimization opportunities as this other built-in type" ?
Alternatively, does LLVM have any tool (or do you know of any outside
LLVM) that would allow to perform static optimization of an arithmetic
expression and transform the code, similar to a preprocessor step?
(*) Note: I acknowledge that even if the operators had the same
meaning as a built-in type, maybe their relative cost would be
different, so, ideally it wouldn't be a matter of just telling the
meaning of the operator, but also its relative cost.
Thanks a lot,
(I'm forwarding this to llvm-dev because after reading the "Extending
LLVM" document (https://llvm.org/docs/ExtendingLLVM.html) it gives the
advice of asking in llvm-dev those questions related to adding new
After deeper considerations on how could I get arithmetic expressions
optimized when they take C++ objects whose operators you implement in
software (imagine a software implementation of IEEE fp types), I'm
coming to the conclusion that the only way for achieving this would be
to implement them not as regular C++ classes in your C++ code, but
internally in LLVM, so that the operators are not substituted before
the translation to IR, but later (either in the backend or perhaps
just before the backend is invoked).
Which I guess redefines my question in much more precise terms:
Can I create new custom builtin types whose operators are not
implemented in CPU-dependent backend code, but on IR code instead? Can
I assign a performance cost to each IR operator, so that they are
optimized while in IR rather than on the backend scheduler? How can I
do this, is there any similar example that I could follow?
Note: My wish of trying to do this in IR rather than in the
CPU-dependent backend is because maintaining a custom builtin whose
operators are actually implemented in C++ code would be perhaps a huge
effort if you need to implement it in all available CPU backends,
while an implementation in IR could be more manageable (perhaps even
automated by invoking clang for getting the IR for the C++ code of
each of your operators).
Thanks a lot!
LLVM has its predetermined set of types of instructions
(https://llvm.org/docs/LangRef.html) and optimizations look for
specific instructions that it can be applied to, instead of its
properties. Hence, it is not possible to apply the same optimization
on user-implemented types and operations.
This might change with MLIR which has extendable types and operations
and optimizations might be more guided by an operation property. For
instance, there is mlir::OperationProperty::Commutative so
optimization passes use this property instead of just knowing all the
instructions that are commutative.
Sadly, commutativity is (currently) the only semantic property of
Another item to consider is, once you implemented a custom type and
operators in C++, how does the compiler know about its properties.
There is no C++ API to make the compiler know.
Thanks a lot for confirming my fears, Michael. Let me add a vote for
adding support for arithmetic expression optimization with generic
user-defined types. Granted, as you mention, there's no C++ API
available for defining operators in such a way that compilers could
have hints for optimization opportunities.
As an alternative, I just realized that some expression parsers can
optimize arithmetic expressions for speed (like ExprTk by Arash Partow
https://github.com/ArashPartow/exprtk , which, according to the
documentation, supports "optimisations: constant-folding, simple
strength reduction and dead code elimination" ).
Unfortunately, I don't know of any standard way of making the C++
preprocessor invoke an external tool for transforming the code before
compiling (of course I can write a custom preprocessor that optimizes
expressions before invoking the C++ preprocessor, but it would be much
cleaner if the expression optimizer could be run transparently by the
Kind regards and thanks a lot!