EM . optimize = WPO + ACO
EM relies upon two complementary optimization techniques – whole-program [ WPO ] and application-centric [ ACO ] – which work in tandem inside the EM language translator, yielding more efficient executable images than equivalent programs written directly in C/C++.
Seeing the whole program
Rule of thumb – the more source code seen by a compiler, the more optimization a compiler can perform. So in the limit, invoking a standard C/C++ compiler with all of the application sources as input would enable the most aggressive levels of program-wide optimization.
The EM language translator in fact does just that – producing a single main.cpp
file which includes generated C++ code for all .em
modules directly or indirectly used in our application:
FULL DISCLOSURE – My early experience with LTO
Taught for decades to organize our C/C++ programs as independent source files (reflecting our code's inherent modularity), the "whole program" would only come together within the linker – already downstream from the optimizer , which would only see small chunks of code at a time.
Back at Texas Instruments, I had the opportunity to work with our compiler team on their Alchemy project – an early foray into what today we commonly term as link-time optimization [LTO] . When generating a linkable object module, the compiler would embed an intermediate form of its source code within the binary; the linker (which binds object modules into an executable image) would effectively extract the intermediate code from these modules, combine them into a "whole program", and rerun the optimizer on this single compilation unit.
Fitting comfortably within the traditional compile+
→ link
build-flow (no need to modify any legacy C/C++ code) personal experience with LTO in popular compilers [ GCC, LLVM, IAR ] proved somewhat frustrating (ironically) due to lengthy build-times. But overall, LTO does yield smaller and faster C/C++ program images.
The EM build-flow mitigates this issue by translating each Mod.em
source file into a corresponding pair of C/C++ files – all combined into a single main.cpp
program file and passed to a single invocation of the compiler with appropriate optimization options [ -O3
, -Os
, -Oz
]. Said another way, C/C++ serves as EM's object language.
With EM programs typically encompassing over 100 individual .em
source files, we can usually translate and compile the "whole program" in as little as ~5 seconds – and with code size/speed often exceeding LTO.
Knowing the whole application
But wait, there's more !!! The EM program build-flow inserts a novel configuration stage between the translation and compilation phases – enabling a world of application-centric optimizations often missing when building legacy C/C++ programs:
Besides generating C++ code for each .em
source file, the EM translator also outputs a corresponding Node.js module; the translator then combines these individual modules into a single main.js
program – executable at build-time on your host PC.
Said another way, the configuration phase represents a staging ground where the "whole program" comes together for a dry-run, so to speak. By implementing special intrinsic functions, each EM module can actively participate in the configuration process at build-time:
by binding values to EM language config
parameters published by other modules
by initializing private config
parameters and var
data objects used internally
by wiring one module to another using EM's proxy
– interface
design pattern
by forcibly including or excluding individual modules from downstream compilation
by generating fragments of specialized C/C++ code which main.cpp
will incorporate
Said another way, EM serves as its own meta-language used for build-time meta-programming .
With boundless resources on your host PC – and with all of Node.js available to the main.js
meta-program – opportunities abound for individual EM modules to encapsulate application-centric logic that ultimately shapes program images targeting resource-constrained MCUs.
What can you do to help
tackle the Technical overview to learn more about the language keywords
cited above
deep-dive into the Program configuration material for the back-story on JavaScript
consider Installing EM and actually inspecting the generated code for some basic examples
Happy coding !!!