Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cranelift-filetests = { path = "lib/filetests", version = "0.22.0" }
cranelift-module = { path = "lib/module", version = "0.22.0" }
cranelift-faerie = { path = "lib/faerie", version = "0.22.0" }
cranelift-simplejit = { path = "lib/simplejit", version = "0.22.0" }
cranelift-preopt = { path = "lib/preopt", version = "0.22.0" }
cranelift = { path = "lib/umbrella", version = "0.22.0" }
filecheck = "0.4.0"
clap = "2.32.0"
Expand Down
54 changes: 54 additions & 0 deletions filetests/preopt/branch.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
test preopt
target x86_64

function %brz_fold() -> i32 {
ebb0:
v0 = bconst.b1 false
brz v0, ebb2
jump ebb1
ebb1:
v1 = iconst.i32 42
return v1
ebb2:
v2 = iconst.i32 24
return v2
}
; sameln: function %brz_fold
; nextln: ebb0:
; nextln: v0 = bconst.b1 false
; nextln: jump ebb2
; nextln:
; nextln: ebb1:
; nextln: v1 = iconst.i32 42
; nextln: return v1
; nextln:
; nextln: ebb2:
; nextln: v2 = iconst.i32 24
; nextln: return v2
; nextln: }

function %brnz_fold() -> i32 {
ebb0:
v0 = bconst.b1 true
brnz v0, ebb2
jump ebb1
ebb1:
v1 = iconst.i32 42
return v1
ebb2:
v2 = iconst.i32 24
return v2
}
; sameln: function %brnz_fold
; nextln: ebb0:
; nextln: v0 = bconst.b1 true
; nextln: jump ebb2
; nextln:
; nextln: ebb1:
; nextln: v1 = iconst.i32 42
; nextln: return v1
; nextln:
; nextln: ebb2:
; nextln: v2 = iconst.i32 24
; nextln: return v2
; nextln: }
36 changes: 36 additions & 0 deletions filetests/preopt/numerical.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
test preopt
target x86_64

function %iadd_fold() -> i32 {
ebb0:
v0 = iconst.i32 37
v1 = iconst.i32 5
v2 = iadd v0, v1
v3 = iconst.i32 8
v4 = iadd v2, v3
return v4
}
; sameln: function %iadd_fold
; nextln: ebb0:
; nextln: v0 = iconst.i32 37
; nextln: v1 = iconst.i32 5
; nextln: v2 = iconst.i32 42
; nextln: v3 = iconst.i32 8
; nextln: v4 = iconst.i32 50
; nextln: return v4
; nextln: }

function %isub_fold() -> i32 {
ebb0:
v0 = iconst.i32 42
v1 = iconst.i32 1
v2 = isub v0, v1
return v2
}
; sameln: function %isub_fold
; nextln: ebb0:
; nextln: v0 = iconst.i32 42
; nextln: v1 = iconst.i32 1
; nextln: v2 = iconst.i32 41
; nextln: return v2
; nextln: }
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test preopt
test simple_preopt
target i686 baseline

; Cases where the denominator is created by an iconst
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test preopt
test simple_preopt
target i686 baseline

; -------- U32 --------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test preopt
test simple_preopt
target i686 baseline

; -------- U32 --------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test preopt
test simple_preopt
target i686 baseline

; -------- U32 --------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test preopt
test simple_preopt
target i686 baseline

; -------- U32 --------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
test preopt
test simple_preopt
target i686

function %iadd_imm(i32) -> i32 {
Expand Down
2 changes: 1 addition & 1 deletion lib/codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ use licm::do_licm;
use loop_analysis::LoopAnalysis;
use nan_canonicalization::do_nan_canonicalization;
use postopt::do_postopt;
use preopt::do_preopt;
use regalloc;
use result::CodegenResult;
use settings::{FlagsOrIsa, OptLevel};
use simple_gvn::do_simple_gvn;
use simple_preopt::do_preopt;
use std::vec::Vec;
use timing;
use unreachable_code::eliminate_unreachable_code;
Expand Down
2 changes: 1 addition & 1 deletion lib/codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ mod nan_canonicalization;
mod partition_slice;
mod postopt;
mod predicates;
mod preopt;
mod ref_slice;
mod regalloc;
mod result;
mod scoped_hash_map;
mod simple_gvn;
mod simple_preopt;
mod stack_layout;
mod topo_order;
mod unreachable_code;
Expand Down
15 changes: 11 additions & 4 deletions lib/codegen/src/timing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ mod details {
}

/// Accumulated timing information for a single pass.
#[derive(Default)]
#[derive(Default, Copy, Clone)]
struct PassTime {
/// Total time spent running this pass including children.
total: Duration,
Expand All @@ -134,17 +134,24 @@ mod details {
}

/// Accumulated timing for all passes.
#[derive(Default)]
pub struct PassTimes {
pass: [PassTime; NUM_PASSES],
}

impl Default for PassTimes {
fn default() -> Self {
PassTimes {
pass: [Default::default(); NUM_PASSES],
}
}
}

impl fmt::Display for PassTimes {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "======== ======== ==================================")?;
writeln!(f, " Total Self Pass")?;
writeln!(f, "-------- -------- ----------------------------------")?;
for (time, desc) in self.pass.iter().zip(&DESCRIPTIONS) {
for (time, desc) in self.pass.iter().zip(&DESCRIPTIONS[..]) {
// Omit passes that haven't run.
if time.total == Duration::default() {
continue;
Expand Down Expand Up @@ -212,7 +219,7 @@ mod details {
/// Add `timings` to the accumulated timings for the current thread.
pub fn add_to_current(times: &PassTimes) {
PASS_TIME.with(|rc| {
for (a, b) in rc.borrow_mut().pass.iter_mut().zip(&times.pass) {
for (a, b) in rc.borrow_mut().pass.iter_mut().zip(&times.pass[..]) {
a.total += b.total;
a.child += b.child;
}
Expand Down
1 change: 1 addition & 0 deletions lib/filetests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ publish = false
[dependencies]
cranelift-codegen = { path = "../codegen", version = "0.22.0", features = ["testing_hooks"] }
cranelift-reader = { path = "../reader", version = "0.22.0" }
cranelift-preopt = { path = "../preopt", version = "0.22.0" }
file-per-thread-logger = "0.1.1"
filecheck = "0.4.0"
num_cpus = "1.8.0"
Expand Down
5 changes: 4 additions & 1 deletion lib/filetests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
)]

extern crate cranelift_codegen;
extern crate cranelift_preopt;
extern crate cranelift_reader;
extern crate file_per_thread_logger;
extern crate filecheck;
Expand Down Expand Up @@ -59,6 +60,7 @@ mod test_print_cfg;
mod test_regalloc;
mod test_shrink;
mod test_simple_gvn;
mod test_simple_preopt;
mod test_verifier;

/// The result of running the test in a file.
Expand Down Expand Up @@ -120,12 +122,13 @@ fn new_subtest(parsed: &TestCommand) -> subtest::SubtestResult<Box<subtest::SubT
"legalizer" => test_legalizer::subtest(parsed),
"licm" => test_licm::subtest(parsed),
"postopt" => test_postopt::subtest(parsed),
"preopt" => test_preopt::subtest(parsed),
"simple_preopt" => test_simple_preopt::subtest(parsed),
"print-cfg" => test_print_cfg::subtest(parsed),
"regalloc" => test_regalloc::subtest(parsed),
"shrink" => test_shrink::subtest(parsed),
"simple-gvn" => test_simple_gvn::subtest(parsed),
"verifier" => test_verifier::subtest(parsed),
"preopt" => test_preopt::subtest(parsed),
_ => Err(format!("unknown test command '{}'", parsed.command)),
}
}
18 changes: 12 additions & 6 deletions lib/filetests/src/test_preopt.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
//! Test command for testing the preopt pass.
//! Test command for testing the constant folding pass.
//!
//! The `dce` test command runs each function through the constant folding pass after ensuring
//! that all instructions are legal for the target.
//!
//! The resulting function is sent to `filecheck`.

use cranelift_codegen;
use cranelift_codegen::ir::Function;
use cranelift_codegen::print_errors::pretty_error;
use cranelift_preopt::optimize;
use cranelift_reader::TestCommand;
use std::borrow::Cow;
use subtest::{run_filecheck, Context, SubTest, SubtestResult};
Expand All @@ -29,16 +33,18 @@ impl SubTest for TestPreopt {
true
}

fn needs_isa(&self) -> bool {
true
}

fn run(&self, func: Cow<Function>, context: &Context) -> SubtestResult<()> {
let isa = context.isa.expect("compile needs an ISA");
let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned());
let isa = context.isa.expect("preopt needs an ISA");

comp_ctx.flowgraph();
comp_ctx
.preopt(isa)
optimize(&mut comp_ctx, isa)
.map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?;

let text = &comp_ctx.func.display(isa).to_string();
let text = comp_ctx.func.display(context.isa).to_string();
run_filecheck(&text, context)
}
}
44 changes: 44 additions & 0 deletions lib/filetests/src/test_simple_preopt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! Test command for testing the preopt pass.
//!
//! The resulting function is sent to `filecheck`.

use cranelift_codegen;
use cranelift_codegen::ir::Function;
use cranelift_codegen::print_errors::pretty_error;
use cranelift_reader::TestCommand;
use std::borrow::Cow;
use subtest::{run_filecheck, Context, SubTest, SubtestResult};

struct TestSimplePreopt;

pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
assert_eq!(parsed.command, "simple_preopt");
if !parsed.options.is_empty() {
Err(format!("No options allowed on {}", parsed))
} else {
Ok(Box::new(TestSimplePreopt))
}
}

impl SubTest for TestSimplePreopt {
fn name(&self) -> &'static str {
"simple_preopt"
}

fn is_mutating(&self) -> bool {
true
}

fn run(&self, func: Cow<Function>, context: &Context) -> SubtestResult<()> {
let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned());
let isa = context.isa.expect("preopt needs an ISA");

comp_ctx.flowgraph();
comp_ctx
.preopt(isa)
.map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?;

let text = &comp_ctx.func.display(isa).to_string();
run_filecheck(&text, context)
}
}
27 changes: 27 additions & 0 deletions lib/preopt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-preopt"
version = "0.22.0"
description = "Support for optimizations in Cranelift"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://cranelift.readthedocs.io/"
repository = "https://github.com/CraneStation/cranelift"
categories = ["no_std"]
readme = "README.md"
keywords = ["optimize", "compile", "compiler", "jit"]

[dependencies]
cranelift-codegen = { path = "../codegen", version = "0.22.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.22.0", default-features = false }
# This is commented out because it doesn't build on Rust 1.25.0, which
# cranelift currently supports.
# rustc_apfloat = { version = "0.1.2", default-features = false }

[features]
default = ["std"]
std = ["cranelift-codegen/std", "cranelift-entity/std"]
core = ["cranelift-codegen/core"]

[badges]
maintenance = { status = "experimental" }
travis-ci = { repository = "CraneStation/cranelift" }
Loading