Skip to content

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:

Image info

Compilation Phase
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 singlemain.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 optimiza­tions often missing when building legacy C/C++ programs:

Image info

Configuration Phase

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 !!!   🌝   💻