Rename Cretonne to Cranelift!

This commit is contained in:
Dan Gohman
2018-07-13 09:01:28 -07:00
parent 19a636af96
commit f4dbd38a4c
306 changed files with 977 additions and 975 deletions

View File

@@ -1,6 +1,6 @@
//! Code sink that writes binary machine code into contiguous memory.
//!
//! The `CodeSink` trait is the most general way of extracting binary machine code from Cretonne,
//! The `CodeSink` trait is the most general way of extracting binary machine code from Cranelift,
//! and it is implemented by things like the `test binemit` file test driver to generate
//! hexadecimal machine code. The `CodeSink` has some undesirable performance properties because of
//! the dual abstraction: `TargetIsa` is a trait object implemented by each supported ISA, so it
@@ -20,7 +20,7 @@ use std::ptr::write_unaligned;
/// A `CodeSink` that writes binary machine code directly into memory.
///
/// A `MemoryCodeSink` object should be used when emitting a Cretonne IR function into executable
/// A `MemoryCodeSink` object should be used when emitting a Cranelift IR function into executable
/// memory. It writes machine code directly to a raw pointer without any bounds checking, so make
/// sure to allocate enough memory for the whole function. The number of bytes required is returned
/// by the `Context::compile()` function.

View File

@@ -1,6 +1,6 @@
//! Binary machine code emission.
//!
//! The `binemit` module contains code for translating Cretonne's intermediate representation into
//! The `binemit` module contains code for translating Cranelift's intermediate representation into
//! binary machine code.
mod memorysink;
@@ -17,7 +17,7 @@ use std::fmt;
/// Offset in bytes from the beginning of the function.
///
/// Cretonne can be used as a cross compiler, so we don't want to use a type like `usize` which
/// Cranelift can be used as a cross compiler, so we don't want to use a type like `usize` which
/// depends on the *host* platform, not the *target* platform.
pub type CodeOffset = u32;
@@ -49,7 +49,7 @@ pub enum Reloc {
impl fmt::Display for Reloc {
/// Display trait implementation drops the arch, since its used in contexts where the arch is
/// already unambigious, e.g. cton syntax with isa specified. In other contexts, use Debug.
/// already unambigious, e.g. clif syntax with isa specified. In other contexts, use Debug.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Reloc::Abs4 => write!(f, "Abs4"),

View File

@@ -15,13 +15,13 @@
//! On RISC architectures, it can happen that conditional branches have a shorter range than
//! unconditional branches:
//!
//! ```cton
//! ```clif
//! brz v1, ebb17
//! ```
//!
//! can be transformed into:
//!
//! ```cton
//! ```clif
//! brnz v1, ebb23
//! jump ebb17
//! ebb23:

View File

@@ -1,6 +1,6 @@
//! Instruction shrinking.
//!
//! Sometimes there are multiple valid encodings for a given instruction. Cretonne often initially
//! Sometimes there are multiple valid encodings for a given instruction. Cranelift often initially
//! chooses the largest one, because this typically provides the register allocator the most
//! flexibility. However, once register allocation is done, this is no longer important, and we
//! can switch to smaller encodings when possible.

View File

@@ -1,4 +1,4 @@
//! Cretonne compilation context and main entry point.
//! Cranelift compilation context and main entry point.
//!
//! When compiling many small functions, it is important to avoid repeatedly allocating and
//! deallocating the data structures needed for compilation. The `Context` struct is used to hold

View File

@@ -46,8 +46,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, SourceLoc};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, SourceLoc};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, srcloc: SourceLoc) {
/// let mut pos = FuncCursor::new(func).with_srcloc(srcloc);
///
@@ -76,8 +76,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, inst: Inst) {
/// let mut pos = FuncCursor::new(func).at_inst(inst);
///
@@ -99,8 +99,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = FuncCursor::new(func).at_first_insertion_point(ebb);
///
@@ -120,8 +120,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = FuncCursor::new(func).at_first_inst(ebb);
///
@@ -141,8 +141,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = FuncCursor::new(func).at_last_inst(ebb);
///
@@ -162,8 +162,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, inst: Inst) {
/// let mut pos = FuncCursor::new(func).after_inst(inst);
///
@@ -183,8 +183,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = FuncCursor::new(func).at_top(ebb);
///
@@ -204,8 +204,8 @@ pub trait Cursor {
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb, Inst};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb, Inst};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = FuncCursor::new(func).at_bottom(ebb);
///
@@ -311,8 +311,8 @@ pub trait Cursor {
/// The `next_ebb()` method is intended for iterating over the EBBs in layout order:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function) {
/// let mut cursor = FuncCursor::new(func);
/// while let Some(ebb) = cursor.next_ebb() {
@@ -344,8 +344,8 @@ pub trait Cursor {
/// The `prev_ebb()` method is intended for iterating over the EBBs in backwards layout order:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function) {
/// let mut cursor = FuncCursor::new(func);
/// while let Some(ebb) = cursor.prev_ebb() {
@@ -381,8 +381,8 @@ pub trait Cursor {
/// this:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_ebb(func: &mut Function, ebb: Ebb) {
/// let mut cursor = FuncCursor::new(func).at_top(ebb);
/// while let Some(inst) = cursor.next_inst() {
@@ -395,8 +395,8 @@ pub trait Cursor {
/// Iterating over all the instructions in a function looks like this:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function) {
/// let mut cursor = FuncCursor::new(func);
/// while let Some(ebb) = cursor.next_ebb() {
@@ -451,8 +451,8 @@ pub trait Cursor {
/// EBB like this:
///
/// ```
/// # use cretonne_codegen::ir::{Function, Ebb};
/// # use cretonne_codegen::cursor::{Cursor, FuncCursor};
/// # use cranelift_codegen::ir::{Function, Ebb};
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
/// fn edit_ebb(func: &mut Function, ebb: Ebb) {
/// let mut cursor = FuncCursor::new(func).at_bottom(ebb);
/// while let Some(inst) = cursor.prev_inst() {

View File

@@ -1,12 +1,12 @@
//! Debug tracing macros.
//!
//! This module defines the `dbg!` macro which works like `println!` except it writes to the
//! Cretonne tracing output file if enabled.
//! Cranelift tracing output file if enabled.
//!
//! Tracing can be enabled by setting the `CRETONNE_DBG` environment variable to something
//! Tracing can be enabled by setting the `CRANELIFT_DBG` environment variable to something
/// other than `0`.
///
/// The output will appear in files named `cretonne.dbg.*`, where the suffix is named after the
/// The output will appear in files named `cranelift.dbg.*`, where the suffix is named after the
/// thread doing the logging.
#[cfg(feature = "std")]
use std::cell::RefCell;
@@ -29,7 +29,7 @@ static STATE: atomic::AtomicIsize = atomic::ATOMIC_ISIZE_INIT;
/// Is debug tracing enabled?
///
/// Debug tracing can be enabled by setting the `CRETONNE_DBG` environment variable to something
/// Debug tracing can be enabled by setting the `CRANELIFT_DBG` environment variable to something
/// other than `0`.
///
/// This inline function turns into a constant `false` when debug assertions are disabled.
@@ -56,7 +56,7 @@ pub fn enabled() -> bool {
/// Initialize `STATE` from the environment variable.
#[cfg(feature = "std")]
fn initialize() -> bool {
let enable = match env::var_os("CRETONNE_DBG") {
let enable = match env::var_os("CRANELIFT_DBG") {
Some(s) => s != OsStr::new("0"),
None => false,
};
@@ -92,7 +92,7 @@ pub fn writeln_with_format_args(args: fmt::Arguments) -> io::Result<()> {
fn open_file() -> io::BufWriter<File> {
let curthread = thread::current();
let tmpstr;
let mut path = "cretonne.dbg.".to_owned();
let mut path = "cranelift.dbg.".to_owned();
path.extend(
match curthread.name() {
Some(name) => name.chars(),

View File

@@ -1,6 +1,6 @@
//! Cretonne instruction builder.
//! Cranelift instruction builder.
//!
//! A `Builder` provides a convenient interface for inserting instructions into a Cretonne
//! A `Builder` provides a convenient interface for inserting instructions into a Cranelift
//! function. Many of its methods are generated from the meta language instruction definitions.
use ir;

View File

@@ -1,4 +1,4 @@
//! Condition codes for the Cretonne code generator.
//! Condition codes for the Cranelift code generator.
//!
//! A condition code here is an enumerated type that determined how to compare two numbers. There
//! are different rules for comparing integers and floating point numbers, so they use different

View File

@@ -1,6 +1,6 @@
//! Cretonne IR entity references.
//! Cranelift IR entity references.
//!
//! Instructions in Cretonne IR need to reference other entities in the function. This can be other
//! Instructions in Cranelift IR need to reference other entities in the function. This can be other
//! parts of the function like extended basic blocks or stack slots, or it can be external entities
//! that are declared in the function preamble in the text format.
//!

View File

@@ -1,6 +1,6 @@
//! External function calls.
//!
//! To a Cretonne function, all functions are "external". Directly called functions must be
//! To a Cranelift function, all functions are "external". Directly called functions must be
//! declared in the preamble, and all function calls must have a signature.
//!
//! This module declares the data types used to represent external functions and call signatures.

View File

@@ -2,7 +2,7 @@
//!
//! These are identifiers for declaring entities defined outside the current
//! function. The name of an external declaration doesn't have any meaning to
//! Cretonne, which compiles functions independently.
//! Cranelift, which compiles functions independently.
use ir::LibCall;
use std::cmp;
@@ -15,16 +15,16 @@ const TESTCASE_NAME_LENGTH: usize = 16;
/// table, or a short sequence of ascii bytes so that test cases do not have
/// to keep track of a sy mbol table.
///
/// External names are primarily used as keys by code using Cretonne to map
/// from a `cretonne_codegen::ir::FuncRef` or similar to additional associated
/// External names are primarily used as keys by code using Cranelift to map
/// from a `cranelift_codegen::ir::FuncRef` or similar to additional associated
/// data.
///
/// External names can also serve as a primitive testing and debugging tool.
/// In particular, many `.cton` test files use function names to identify
/// In particular, many `.clif` test files use function names to identify
/// functions.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExternalName {
/// A name in a user-defined symbol table. Cretonne does not interpret
/// A name in a user-defined symbol table. Cranelift does not interpret
/// these numbers in any way.
User {
/// Arbitrary.
@@ -51,7 +51,7 @@ impl ExternalName {
/// # Examples
///
/// ```rust
/// # use cretonne_codegen::ir::ExternalName;
/// # use cranelift_codegen::ir::ExternalName;
/// // Create `ExternalName` from a string.
/// let name = ExternalName::testcase("hello");
/// assert_eq!(name.to_string(), "%hello");
@@ -72,7 +72,7 @@ impl ExternalName {
///
/// # Examples
/// ```rust
/// # use cretonne_codegen::ir::ExternalName;
/// # use cranelift_codegen::ir::ExternalName;
/// // Create `ExternalName` from integer indicies
/// let name = ExternalName::user(123, 456);
/// assert_eq!(name.to_string(), "u123:456");

View File

@@ -23,7 +23,7 @@ use write::write_function;
/// The clone will have all the same entity numbers as the original.
#[derive(Clone)]
pub struct Function {
/// Name of this function. Mostly used by `.cton` files.
/// Name of this function. Mostly used by `.clif` files.
pub name: ExternalName,
/// Signature of this function.
@@ -68,7 +68,7 @@ pub struct Function {
/// Source locations.
///
/// Track the original source location for each instruction. The source locations are not
/// interpreted by Cretonne, only preserved.
/// interpreted by Cranelift, only preserved.
pub srclocs: SourceLocs,
}

View File

@@ -27,7 +27,7 @@ pub enum GlobalValueData {
offset: Offset32,
},
/// Value is identified by a symbolic name. Cretonne itself does not interpret this name;
/// Value is identified by a symbolic name. Cranelift itself does not interpret this name;
/// it's used by embedders to link with other data structures.
Sym {
/// The symbolic name.

View File

@@ -1,7 +1,7 @@
//! Immediate operands for Cretonne instructions
//! Immediate operands for Cranelift instructions
//!
//! This module defines the types of immediate operands that can appear on Cretonne instructions.
//! Each type here should have a corresponding definition in the `cretonne.immediates` Python
//! This module defines the types of immediate operands that can appear on Cranelift instructions.
//! Each type here should have a corresponding definition in the `cranelift.immediates` Python
//! module in the meta language.
use std::fmt::{self, Display, Formatter};

View File

@@ -64,7 +64,7 @@ impl Opcode {
}
}
// This trait really belongs in lib/reader where it is used by the `.cton` file parser, but since
// This trait really belongs in lib/reader where it is used by the `.clif` file parser, but since
// it critically depends on the `opcode_name()` function which is needed here anyway, it lives in
// this module. This also saves us from running the build script twice to generate code for the two
// separate crates.

View File

@@ -11,9 +11,9 @@ use std::str::FromStr;
/// The name of a runtime library routine.
///
/// Runtime library calls are generated for Cretonne IR instructions that don't have an equivalent
/// Runtime library calls are generated for Cranelift IR instructions that don't have an equivalent
/// ISA instruction or an easy macro expansion. A `LibCall` is used as a well-known name to refer to
/// the runtime library routine. This way, Cretonne doesn't have to know about the naming
/// the runtime library routine. This way, Cranelift doesn't have to know about the naming
/// convention in the embedding VM's runtime library.
///
/// This list is likely to grow over time.

View File

@@ -51,10 +51,10 @@ impl MemFlags {
/// Test if the `notrap` flag is set.
///
/// Normally, trapping is part of the semantics of a load/store operation. If the platform
/// would cause a trap when accessing the effective address, the Cretonne memory operation is
/// would cause a trap when accessing the effective address, the Cranelift memory operation is
/// also required to trap.
///
/// The `notrap` flag tells Cretonne that the memory is *accessible*, which means that
/// The `notrap` flag tells Cranelift that the memory is *accessible*, which means that
/// accesses will not trap. This makes it possible to delete an unused load or a dead store
/// instruction.
pub fn notrap(self) -> bool {
@@ -68,7 +68,7 @@ impl MemFlags {
/// Test if the `aligned` flag is set.
///
/// By default, Cretonne memory instructions work with any unaligned effective address. If the
/// By default, Cranelift memory instructions work with any unaligned effective address. If the
/// `aligned` flag is set, the instruction is permitted to trap or return a wrong result if the
/// effective address is misaligned.
pub fn aligned(self) -> bool {

View File

@@ -1,4 +1,4 @@
//! Representation of Cretonne IR functions.
//! Representation of Cranelift IR functions.
mod builder;
pub mod condcodes;

View File

@@ -12,7 +12,7 @@ use std::u32;
/// 1. An instruction or
/// 2. An EBB header.
///
/// This corresponds more or less to the lines in the textual form of Cretonne IR.
/// This corresponds more or less to the lines in the textual form of Cranelift IR.
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct ProgramPoint(u32);

View File

@@ -1,13 +1,13 @@
//! Source locations.
//!
//! Cretonne tracks the original source location of each instruction, and preserves the source
//! Cranelift tracks the original source location of each instruction, and preserves the source
//! location when instructions are transformed.
use std::fmt;
/// A source location.
///
/// This is an opaque 32-bit number attached to each Cretonne IR instruction. Cretonne does not
/// This is an opaque 32-bit number attached to each Cranelift IR instruction. Cranelift does not
/// interpret source locations in any way, they are simply preserved from the input to the output.
///
/// The default source location uses the all-ones bit pattern `!0`. It is used for instructions

View File

@@ -15,7 +15,7 @@ use std::vec::Vec;
/// The size of an object on the stack, or the size of a stack frame.
///
/// We don't use `usize` to represent object sizes on the target platform because Cretonne supports
/// We don't use `usize` to represent object sizes on the target platform because Cranelift supports
/// cross-compilation, and `usize` is a type that depends on the host platform, not the target
/// platform.
pub type StackSize = u32;

View File

@@ -1,4 +1,4 @@
//! Common types for the Cretonne code generator.
//! Common types for the Cranelift code generator.
use std::default::Default;
use std::fmt::{self, Debug, Display, Formatter};

View File

@@ -2,15 +2,15 @@
//!
//! The `isa` module provides a `TargetIsa` trait which provides the behavior specialization needed
//! by the ISA-independent code generator. The sub-modules of this module provide definitions for
//! the instruction sets that Cretonne can target. Each sub-module has it's own implementation of
//! the instruction sets that Cranelift can target. Each sub-module has it's own implementation of
//! `TargetIsa`.
//!
//! # Constructing a `TargetIsa` instance
//!
//! The target ISA is built from the following information:
//!
//! - The name of the target ISA as a string. Cretonne is a cross-compiler, so the ISA to target
//! can be selected dynamically. Individual ISAs can be left out when Cretonne is compiled, so a
//! - The name of the target ISA as a string. Cranelift is a cross-compiler, so the ISA to target
//! can be selected dynamically. Individual ISAs can be left out when Cranelift is compiled, so a
//! string is used to identify the proper sub-module.
//! - Values for settings that apply to all ISAs. This is represented by a `settings::Flags`
//! instance.
@@ -20,11 +20,11 @@
//! appropriate for the requested ISA:
//!
//! ```
//! # extern crate cretonne_codegen;
//! # extern crate cranelift_codegen;
//! # #[macro_use] extern crate target_lexicon;
//! # fn main() {
//! use cretonne_codegen::settings::{self, Configurable};
//! use cretonne_codegen::isa;
//! use cranelift_codegen::settings::{self, Configurable};
//! use cranelift_codegen::isa;
//! use std::str::FromStr;
//! use target_lexicon::Triple;
//!

View File

@@ -274,7 +274,7 @@ pub fn prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenRes
pub fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
debug_assert!(
!isa.flags().probestack_enabled(),
"baldrdash does not expect cretonne to emit stack probes"
"baldrdash does not expect cranelift to emit stack probes"
);
// Baldrdash on 32-bit x86 always aligns its stack pointer to 16 bytes.
@@ -325,7 +325,7 @@ pub fn fastcall_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> C
let csr_stack_size = ((csrs.iter(GPR).len() + 2) * word_size) as i32;
// TODO: eventually use the 32 bytes (shadow store) as spill slot. This currently doesn't work
// since cretonne does not support spill slots before incoming args
// since cranelift does not support spill slots before incoming args
func.create_stack_slot(ir::StackSlotData {
kind: ir::StackSlotKind::IncomingArg,

View File

@@ -14,13 +14,13 @@
//!
//! When legalizing a single instruction, it is wrapped in splits and concatenations:
//!
//!```cton
//!```clif
//! v1 = bxor.i64 v2, v3
//! ```
//!
//! becomes:
//!
//!```cton
//!```clif
//! v20, v21 = isplit v2
//! v30, v31 = isplit v3
//! v10 = bxor.i32 v20, v30
@@ -38,13 +38,13 @@
//! first check if the value is defined by the corresponding concatenation. If so, then just use
//! the two concatenation inputs directly:
//!
//! ```cton
//! ```clif
//! v4 = iadd_imm.i64 v1, 1
//! ```
//!
//! becomes, using the expanded code from above:
//!
//! ```cton
//! ```clif
//! v40, v5 = iadd_imm_cout.i32 v10, 1
//! v6 = bint.i32
//! v41 = iadd.i32 v11, v6
@@ -283,7 +283,7 @@ fn add_repair(
///
/// Given this input:
///
/// ```cton
/// ```clif
/// v10 = iconcat v1, v2
/// v11, v12 = isplit v10
/// ```

View File

@@ -1,4 +1,4 @@
//! Cretonne code generation library.
//! Cranelift code generation library.
#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
#![warn(unused_import_braces)]
@@ -56,11 +56,11 @@ pub use legalizer::legalize_function;
pub use verifier::verify_function;
pub use write::write_function;
/// Version number of the cretonne-codegen crate.
/// Version number of the cranelift-codegen crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
#[macro_use]
pub extern crate cretonne_entity as entity;
pub extern crate cranelift_entity as entity;
#[macro_use]
pub mod dbg;

View File

@@ -65,7 +65,7 @@ fn pretty_function_error(
}
}
/// Pretty-print a Cretonne error.
/// Pretty-print a Cranelift error.
pub fn pretty_error(func: &ir::Function, isa: Option<&TargetIsa>, err: CodegenError) -> String {
if let CodegenError::Verifier(e) = err {
pretty_verifier_error(func, isa, &e)

View File

@@ -64,7 +64,7 @@
//! LLVM's register allocator computes liveness per *virtual register*, where a virtual register is
//! a disjoint union of related SSA values that should be assigned to the same physical register.
//! It uses a compact data structure very similar to our `LiveRange`. The important difference is
//! that Cretonne's `LiveRange` only describes a single SSA value, while LLVM's `LiveInterval`
//! that Cranelift's `LiveRange` only describes a single SSA value, while LLVM's `LiveInterval`
//! describes the live range of a virtual register *and* which one of the related SSA values is
//! live at any given program point.
//!
@@ -93,11 +93,11 @@
//! functions.
//! - A single live range can be recomputed after making modifications to the IR. No global
//! algorithm is necessary. This feature depends on having use-def chains for virtual registers
//! which Cretonne doesn't.
//! which Cranelift doesn't.
//!
//! Cretonne uses a very similar data structures and algorithms to LLVM, with the important
//! Cranelift uses a very similar data structures and algorithms to LLVM, with the important
//! difference that live ranges are computed per SSA value instead of per virtual register, and the
//! uses in Cretonne IR refers to SSA values instead of virtual registers. This means that Cretonne
//! uses in Cranelift IR refers to SSA values instead of virtual registers. This means that Cranelift
//! can skip the last step of reconstructing SSA form for the virtual register uses.
//!
//! ## Fast Liveness Checking for SSA-Form Programs
@@ -112,27 +112,27 @@
//! then allows liveness queries for any (value, program point) pair. Each query traverses the use
//! chain of the value and performs lookups in the precomputed bit-vectors.
//!
//! I did not seriously consider this analysis for Cretonne because:
//! I did not seriously consider this analysis for Cranelift because:
//!
//! - It depends critically on use chains which Cretonne doesn't have.
//! - It depends critically on use chains which Cranelift doesn't have.
//! - Popular variables like the `this` pointer in a C++ method can have very large use chains.
//! Traversing such a long use chain on every liveness lookup has the potential for some nasty
//! quadratic behavior in unfortunate cases.
//! - It says "fast" in the title, but the paper only claims to be 16% faster than a data-flow
//! based approach, which isn't that impressive.
//!
//! Nevertheless, the property of only depending in the CFG structure is very useful. If Cretonne
//! Nevertheless, the property of only depending in the CFG structure is very useful. If Cranelift
//! gains use chains, this approach would be worth a proper evaluation.
//!
//!
//! # Cretonne's liveness analysis
//! # Cranelift's liveness analysis
//!
//! The algorithm implemented in this module is similar to LLVM's with these differences:
//!
//! - The `LiveRange` data structure describes the liveness of a single SSA value, not a virtual
//! register.
//! - Instructions in Cretonne IR contains references to SSA values, not virtual registers.
//! - All live ranges are computed in one traversal of the program. Cretonne doesn't have use
//! - Instructions in Cranelift IR contains references to SSA values, not virtual registers.
//! - All live ranges are computed in one traversal of the program. Cranelift doesn't have use
//! chains, so it is not possible to compute the live range for a single SSA value independently.
//!
//! The liveness computation visits all instructions in the program. The order is not important for
@@ -150,18 +150,18 @@
//! visited. No data about each value beyond the live range is needed between visiting uses, so
//! nothing is lost by computing the live range of all values simultaneously.
//!
//! ## Cache efficiency of Cretonne vs LLVM
//! ## Cache efficiency of Cranelift vs LLVM
//!
//! Since LLVM computes the complete live range of a virtual register in one go, it can keep the
//! whole `LiveInterval` for the register in L1 cache. Since it is visiting the instructions in use
//! chain order, some cache thrashing can occur as a result of pulling instructions into cache
//! somewhat chaotically.
//!
//! Cretonne uses a transposed algorithm, visiting instructions in order. This means that each
//! Cranelift uses a transposed algorithm, visiting instructions in order. This means that each
//! instruction is brought into cache only once, and it is likely that the other instructions on
//! the same cache line will be visited before the line is evicted.
//!
//! Cretonne's problem is that the `LiveRange` structs are visited many times and not always
//! Cranelift's problem is that the `LiveRange` structs are visited many times and not always
//! regularly. We should strive to make the `LiveRange` struct as small as possible such that
//! multiple related values can live on the same cache line.
//!

View File

@@ -41,7 +41,7 @@
//!
//! If one live range ends at an instruction that defines another live range, those two live ranges
//! are not considered to interfere. This is because most ISAs allow instructions to reuse an input
//! register for an output value. If Cretonne gets support for inline assembly, we will need to
//! register for an output value. If Cranelift gets support for inline assembly, we will need to
//! handle *early clobbers* which are output registers that are not allowed to alias any input
//! registers.
//!

View File

@@ -4,22 +4,22 @@ use verifier::VerifierError;
/// A compilation error.
///
/// When Cretonne fails to compile a function, it will return one of these error codes.
/// When Cranelift fails to compile a function, it will return one of these error codes.
#[derive(Fail, Debug, PartialEq, Eq)]
pub enum CodegenError {
/// An IR verifier error.
///
/// This always represents a bug, either in the code that generated IR for Cretonne, or a bug
/// in Cretonne itself.
/// This always represents a bug, either in the code that generated IR for Cranelift, or a bug
/// in Cranelift itself.
#[fail(display = "Verifier error: {}", _0)]
Verifier(#[cause] VerifierError),
/// An implementation limit was exceeded.
///
/// Cretonne can compile very large and complicated functions, but the [implementation has
/// Cranelift can compile very large and complicated functions, but the [implementation has
/// limits][limits] that cause compilation to fail when they are exceeded.
///
/// [limits]: https://cretonne.readthedocs.io/en/latest/langref.html#implementation-limits
/// [limits]: https://cranelift.readthedocs.io/en/latest/langref.html#implementation-limits
#[fail(display = "Implementation limit exceeded")]
ImplLimitExceeded,

View File

@@ -11,7 +11,7 @@
//!
//! # Example
//! ```
//! use cretonne_codegen::settings::{self, Configurable};
//! use cranelift_codegen::settings::{self, Configurable};
//!
//! let mut b = settings::builder();
//! b.set("opt_level", "fastest");

View File

@@ -41,11 +41,11 @@ define_passes!{
Pass, NUM_PASSES, DESCRIPTIONS;
process_file: "Processing test file",
parse_text: "Parsing textual Cretonne IR",
parse_text: "Parsing textual Cranelift IR",
wasm_translate_module: "Translate WASM module",
wasm_translate_function: "Translate WASM function",
verifier: "Verify Cretonne IR",
verifier: "Verify Cranelift IR",
verify_cssa: "Verify CSSA",
verify_liveness: "Verify live ranges",
verify_locations: "Verify value locations",

View File

@@ -11,7 +11,7 @@ use verifier::VerifierResult;
/// Verify conventional SSA form for `func`.
///
/// Conventional SSA form is represented in Cretonne with the help of virtual registers:
/// Conventional SSA form is represented in Cranelift with the help of virtual registers:
///
/// - Two values are said to be *PHI-related* if one is an EBB argument and the other is passed as
/// a branch argument in a location that matches the first value.

View File

@@ -1,7 +1,7 @@
//! Converting Cretonne IR to text.
//! Converting Cranelift IR to text.
//!
//! The `write` module provides the `write_function` function which converts an IR `Function` to an
//! equivalent textual form. This textual form can be read back by the `cretonne-reader` crate.
//! equivalent textual form. This textual form can be read back by the `cranelift-reader` crate.
use ir::{DataFlowGraph, Ebb, Function, Inst, SigRef, Type, Value, ValueDef};
use isa::{RegInfo, TargetIsa};