MLRISC

MLRISC Contributors Requirements How to Obtain MLRISC

Overview

Problem Statement Contributions MLRISC Based Compiler MLRISC Intermediate Representation MLRisc Generation Back End Optimizations Register Allocation Machine Description Garbage Collection Safety System Integration Optimizations Graphical Interface Line Counts Systems Using MLRISC Future Work

System

Architecture of MLRISC The MLTREE Language MLTree Extensions MLTree Utilities Instruction Selection Assemblers Machine Code Emitters Delay Slot Filling Span Dependency Resolution The Graph Library The Graph Visualization Library Basic Compiler Graphs The MLRISC IR SSA Optimizations ILP Optimizations Optimizations for VLIW/EPIC Architectur... Register Allocator

Back Ends

The Alpha Back End The PA RISC Back End The Sparc Back End The Intel x86 Back End The PowerPC Back End The MIPS Back End The TI C6x Back End

Basic Types

Annotations Cells Cluster Client Defined Constants Client Defined Pseudo Ops Instructions Instruction Streams Label Expressions Labels Regions Regmap

# MLRisc Generation

Every compiler will eventually compile down to an abstract machine that it believes will execute source programs efficiently. The abstract machine will typically consists of abstract machine registers and instructions, one or more stacks, and parameter passing conventions. The hope is that all this will map down efficiently onto the target machine. Indeed, the abstract machine should be reasonably close to architectures that are envisioned as possible targets. Several step need to be followed in the generation of MLRisc.

1. The first step in generating target machine code is to define the MLRisc intermediate representation after it has been appropriately specialized. The interfaces that describe the dimensions of specialization are quite simple. Depending on the compiler, these may be target dependent; for example, in the SML/NJ compiler, the encoding of registers used to indicate the roots of garbage collection depend on how the runtime system decodes the information.

2. The only real connection between the MLRisc intermediate representation and the target machine is that the first 0..K-1 MLRisc registers map onto the first K physical registers on the target machine. Thus some mapping of dedicated abstract machine registers to physical target registers is required. It is not always necessary to map abstract machine registers to physical machine registers. For example, on architectures like the x86 with few registers, some abstract machine registers may be mapped to fixed memory locations. Thus an abstract machine register like the `maskReg` may have something like:

          LOAD(32, LABEL maskRegLab)

   spliced instead.

3. The unit of compilation is called a cluster which is the smallest unit for inter-procedural optimizations. A cluster will typically consist of several entry points that may call each other, as well as call local functions in the module. For maximum flexibility, the parameter passing convention for local functions should be specialized by the register allocator.

   Once the MLRisc trees for a cluster have been built, they must be converted into target assembly or machine code. This is done by building up a function (codegen) that glues together optimizations modules that have been specialized. For example, the target instruction set must be specialized to hold the MLRisc constants; the flowgraph must be specialized to carry these instructions as well as the MLRisc pseudo-ops; the optimization modules must know about several front end constraints such as how to spill registers.

If the module that translates the abstract machine instructions into MLRisc instructions has been appropriately parameterized, then it can be reused for multiple target architectures. For high level languages it is better to generate MLRisc instructions from the high level intermediate form used by the front end of the compiler.

Lal George
Allen Leung

Generated by mltex2html
Last modified: Mon Oct 3 20:52:35 UTC 2022 by buildd@x86-grnet-02