• No results found

This section describes developments conducted at STMicroelectronics. Due to their industrial context, the effort dedicated to dissemination and publication was limited.

6.6.1

LxBE – VLIW Compilation

This work was performed at STMicroelectronics in 2000–2004. Other par- ticipants include a team of eight engineers and PhDs. LxBE is 300k lines of C++. It is proprietary code.

VLIW processors do not have any hardware to detect dependencies between operations, or any out-of-order capability. They are easier to design, cheaper to manufacture, and they consume less power. But the performance comes entirely from the compiler’s ability to extract instruction level parallelism.

LxBE stands for Lx back-end. It is the codename of a effort to produce a state- of-the-art, industrial-quality, and retargetable compiler for the ST200 processor family. It was designed to be shipped to real customers, implying a significant effort of documentation, generating proper error messages, etc. At the same time, it was also flexible enough to be used as a research vehicle.

The back-end was implemented from scratch, in an effort initiated by Josh Fisher’s group at Hewlett-Packard Laboratories, soon joined by the AST (Advanced System Technology) unit of STMicroelectronics. We connected it with a compiler front-end developed by the Portland Group Inc. (PGI), one of the leaders of com- pilers and tools for parallel computing, and a subsidiary of STMicroelectronics at that time. Connecting two large pieces of software independently developed proved to be a large and complex effort.

Robustness was a major concern. Benchmarking and testing were a significant part of the global effort, as well as generation of proper debug information, and clean integration in the overall toolchain. In spite of the industrial focus, we obtained and published new results about alias analysis [GCCRR02, CGRCR04] (Section 2.1).

6.6.2

Processor Virtualization

This work was performed at ST200, with a team of engineers and PhDs. GCC4CLI consists in 40k lines of C added to the GCC middle-end. It is open-source: https://gcc.gnu.org/projects/cli.html. PVM consists in 170k lines of C. It remained proprietary.

As an alternative to the burden of deploying statically compiled code, we started exploring more dynamic aspects of compilation: JIT compiler and virtual machines for embedded systems. Introducing a platform-neutral program representation in the form of a bytecode is a major issue for application portability. In the embedded system industry, the execution targets evolve very rapidly and are often heteroge- neous. JIT compilers and virtual machines smooth the development flow and make the integration easier; they also make it possible to postpone the allocation of code fragments to the different processors, even until run-time [ROÖC10].

For pragmatic reasons, we adopted the well defined and extensively documented CLI format (also known as the core of Microsoft .NET). We developed both the bytecode producer as an extension of the GCC compiler (GCC4CLI), and bytecode consumers: an interpreter and JIT compilers.

We showed that the bytecode is typically smaller than the same application written in native code, even for dense instruction sets like ARM Thumb or SH-4 [CR05]. Code size is extremely important in the embedded world because it directly translates into the cost of the flash memory. We also showed that applications compiled to bytecode are not necessarily slow, and that the average performance is not very different from programs compiled directly to native code [CCFP+08],

provided that a reasonable set of optimizations is available in the JIT compiler. This result debunked a myth that using bytecodes results in a “loss” of information that, in turn, degrades performance.

GCC4CLI Most legacy code for embedded systems is written in the C language. Because there was no C compiler generating CLI, we developed a back-end for GCC [COR07]. Named GCC4CLI, this compiler is more than a mere port of GCC: CLI is a strongly typed representation, forcing us to maintain high-level informa- tion. The evaluation stack – another common feature of virtual machines – also requires special treatment. GCC4CLI adds a new intermediate representation to the GCC compiler, along with a dozen new optimizations specific to the CLI format [SOR09]. Good quality code required developing stack-oriented optimizations, such as elimination of redundant stack accesses [COR07]. GCC4CLI was instrumental to our split-compilation research, in particular the generation of vectorized bytecode [Roh10] for our Vapor SIMD [RDN+11, NDR+11] (see Section 3.1) and interpreter superinstructions (see Section 5.3).

Beyond the need to handle the stack, compiling the C language to the CLI representation proved to be a challenging task, due to the fact that CLI is stricter than C in several aspects (management of data types, function prototypes, switch statements, vararg functions...) We studied the relations of the various components of the C ecosystem (language standard, ELF format for executables and libraries, operating system interface) and we proposed solutions for efficient compilation of C to CLI [ROC10].

PVM We designed and built PVM, an entire virtual machine for ARM- and ST200-based STMicroelectronics platforms, featuring an interpreter and JIT com- pilers, capable of mixed-mode execution (switching between interpretation and JIT- compilation). We demonstrated that JIT technology is a viable approach even for real-time embedded systems.

The operations of the virtual machine are under the control of the VES (Virtual Execution System). The VES first requests the loader to locate the executable and to store it in memory. The verifier is then invoked to check the legality of the byte- code, as mandated by the CLI standard. In particular, it checks that local variables are only assigned values of the proper type, and that no stack overflow or underflow can occur. While processing the CLI input stream, it emits an internal representa-

73

tion (IR bytecode) that is used by the rest of virtual machine. IR resembles CLI, but it is more efficiently processed by the interpreter. For example, polymorphic CLI operators such as add are replaced by typed operators like add.i4 (32-bit inte- ger addition) or add.r8 (double precision floating point). When the interpreter is invoked, frequent bytecode patterns are combined into pre-built superinstructions [EG03], to reduce the number of dispatched bytecodes and improve performance.

PVM’s interpreter was instrumental to our research in applying vectorization technology to interpreters (cf. Section 5.3), as well as debunking the folklore about the performance of indirect branch prediction in interpreters (cf. Section 5.2).

Related documents