Static Basic Block Reordering Heuristics for Implicit Control Flow in Baseline JITs
Abstract
Baseline JIT compilers in dynamically-typed languages often use techniques such as static type predictions to optimize common execution paths using static heuristics. Such compilations exhibit implicit slow paths, defined by the language implementation and not by a developer, representing uncommon execution paths e.g., automatic type coercions, type validations and operation reifications. At run time implicit slow paths need to be jumped over and penalize overall execution. Removing implicit slow paths from the main execution path requires code reordering techniques. However, such heuristics are generally designed to work with profiling information. Based on the insight that implicit slow paths are known at compile-time, and thus do not require runtime-profiles, we experimented with two different code reordering algorithms: Pettis-Hansen Bottom-Up $(O (n^3))$ augmented with static code layout heuristics, and a slow-to-end heuristic $(O (n))$. Our results show that many micro-benchmarks improve their run time by 1.2x. Benchmarks governed by more expensive computations such as message sends or garbage collections show in general no visible performance improvement nor degradations, while very few cases show degradations of up to 1.2x. We show that such static heuristics have low performance impact at compile-time and have great potential when static type predictions are present in the JIT compiler.