Efficient Global Register Allocation

Efficient Global Register Allocation

Efficient global register allocation Ian Rogers Google Mountain View, California, USA [email protected] ABSTRACT interval itself is a collection of pairs of beginning and end integers. In a compiler, an essential component is the register allocator. Two As an interval may be needed for every instruction, in Static Single main algorithms have dominated implementations, graph coloring Assignment (SSA) form, the interval’s memory requirement is often and linear scan, differing in how live values are modeled. Graph similar to that of the instruction representation. Phrased another coloring uses an edge in an ‘interference graph’ to show that two way, modeling intervals can more than double the compiler’s mem- values cannot reside in the same register. Linear scan numbers all ory usage. Graph coloring similarly impacts memory and in his values, creates intervals between definition and uses, and then inter- seminal paper Chaitin concludes with “a fair amount of virtual vals that do not overlap may be allocated to the same register. For storage is needed to hold the program IL and interference graph,” both algorithms the liveness models are computed at considerable [11]. runtime and memory cost. Furthermore, these algorithms do little As a runtime cost, interval construction is often a significant to improve code quality, where the target architecture and register portion of register allocation time. Poletto and Sarkar’s early linear coalescing are important concerns. scan work shows “allocation setup”, described as, “the construction We describe a new register allocation algorithm with lightweight of live intervals,” as being the largest portion of time spent for the implementation characteristics. The algorithm introduces a ‘future- register allocation of “dynamic code kernels” (Fig. 3 in [28]). The active’ set for values that will reside in a register later in the alloca- overhead of interval construction is used to motivate a fast interval tion. Registers are allocated and freed in the manner of linear scan, construction that unfortunately lowered code quality. although other ordering heuristics could improve code quality or Fig. 1 shows a repeat of Poletto and Sarkar’s analysis but for lower runtime cost. An advantageous property of the approach is LLVM [22] compiling itself at compilation level ‘-O2’. The box plots an ability to make these trade-offs. A key result is the ‘future-active’ show the minimum, 1 percentile, median, 99 percentile and maxi- set can remove any liveness model for over 90% of instructions and mum compile time percentage of each phase compiling a file from 80% of methods. The major contribution is the allocation algorithm LLVM, where the register allocator is LLVM’s greedy allocator [26]. that, for example, solves an inability of the similarly motivated Unlike Poletto and Sarkar’s early work [28], interval construction is Treescan register allocator [15] to look ahead of the instruction not the slowest of the 3 phases. However, removing the phase would being allocated - allowing an unconstrained allocation order, and an save 0.2% of compile time or 20% of one of the major portions of ability to better handle fixed registers and loop carried values. The register allocation time. Just as when Poletto and Sarkar introduced approach also is not reliant on properties of SSA form, similar to the linear scan, interval construction costs have been attempted to be original linear scan work. An analysis is presented in a production avoided in a number of register allocators. We will review these compiler for Java code compiled through SSA form to Android dex allocators in section 6. files. After memory and runtime complexity, the final cost we sought to eliminate was the implementation complexity. Better memory 1 INTRODUCTION 10 9 The problem at the heart of register allocation is how to allocate 8 instructions (producing values) to registers so that a register is not 7 in use, holding the result of two ‘live’ instructions, at the same time. 6 arXiv:2011.05608v1 [cs.PL] 11 Nov 2020 An approach to modeling this problem is with an interference graph, 5 where instructions are vertices and edges exist between vertices 4 live at the same time. This model allows register allocation to be 3 solved through graph coloring [11], where each color is a distinct 2 register. An alternate approach is to serialize and incrementally Time Percent of Compile 1 number instructions, intervals are then formed from the definition 0 to the last use of an instruction. If two intervals have an empty intersection then they may be allocated to the same register [27, 28]. Live Analysis Live Intervals Greedy Allocator Linear scan register allocation has been refined to allow for liveness holes, and to vary the order the intervals are processed Figure 1: Contribution to LLVM compile time of register al- [26, 30, 33]. Interval based register allocators are popular due to locator phases. Compilation times were measured using on their performance and for being easy to tweak using heuristics. LLVM 7.0 using its time reporting option. Each file was com- Modeling intervals comes with clear memory costs. Typically piled 30 times on an Intel Xeon E5-2690 at 2.9GHz with 64GB an interval is associated with one or more instructions, and the of RAM. Ian Rogers and runtime performance were a concern, not because lower code do or do not motivate the use of intervals compared to the new quality was acceptable but the opposite, we wanted to focus the approach. Similarly, comparisons are not made against algorithms implementation effort on best mapping to the target architecture. such as graph coloring as this would not address implementation In common with LLVM’s greedy allocator [26], existing compilers complexity and such comparisons are already readily available in for the target architecture have a register assignment phase (also existing literature [25, 28, 30]. known as a rewrite phase) to modify impossible register alloca- The final sections of the paper consider improvements that can tions to ones that fit the machine’s constraints4 [ , 31]. We wished further reduce cost and/or that can increase code quality. A compar- to eliminate this rewriting, as even in simple cases a third of in- ison of the most related work is performed and finally conclusions structions in the final code could be introduced by it. However, by are drawn. allocating directly into the target registers we may need to restart the register allocator, for example, if register usage had become 2 BACKGROUND fragmented and no allowable register was available. The presented In the compiler we model a register allocator as taking an instruc- approach analyzes the register allocation at the point no allocation tion and mapping it to a target machine register. We present the is available, selects the best candidate instruction that can have its target machine in section 2.1 and the compiler in section 2.2. live range split, inserts moves and then restarts the register allo- cation1. The introduced move instructions become candidates for the existing register coalescing algorithms. Performing a similar 2.1 Dex files analysis and transformation with intervals is a challenge. Firstly, Regularly a Java program is compiled into a class file [23], where intervals and not instructions are allocated and so determining each class file holds the code and data for a single class. Bytecode cost requires going through an abstraction and determining what in class files is stack oriented, while indices into a constant pool intervals and instructions are being modeled as live at the failure can provide literal values or describe symbolic references to fields, point. Secondly, the liveness model needs updating following the methods and other classes. transformation, something that may be handled by additional state Android introduced the notion of dex files, that hold more than or by just recomputing the model. It could be that existing register one class, and are executed by the Dalvik or ART runtimes [4, 10]. coalescing performed is impacted by live range splitting, something Various tables in the dex file take the place of the constant pool the presented approach handles elegantly by not having state but and classes may share table entries to reduce size. Tables may be that requires existing approaches to either ignore, recompute or indexed by dex instructions or from other tables. For the string model via additional complex state. table the index may be 32-bit but in general the index is limited Reduced complexity and an ability to spot optimizations are key to 16-bits. If there is no room in a table then the compiler will advantages to the presented algorithm. We will discuss the target generate multiple dex files following a convention that indicates to machine challenges that motivated them in section 2 as well as the runtime that the dex files should be considered one unit. Classes the compiler framework. These advantages would also be apparent may not be split over dex files and each dex file is required to verify were the register allocation algorithm used for other architectures. separately. It is possible to organize the tables to either achieve a Section 3 describes the major contribution of the paper, a reg- smaller file, or to optimize start-up speed. ister allocator algorithm that performs on-the-fly construction of Dex instructions are 2-byte aligned and may be up to 10 bytes ‘future-active’ sets and the ‘live-at-the-same-time’ operations that in length [14]. They consist of a 1-byte opcode and then multiple allow these to function as intervals. For an intuition as to why bytes encoding registers used and defined, constants, branch offsets this improves performance, the ‘future-active’ sets are only used and symbol table indices.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    12 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us