Skip to content

Tachyon’s Design Principles

January 6, 2012

I have been working on the Tachyon compiler for almost two years at this point. Because this compiler aims to eventually support all of the ECMAScript 5 specification, it has grown fairly large and complex. Its complexity will no doubt keep increasing as new features and optimizations are added to the implementation. Because of this growing complexity, there is a need to try and keep the implementation well-organized and self-consistent. In this post, I will outline the basic principles I aim to follow in the design and implementation of Tachyon. These principles are rooted in my own experience and opinions as a programmer as well as in Tachyon’s design goals.

The Tachyon project was originally initiated with the goal of being a flexible platform for academics to experiment with various language ideas and compiler optimizations. The choice to write the compiler itself in JavaScript was partly motivated by the perception that writing compiler algorithms in JavaScript could be done more quickly and easily than in traditional statically typed languages such as C and C++, making Tachyon more appealing as an experimental research platform. I have been aiming to use Tachyon to test my own optimization ideas. As such, it has been important for me that Tachyon should be designed with the generation of efficient machine code in mind.

The design principles outlined below are based on these design goals:

  1. As much of Tachyon’s code as possible should be written in pure JavaScript. Where low-level facilities are needed or when performance demands require it, Tachyon’s extended JavaScript dialect should be used. Use of C code should be restricted, as much as possible, to low-level OS/platform/API interfaces. This will help keep the implementation minimalist and self-consistent. It should also help Tachyon optimize itself. This has motivated the implementation of Tachyon’s garbage collector in extended JavaScript.
  2. Tachyon should be designed with ease of code analysis and optimization in mind. The Tachyon frontend should use a platform-neutral Intermediate Representation (IR) that is easy to traverse and transform.
  3. Analyses and optimizations that are not specific to a given platform should be implemented in Tachyon’s frontend part, which uses a platform-neutral IR. This will avoid duplication of code in platform-specific backends.
  4. Platform-specific optimizations should be implemented in one of Tachyon’s backends. The frontend’s IR should be low-level enough that these platform-specific optimizations are possible, but the frontend’s code should not be burdened by the specific complexities of the x86 or ARM instruction sets, for example.
  5. The Tachyon frontend should have as little dependencies on backend components as possible. This will help keep the code less tightly coupled and more portable.
  6. The stock implementation of Tachyon should be kept relatively simple and not be overburdened with low-level optimizations. This will help keep the code smaller, less tightly coupled and more maintainable.
  7. The algorithms used in Tachyon should be able to scale to reasonable input sizes. Compilation speed is not Tachyon’s primary goal, but the compiler should be able to manage to compile real-world code within a reasonable time frame so that it is practical to study this code.
  8. Where performance is not critical, simpler, more concise algorithms should be preferred.
  9. Tachyon’s code should be well-commented and self-documenting. Code, by itself, is never as intuitive and self-obvious to new users as it was to those who wrote it.
  10. Tachyon should be extensively tested using unit tests and self-checking test programs. It is very important to ensure that Tachyon remains a reliable compiler and as few new bugs creep in as possible.

From → Programming, Tachyon

Leave a Comment

Leave a comment