Understanding Various Levels of Optimizations

Learn how to utilize the emcc compiler’s optimization options and integrate the Closure Compiler to enhance code efficiency and reduce code size.

C/C++ programs are compiled and converted into native code via Clang or the GCC compiler. They convert the C/C++ program based on the target. Here, the target refers to the end machine where the code is executed. emcc has the Clang compiler built in. The emcc compiler is responsible for converting the C or C++ source code into LLVM byte code.

In this section, we’ll see how to improve the optimization and code size of the generated WebAssembly binary code. To improve the efficiency and generated code size, the Emscripten compiler has the following options:

  • Optimizations

  • Closure Compiler

Let’s talk about optimizations first.

Optimizations

The goal of the compiler is to reduce the cost of compilation—that is, the compile time. With the -O optimization flag, the compiler tries to improve the code size and/or the performance at the expense of the compile time. In terms of compiler optimizations, code size and performance are mutually exclusive. The faster the compile time, the lower the optimization. To specify the optimization, we use the -O<0/1/2/3/s/z> flag. Each of the options includes various assertions, code size optimizations, and code performance optimizations, along with others.

The following are the various optimizations available:

  • -O0: This is the default option and a perfect starter with which to experiment. This option means “no optimizations.” This optimization level compiles the fastest and generates the most debuggable code. This is a basic optimization level. This option tries to inline functions.

  • -O1: This option adds simple optimizations and tries to generate a minimum code size. This option removes runtime assertions in the generated code and builds slower than the -O0 option. This option also tries to simplify the loops.

  • -O2: This option adds further optimizations than -O1. It’s slower than -O1 but generates code that is more optimized than the -O1 option. This option also optimizes the code based on JavaScript optimization and removes code that is not part of JavaScript modules. It removes the inline functions, and sets the vectorize-loop option. This option adds a moderate level of optimization, and it also adds dead code elimination. Vectorization will instruct the processor to do the operation in chunks rather than doing it one by one.

  • -O3: This option adds more options, takes more time to compile, and generates more optimized code than the -O2 option. This option produces optimal production-ready code. It’s like -O2, except that it enables optimizations that take longer to perform or that may generate larger code (in an attempt to make the program run faster).

  • -Os: This option is similar to -O2. It adds extra optimizations and reduces the code size. Reducing the code size in turn decreases the performance. This option generates smaller code than -O2.

  • -Oz: This option is similar to -Os but reduces the code size even further. This option takes more compile time to generate the binary code.

We will now explore the various optimization options provided by Emscripten:

  1. First, we create a C file called optimization_check.c:

Get hands-on with 1200+ tech skills courses.