Rename Cretonne to Cranelift!
This commit is contained in:
@@ -1,22 +1,22 @@
|
||||
[package]
|
||||
authors = ["The Cretonne Project Developers"]
|
||||
name = "cretonne-codegen"
|
||||
authors = ["The Cranelift Project Developers"]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.13.0"
|
||||
description = "Low-level code generator library"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
documentation = "https://cretonne.readthedocs.io/"
|
||||
repository = "https://github.com/cretonne/cretonne"
|
||||
documentation = "https://cranelift.readthedocs.io/"
|
||||
repository = "https://github.com/cranelift/cranelift"
|
||||
readme = "README.md"
|
||||
keywords = ["compile", "compiler", "jit"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
cretonne-entity = { path = "../entity", version = "0.13.0", default-features = false }
|
||||
cranelift-entity = { path = "../entity", version = "0.13.0", default-features = false }
|
||||
failure = { version = "0.1.1", default-features = false, features = ["derive"] }
|
||||
failure_derive = { version = "0.1.1", default-features = false }
|
||||
hashmap_core = { version = "0.1.8", optional = true }
|
||||
target-lexicon = { version = "0.0.2", default-features = false }
|
||||
# It is a goal of the cretonne-codegen crate to have minimal external dependencies.
|
||||
# It is a goal of the cranelift-codegen crate to have minimal external dependencies.
|
||||
# Please don't add any unless they are essential to the task of creating binary
|
||||
# machine code. Integration tests that need external dependencies can be
|
||||
# accomodated in `tests`.
|
||||
@@ -26,9 +26,9 @@ target-lexicon = { version = "0.0.2", default-features = false }
|
||||
# of some minimal std-like replacement libraries. At least one of these two
|
||||
# features need to be enabled.
|
||||
default = ["std"]
|
||||
std = ["cretonne-entity/std", "target-lexicon/std"]
|
||||
std = ["cranelift-entity/std", "target-lexicon/std"]
|
||||
core = ["hashmap_core"]
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "experimental" }
|
||||
travis-ci = { repository = "cretonne/cretonne" }
|
||||
travis-ci = { repository = "cranelift/cranelift" }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
This crate contains the core Cretonne code generator. It translates code from an
|
||||
This crate contains the core Cranelift code generator. It translates code from an
|
||||
intermediate representation into executable machine code.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// TARGET
|
||||
// Target triple provided by Cargo.
|
||||
//
|
||||
// CRETONNE_TARGETS (Optional)
|
||||
// CRANELIFT_TARGETS (Optional)
|
||||
// A setting for conditional compilation of isa targets. Possible values can be "native" or
|
||||
// known isa targets separated by ','.
|
||||
//
|
||||
@@ -24,12 +24,12 @@ use std::process;
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set");
|
||||
let target_triple = env::var("TARGET").expect("The TARGET environment variable must be set");
|
||||
let cretonne_targets = env::var("CRETONNE_TARGETS").ok();
|
||||
let cretonne_targets = cretonne_targets.as_ref().map(|s| s.as_ref());
|
||||
let cranelift_targets = env::var("CRANELIFT_TARGETS").ok();
|
||||
let cranelift_targets = cranelift_targets.as_ref().map(|s| s.as_ref());
|
||||
let python = identify_python();
|
||||
|
||||
// Configure isa targets cfg.
|
||||
match isa_targets(cretonne_targets, &target_triple) {
|
||||
match isa_targets(cranelift_targets, &target_triple) {
|
||||
Ok(isa_targets) => {
|
||||
for isa in &isa_targets {
|
||||
println!("cargo:rustc-cfg=build_{}", isa.name());
|
||||
@@ -84,7 +84,7 @@ fn identify_python() -> &'static str {
|
||||
return python;
|
||||
}
|
||||
}
|
||||
panic!("The Cretonne build requires Python (version 2.7 or version 3)");
|
||||
panic!("The Cranelift build requires Python (version 2.7 or version 3)");
|
||||
}
|
||||
|
||||
/// Represents known ISA target.
|
||||
@@ -142,8 +142,8 @@ impl Isa {
|
||||
}
|
||||
|
||||
/// Returns isa targets to configure conditional compilation.
|
||||
fn isa_targets(cretonne_targets: Option<&str>, target_triple: &str) -> Result<Vec<Isa>, String> {
|
||||
match cretonne_targets {
|
||||
fn isa_targets(cranelift_targets: Option<&str>, target_triple: &str) -> Result<Vec<Isa>, String> {
|
||||
match cranelift_targets {
|
||||
Some("native") => Isa::from_arch(target_triple.split('-').next().unwrap())
|
||||
.map(|isa| vec![isa])
|
||||
.ok_or_else(|| {
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Definitions for the base Cretonne language."""
|
||||
"""Definitions for the base Cranelift language."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
The `cretonne.entities` module predefines all the Cretonne entity reference
|
||||
operand types. There are corresponding definitions in the `cretonne.entities`
|
||||
The `cranelift.entities` module predefines all the Cranelift entity reference
|
||||
operand types. There are corresponding definitions in the `cranelift.entities`
|
||||
Rust module.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""
|
||||
The cretonne.formats defines all instruction formats.
|
||||
The cranelift.formats defines all instruction formats.
|
||||
|
||||
Every instruction format has a corresponding `InstructionData` variant in the
|
||||
Rust representation of Cretonne IR, so all instruction formats must be defined
|
||||
Rust representation of Cranelift IR, so all instruction formats must be defined
|
||||
in this module.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
The `cretonne.immediates` module predefines all the Cretonne immediate operand
|
||||
types.
|
||||
The `cranelift.immediates` module predefines all the Cranelift immediate
|
||||
operand types.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from cdsl.operands import ImmediateKind
|
||||
@@ -8,7 +8,7 @@ from cdsl.operands import ImmediateKind
|
||||
#: A 64-bit immediate integer operand.
|
||||
#:
|
||||
#: This type of immediate integer can interact with SSA values with any
|
||||
#: :py:class:`cretonne.IntType` type.
|
||||
#: :py:class:`cranelift.IntType` type.
|
||||
imm64 = ImmediateKind('imm64', 'A 64-bit immediate integer.')
|
||||
|
||||
#: An unsigned 8-bit immediate integer operand.
|
||||
@@ -42,13 +42,13 @@ ieee64 = ImmediateKind('ieee64', 'A 64-bit immediate floating point number.')
|
||||
#: An immediate boolean operand.
|
||||
#:
|
||||
#: This type of immediate boolean can interact with SSA values with any
|
||||
#: :py:class:`cretonne.BoolType` type.
|
||||
#: :py:class:`cranelift.BoolType` type.
|
||||
boolean = ImmediateKind('bool', 'An immediate boolean.',
|
||||
rust_type='bool')
|
||||
|
||||
#: A condition code for comparing integer values.
|
||||
#:
|
||||
#: This enumerated operand kind is used for the :cton:inst:`icmp` instruction
|
||||
#: This enumerated operand kind is used for the :clif:inst:`icmp` instruction
|
||||
#: and corresponds to the `condcodes::IntCC` Rust type.
|
||||
intcc = ImmediateKind(
|
||||
'intcc',
|
||||
@@ -70,7 +70,7 @@ intcc = ImmediateKind(
|
||||
|
||||
#: A condition code for comparing floating point values.
|
||||
#:
|
||||
#: This enumerated operand kind is used for the :cton:inst:`fcmp` instruction
|
||||
#: This enumerated operand kind is used for the :clif:inst:`fcmp` instruction
|
||||
#: and corresponds to the `condcodes::FloatCC` Rust type.
|
||||
floatcc = ImmediateKind(
|
||||
'floatcc',
|
||||
@@ -94,7 +94,7 @@ floatcc = ImmediateKind(
|
||||
'uge': 'UnorderedOrGreaterThanOrEqual',
|
||||
})
|
||||
|
||||
#: Flags for memory operations like :cton:inst:`load` and :cton:inst:`store`.
|
||||
#: Flags for memory operations like :clif:inst:`load` and :clif:inst:`store`.
|
||||
memflags = ImmediateKind(
|
||||
'memflags',
|
||||
'Memory operation flags',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Cretonne base instruction set.
|
||||
Cranelift base instruction set.
|
||||
|
||||
This module defines the basic Cretonne instruction set that all targets
|
||||
This module defines the basic Cranelift instruction set that all targets
|
||||
support.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
@@ -1524,8 +1524,8 @@ fdiv = Instruction(
|
||||
'fdiv', r"""
|
||||
Floating point division.
|
||||
|
||||
Unlike the integer division instructions :cton:inst:`sdiv` and
|
||||
:cton:inst:`udiv`, this can't trap. Division by zero is infinity or
|
||||
Unlike the integer division instructions :clif:inst:`sdiv` and
|
||||
:clif:inst:`udiv`, this can't trap. Division by zero is infinity or
|
||||
NaN, depending on the dividend.
|
||||
""",
|
||||
ins=(x, y), outs=a)
|
||||
@@ -1800,7 +1800,7 @@ fpromote = Instruction(
|
||||
Each lane in `x` is converted to the destination floating point format.
|
||||
This is an exact operation.
|
||||
|
||||
Cretonne currently only supports two floating point formats
|
||||
Cranelift currently only supports two floating point formats
|
||||
- :type:`f32` and :type:`f64`. This may change in the future.
|
||||
|
||||
The result type must have the same number of vector lanes as the input,
|
||||
@@ -1816,7 +1816,7 @@ fdemote = Instruction(
|
||||
Each lane in `x` is converted to the destination floating point format
|
||||
by rounding to nearest, ties to even.
|
||||
|
||||
Cretonne currently only supports two floating point formats
|
||||
Cranelift currently only supports two floating point formats
|
||||
- :type:`f32` and :type:`f64`. This may change in the future.
|
||||
|
||||
The result type must have the same number of vector lanes as the input,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Patterns for legalizing the `base` instruction set.
|
||||
|
||||
The base Cretonne instruction set is 'fat', and many instructions don't have
|
||||
The base Cranelift instruction set is 'fat', and many instructions don't have
|
||||
legal representations in a given target ISA. This module defines legalization
|
||||
patterns that describe how base instructions can be transformed to other base
|
||||
instructions that are legal.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Cretonne predicates that consider `Function` fields.
|
||||
Cranelift predicates that consider `Function` fields.
|
||||
"""
|
||||
from cdsl.predicates import FieldPredicate
|
||||
from .formats import UnaryGlobalValue, InstructionFormat
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Cretonne shared settings.
|
||||
Cranelift shared settings.
|
||||
|
||||
This module defines settings relevant for all code generators.
|
||||
"""
|
||||
@@ -20,10 +20,10 @@ opt_level = EnumSetting(
|
||||
|
||||
enable_verifier = BoolSetting(
|
||||
"""
|
||||
Run the Cretonne IR verifier at strategic times during compilation.
|
||||
Run the Cranelift IR verifier at strategic times during compilation.
|
||||
|
||||
This makes compilation slower but catches many bugs. The verifier is
|
||||
disabled by default, except when reading Cretonne IR from a text file.
|
||||
disabled by default, except when reading Cranelift IR from a text file.
|
||||
""",
|
||||
default=True)
|
||||
|
||||
@@ -51,8 +51,8 @@ call_conv = EnumSetting(
|
||||
'probestack'
|
||||
)
|
||||
|
||||
# Note that Cretonne doesn't currently need an is_pie flag, because PIE is just
|
||||
# PIC where symbols can't be pre-empted, which can be expressed with the
|
||||
# Note that Cranelift doesn't currently need an is_pie flag, because PIE is
|
||||
# just PIC where symbols can't be pre-empted, which can be expressed with the
|
||||
# `colocated` flag on external functions and global values.
|
||||
is_pic = BoolSetting("Enable Position-Independent Code generation")
|
||||
|
||||
@@ -126,7 +126,7 @@ baldrdash_prologue_words = NumSetting(
|
||||
in the epilogue.
|
||||
|
||||
This setting configures the number of pointer-sized words pushed on the
|
||||
stack when the Cretonne-generated code is entered. This includes the
|
||||
stack when the Cranelift-generated code is entered. This includes the
|
||||
pushed return address on x86.
|
||||
""")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
The base.types module predefines all the Cretonne scalar types.
|
||||
The base.types module predefines all the Cranelift scalar types.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from cdsl.types import IntType, FloatType, BoolType, FlagsType
|
||||
|
||||
@@ -18,7 +18,7 @@ import gen_binemit
|
||||
def main():
|
||||
# type: () -> None
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate sources for Cretonne.')
|
||||
description='Generate sources for Cranelift.')
|
||||
parser.add_argument('--out-dir', help='set output directory')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Cretonne DSL classes.
|
||||
Cranelift DSL classes.
|
||||
|
||||
This module defines the classes that are used to define Cretonne instructions
|
||||
This module defines the classes that are used to define Cranelift instructions
|
||||
and other entitties.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Abstract syntax trees.
|
||||
|
||||
This module defines classes that can be used to create abstract syntax trees
|
||||
for patern matching an rewriting of cretonne instructions.
|
||||
for patern matching an rewriting of cranelift instructions.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from . import instructions
|
||||
|
||||
@@ -50,7 +50,7 @@ class InstructionFormat(object):
|
||||
of values.
|
||||
|
||||
All instruction formats must be predefined in the
|
||||
:py:mod:`cretonne.formats` module.
|
||||
:py:mod:`cranelift.formats` module.
|
||||
|
||||
:param kinds: List of `OperandKind` objects describing the operands.
|
||||
:param name: Instruction format name in CamelCase. This is used as a Rust
|
||||
|
||||
@@ -67,7 +67,7 @@ VARIABLE_ARGS = OperandKind(
|
||||
|
||||
|
||||
# Instances of immediate operand types are provided in the
|
||||
# `cretonne.immediates` module.
|
||||
# `cranelift.immediates` module.
|
||||
class ImmediateKind(OperandKind):
|
||||
"""
|
||||
The kind of an immediate instruction operand.
|
||||
@@ -152,7 +152,7 @@ class ImmediateKind(OperandKind):
|
||||
|
||||
|
||||
# Instances of entity reference operand types are provided in the
|
||||
# `cretonne.entities` module.
|
||||
# `cranelift.entities` module.
|
||||
class EntityRefKind(OperandKind):
|
||||
"""
|
||||
The kind of an entity reference instruction operand.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Cretonne predicates.
|
||||
Cranelift predicates.
|
||||
|
||||
A *predicate* is a function that computes a boolean result. The inputs to the
|
||||
function determine the kind of predicate:
|
||||
|
||||
@@ -14,7 +14,7 @@ except ImportError:
|
||||
|
||||
class Setting(object):
|
||||
"""
|
||||
A named setting variable that can be configured externally to Cretonne.
|
||||
A named setting variable that can be configured externally to Cranelift.
|
||||
|
||||
Settings are normally not named when they are created. They get their name
|
||||
from the `extract_names` method.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Cretonne ValueType hierarchy"""
|
||||
"""Cranelift ValueType hierarchy"""
|
||||
from __future__ import absolute_import
|
||||
import math
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Type variables for Parametric polymorphism.
|
||||
|
||||
Cretonne instructions and instruction transformations can be specified to be
|
||||
Cranelift instructions and instruction transformations can be specified to be
|
||||
polymorphic by using type variables.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Generate legalizer transformations.
|
||||
|
||||
The transformations defined in the `cretonne.legalize` module are all of the
|
||||
The transformations defined in the `cranelift.legalize` module are all of the
|
||||
macro-expansion form where the input pattern is a single instruction. We
|
||||
generate a Rust function for each `XFormGroup` which takes a `Cursor` pointing
|
||||
at the instruction to be legalized. The expanded destination pattern replaces
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""
|
||||
Cretonne target ISA definitions
|
||||
-------------------------------
|
||||
Cranelift target ISA definitions
|
||||
--------------------------------
|
||||
|
||||
The :py:mod:`isa` package contains sub-packages for each target instruction set
|
||||
architecture supported by Cretonne.
|
||||
architecture supported by Cranelift.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from cdsl.isa import TargetISA # noqa
|
||||
@@ -19,6 +19,6 @@ def all_isas():
|
||||
# type: () -> List[TargetISA]
|
||||
"""
|
||||
Get a list of all the supported target ISAs. Each target ISA is represented
|
||||
as a :py:class:`cretonne.TargetISA` instance.
|
||||
as a :py:class:`cranelift.TargetISA` instance.
|
||||
"""
|
||||
return [riscv.ISA, x86.ISA, arm32.ISA, arm64.ISA]
|
||||
|
||||
@@ -61,7 +61,7 @@ RV32.enc(base.iconst.i32, Iz, OPIMM(0b000))
|
||||
RV64.enc(base.iconst.i32, Iz, OPIMM(0b000))
|
||||
RV64.enc(base.iconst.i64, Iz, OPIMM(0b000))
|
||||
|
||||
# Dynamic shifts have the same masking semantics as the cton base instructions.
|
||||
# Dynamic shifts have the same masking semantics as the clif base instructions.
|
||||
for inst, inst_imm, f3, f7 in [
|
||||
(base.ishl, base.ishl_imm, 0b001, 0b0000000),
|
||||
(base.ushr, base.ushr_imm, 0b101, 0b0000000),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"""
|
||||
x86 Target Architecture
|
||||
-------------------------
|
||||
-----------------------
|
||||
|
||||
This target ISA generates code for x86 CPUs with two separate CPU modes:
|
||||
|
||||
`I32`
|
||||
32-bit x86 architecture, also known as 'IA-32', also sometimes referred
|
||||
to as 'i386', however note that Cretonne depends on instructions not
|
||||
to as 'i386', however note that Cranelift depends on instructions not
|
||||
in the original `i386`, such as SSE2, CMOVcc, and UD2.
|
||||
|
||||
`I64`
|
||||
|
||||
@@ -34,7 +34,7 @@ except ImportError:
|
||||
|
||||
# Opcode representation.
|
||||
#
|
||||
# Cretonne requires each recipe to have a single encoding size in bytes, and
|
||||
# Cranelift requires each recipe to have a single encoding size in bytes, and
|
||||
# x86 opcodes are variable length, so we use separate recipes for different
|
||||
# styles of opcodes and prefixes. The opcode format is indicated by the recipe
|
||||
# name prefix:
|
||||
@@ -1600,7 +1600,7 @@ rcmp_sp = TailRecipe(
|
||||
#
|
||||
# 1. Guarantee that the test and branch get scheduled next to each other so
|
||||
# macro fusion is guaranteed to be possible.
|
||||
# 2. Hide the status flags from Cretonne which doesn't currently model flags.
|
||||
# 2. Hide the status flags from Cranelift which doesn't currently model flags.
|
||||
#
|
||||
# The encoding bits affect both the test and the branch instruction:
|
||||
#
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Definitions for the semantics segment of the Cretonne language."""
|
||||
"""Definitions for the semantics segment of the Cranelift language."""
|
||||
from cdsl.ti import TypeEnv, ti_rtl, get_type_env
|
||||
from cdsl.operands import ImmediateKind
|
||||
from cdsl.ast import Var
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Tools to elaborate a given Rtl with concrete types into its semantically
|
||||
equivalent primitive version. Its elaborated primitive version contains only
|
||||
primitive cretonne instructions, which map well to SMTLIB functions.
|
||||
primitive cranelift instructions, which map well to SMTLIB functions.
|
||||
"""
|
||||
from .primitives import GROUP as PRIMITIVES, prim_to_bv, prim_from_bv
|
||||
from cdsl.xform import Rtl
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Cretonne primitive instruction set.
|
||||
Cranelift primitive instruction set.
|
||||
|
||||
This module defines a primitive instruction set, in terms of which the base set
|
||||
is described. Most instructions in this set correspond 1-1 with an SMTLIB
|
||||
@@ -26,9 +26,9 @@ y = Operand('x', BV, doc="A semantic value Y (same width as X)")
|
||||
a = Operand('a', BV, doc="A semantic value A (same width as X)")
|
||||
cond = Operand('b', TypeVar.singleton(b1), doc='A b1 value')
|
||||
|
||||
real = Operand('real', Real, doc="A real cretonne value")
|
||||
real = Operand('real', Real, doc="A real cranelift value")
|
||||
fromReal = Operand('fromReal', Real.to_bitvec(),
|
||||
doc="A real cretonne value converted to a BV")
|
||||
doc="A real cranelift value converted to a BV")
|
||||
|
||||
#
|
||||
# BV Conversion/Materialization
|
||||
|
||||
@@ -186,14 +186,16 @@ def equivalent(r1, r2, inp_m, out_m):
|
||||
(q1, m1) = to_smt(r1)
|
||||
(q2, m2) = to_smt(r2)
|
||||
|
||||
# Build an expression for the equality of real Cretone inputs of r1 and r2
|
||||
# Build an expression for the equality of real Cranelift inputs of
|
||||
# r1 and r2
|
||||
args_eq_exp = [] # type: List[ExprRef]
|
||||
|
||||
for (v1, v2) in inp_m.items():
|
||||
assert isinstance(v2, Var)
|
||||
args_eq_exp.append(mk_eq(m1[v1], m2[v2]))
|
||||
|
||||
# Build an expression for the equality of real Cretone outputs of r1 and r2
|
||||
# Build an expression for the equality of real Cranelift outputs of
|
||||
# r1 and r2
|
||||
results_eq_exp = [] # type: List[ExprRef]
|
||||
for (v1, v2) in out_m.items():
|
||||
assert isinstance(v2, Var)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
//!
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Representation of Cretonne IR functions.
|
||||
//! Representation of Cranelift IR functions.
|
||||
|
||||
mod builder;
|
||||
pub mod condcodes;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
//!
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
/// ```
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
//!
|
||||
|
||||
@@ -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.
|
||||
//!
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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};
|
||||
|
||||
Reference in New Issue
Block a user