diff --git a/Cargo.lock b/Cargo.lock index bb3d43101b..a5c941a1b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -599,7 +599,6 @@ dependencies = [ "cranelift-jit", "cranelift-module", "cranelift-native", - "cranelift-preopt", "cranelift-reader", "cranelift-wasm", "file-per-thread-logger", @@ -713,13 +712,6 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "cranelift-preopt" -version = "0.93.0" -dependencies = [ - "cranelift-codegen", -] - [[package]] name = "cranelift-reader" version = "0.93.0" @@ -758,7 +750,6 @@ dependencies = [ "cranelift-module", "cranelift-native", "cranelift-object", - "cranelift-preopt", "cranelift-reader", "cranelift-wasm", "filecheck", diff --git a/Cargo.toml b/Cargo.toml index c37359a72f..f02ac04fc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,7 +150,6 @@ cranelift-reader = { path = "cranelift/reader", version = "0.93.0" } cranelift-filetests = { path = "cranelift/filetests" } cranelift-object = { path = "cranelift/object", version = "0.93.0" } cranelift-jit = { path = "cranelift/jit", version = "0.93.0" } -cranelift-preopt = { path = "cranelift/preopt", version = "0.93.0" } cranelift-fuzzgen = { path = "cranelift/fuzzgen" } cranelift-bforest = { path = "cranelift/bforest", version = "0.93.0" } cranelift = { path = "cranelift/umbrella", version = "0.93.0" } diff --git a/cranelift/Cargo.toml b/cranelift/Cargo.toml index a34d6a6396..0dff273f87 100644 --- a/cranelift/Cargo.toml +++ b/cranelift/Cargo.toml @@ -31,7 +31,6 @@ cranelift-filetests = { workspace = true } cranelift-module = { workspace = true } cranelift-object = { workspace = true } cranelift-jit = { workspace = true } -cranelift-preopt = { workspace = true } cranelift = { workspace = true } filecheck = "0.5.0" log = { workspace = true } diff --git a/cranelift/codegen/src/simple_preopt.rs b/cranelift/codegen/src/simple_preopt.rs index 41b5e7d706..c8925ab413 100644 --- a/cranelift/codegen/src/simple_preopt.rs +++ b/cranelift/codegen/src/simple_preopt.rs @@ -1,8 +1,7 @@ //! A pre-legalization rewriting pass. //! //! This module provides early-stage optimizations. The optimizations found -//! should be useful for already well-optimized code. More general purpose -//! early-stage optimizations can be found in the preopt crate. +//! should be useful for already well-optimized code. use crate::cursor::{Cursor, FuncCursor}; use crate::divconst_magic_numbers::{magic_s32, magic_s64, magic_u32, magic_u64}; diff --git a/cranelift/docs/testing.md b/cranelift/docs/testing.md index fdc3339b8c..1ed87424f1 100644 --- a/cranelift/docs/testing.md +++ b/cranelift/docs/testing.md @@ -262,7 +262,7 @@ Test the instruction shrinking pass. The shrink pass is run on each function, and then results are run through filecheck. -### `test preopt` +### `test simple_preopt` Test the preopt pass. diff --git a/cranelift/filetests/Cargo.toml b/cranelift/filetests/Cargo.toml index 9af750b6ab..123c27ac30 100644 --- a/cranelift/filetests/Cargo.toml +++ b/cranelift/filetests/Cargo.toml @@ -15,7 +15,6 @@ cranelift-frontend = { workspace = true } cranelift-interpreter = { workspace = true } cranelift-native = { workspace = true } cranelift-reader = { workspace = true } -cranelift-preopt = { workspace = true } cranelift-jit = { workspace = true, features = ["selinux-fix"] } cranelift-module = { workspace = true } file-per-thread-logger = "0.1.2" diff --git a/cranelift/filetests/filetests/preopt/branch.clif b/cranelift/filetests/filetests/preopt/branch.clif deleted file mode 100644 index a39810973c..0000000000 --- a/cranelift/filetests/filetests/preopt/branch.clif +++ /dev/null @@ -1,80 +0,0 @@ -test preopt -target aarch64 -target x86_64 - -function %brz_fold() -> i32 { -block0: - v0 = iconst.i8 0 - brz v0, block2 - jump block1 -block1: - v1 = iconst.i32 42 - return v1 -block2: - v2 = iconst.i32 24 - return v2 -} -; sameln: function %brz_fold -; nextln: block0: -; nextln: v0 = iconst.i8 0 -; nextln: jump block2 -; nextln: -; nextln: block1: -; nextln: v1 = iconst.i32 42 -; nextln: return v1 -; nextln: -; nextln: block2: -; nextln: v2 = iconst.i32 24 -; nextln: return v2 -; nextln: } - -function %brnz_fold() -> i32 { -block0: - v0 = iconst.i8 1 - brnz v0, block2 - jump block1 -block1: - v1 = iconst.i32 42 - return v1 -block2: - v2 = iconst.i32 24 - return v2 -} -; sameln: function %brnz_fold -; nextln: block0: -; nextln: v0 = iconst.i8 1 -; nextln: jump block2 -; nextln: -; nextln: block1: -; nextln: v1 = iconst.i32 42 -; nextln: return v1 -; nextln: -; nextln: block2: -; nextln: v2 = iconst.i32 24 -; nextln: return v2 -; nextln: } - -function %brz_fold_param(i8) -> i32 { -block0(v0: i8): - brz v0, block2 - jump block1 -block1: - v1 = iconst.i32 42 - return v1 -block2: - v2 = iconst.i32 24 - return v2 -} -; sameln: function %brz_fold_param(i8) -> i32 fast { -; nextln: block0(v0: i8): -; nextln: brz v0, block2 -; nextln: jump block1 -; nextln: -; nextln: block1: -; nextln: v1 = iconst.i32 42 -; nextln: return v1 -; nextln: -; nextln: block2: -; nextln: v2 = iconst.i32 24 -; nextln: return v2 -; nextln: } diff --git a/cranelift/filetests/filetests/preopt/constant_fold.clif b/cranelift/filetests/filetests/preopt/constant_fold.clif deleted file mode 100644 index 6d90187199..0000000000 --- a/cranelift/filetests/filetests/preopt/constant_fold.clif +++ /dev/null @@ -1,20 +0,0 @@ -test preopt -target aarch64 -target x86_64 - -function %constant_fold(f64) -> f64 { -block0(v0: f64): - v1 = f64const 0x1.0000000000000p0 - v2 = f64const 0x1.0000000000000p1 - v3 = fadd v1, v2 - v4 = fadd v3, v0 - return v4 -} -; sameln: function %constant_fold(f64) -> f64 fast { -; nextln: block0(v0: f64): -; nextln: v1 = f64const 0x1.0000000000000p0 -; nextln: v2 = f64const 0x1.0000000000000p1 -; nextln: v3 = f64const 0x1.8000000000000p1 -; nextln: v4 = fadd v3, v0 -; nextln: return v4 -; nextln: } diff --git a/cranelift/filetests/filetests/preopt/numerical.clif b/cranelift/filetests/filetests/preopt/numerical.clif deleted file mode 100644 index 6ab642a550..0000000000 --- a/cranelift/filetests/filetests/preopt/numerical.clif +++ /dev/null @@ -1,37 +0,0 @@ -test preopt -target aarch64 -target x86_64 - -function %iadd_fold() -> i32 { -block0: - 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: block0: -; 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 { -block0: - v0 = iconst.i32 42 - v1 = iconst.i32 1 - v2 = isub v0, v1 - return v2 -} -; sameln: function %isub_fold -; nextln: block0: -; nextln: v0 = iconst.i32 42 -; nextln: v1 = iconst.i32 1 -; nextln: v2 = iconst.i32 41 -; nextln: return v2 -; nextln: } diff --git a/cranelift/filetests/src/lib.rs b/cranelift/filetests/src/lib.rs index bf69547969..7fb7d44b35 100644 --- a/cranelift/filetests/src/lib.rs +++ b/cranelift/filetests/src/lib.rs @@ -45,7 +45,6 @@ mod test_interpret; mod test_legalizer; mod test_licm; mod test_optimize; -mod test_preopt; mod test_print_cfg; mod test_run; mod test_safepoint; @@ -122,7 +121,6 @@ fn new_subtest(parsed: &TestCommand) -> anyhow::Result "legalizer" => test_legalizer::subtest(parsed), "licm" => test_licm::subtest(parsed), "optimize" => test_optimize::subtest(parsed), - "preopt" => test_preopt::subtest(parsed), "print-cfg" => test_print_cfg::subtest(parsed), "run" => test_run::subtest(parsed), "safepoint" => test_safepoint::subtest(parsed), diff --git a/cranelift/filetests/src/test_preopt.rs b/cranelift/filetests/src/test_preopt.rs deleted file mode 100644 index b9d9e9d60c..0000000000 --- a/cranelift/filetests/src/test_preopt.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! 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 crate::subtest::{run_filecheck, Context, SubTest}; -use cranelift_codegen; -use cranelift_codegen::ir::Function; -use cranelift_preopt::optimize; -use cranelift_reader::TestCommand; -use std::borrow::Cow; - -struct TestPreopt; - -pub fn subtest(parsed: &TestCommand) -> anyhow::Result> { - assert_eq!(parsed.command, "preopt"); - if !parsed.options.is_empty() { - anyhow::bail!("No options allowed on {}", parsed); - } - Ok(Box::new(TestPreopt)) -} - -impl SubTest for TestPreopt { - fn name(&self) -> &'static str { - "preopt" - } - - fn is_mutating(&self) -> bool { - true - } - - fn needs_isa(&self) -> bool { - true - } - - fn run(&self, func: Cow, context: &Context) -> anyhow::Result<()> { - let isa = context.isa.expect("compile needs an ISA"); - let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned()); - - optimize(&mut comp_ctx, isa) - .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, Into::into(e)))?; - - let text = comp_ctx.func.display().to_string(); - run_filecheck(&text, context) - } -} diff --git a/cranelift/preopt/Cargo.toml b/cranelift/preopt/Cargo.toml deleted file mode 100644 index d0c3427680..0000000000 --- a/cranelift/preopt/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -authors = ["The Cranelift Project Developers"] -name = "cranelift-preopt" -version = "0.93.0" -description = "Support for optimizations in Cranelift" -license = "Apache-2.0 WITH LLVM-exception" -documentation = "https://docs.rs/cranelift-preopt" -repository = "https://github.com/bytecodealliance/wasmtime" -categories = ["no-std"] -readme = "README.md" -keywords = ["optimize", "compile", "compiler", "jit"] -edition.workspace = true - -[dependencies] -cranelift-codegen = { workspace = true } -# 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"] -core = ["cranelift-codegen/core"] - -[badges] -maintenance = { status = "experimental" } diff --git a/cranelift/preopt/LICENSE b/cranelift/preopt/LICENSE deleted file mode 100644 index f9d81955f4..0000000000 --- a/cranelift/preopt/LICENSE +++ /dev/null @@ -1,220 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ---- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - diff --git a/cranelift/preopt/README.md b/cranelift/preopt/README.md deleted file mode 100644 index 1c4f04dc64..0000000000 --- a/cranelift/preopt/README.md +++ /dev/null @@ -1 +0,0 @@ -This crate performs early-stage optimizations on [Cranelift](https://crates.io/crates/cranelift) IR. diff --git a/cranelift/preopt/src/constant_folding.rs b/cranelift/preopt/src/constant_folding.rs deleted file mode 100644 index ca11d44b8d..0000000000 --- a/cranelift/preopt/src/constant_folding.rs +++ /dev/null @@ -1,253 +0,0 @@ -//! Fold operations on constants at compile time. -#![allow(clippy::float_arithmetic)] - -use cranelift_codegen::{ - cursor::{Cursor, FuncCursor}, - ir::{self, dfg::ValueDef, instructions::Opcode, types, InstBuilder}, -}; -// use rustc_apfloat::{ -// ieee::{Double, Single}, -// Float, -// }; - -enum ConstImm { - I64(i64), - Ieee32(f32), // Ieee32 and Ieee64 will be replaced with `Single` and `Double` from the rust_apfloat library eventually. - Ieee64(f64), -} - -impl ConstImm { - fn unwrap_i64(self) -> i64 { - if let Self::I64(imm) = self { - imm - } else { - panic!("self did not contain an `i64`.") - } - } - - fn evaluate_truthiness(self) -> bool { - match self { - Self::I64(imm) => imm != 0, - _ => panic!( - "Only a `ConstImm::Bool` and `ConstImm::I64` can be evaluated for \"truthiness\"" - ), - } - } -} - -/// Fold operations on constants. -/// -/// It's important to note that this will not remove unused constants. It's -/// assumed that the DCE pass will take care of them. -pub fn fold_constants(func: &mut ir::Function) { - let mut pos = FuncCursor::new(func); - - while let Some(_block) = pos.next_block() { - while let Some(inst) = pos.next_inst() { - use self::ir::InstructionData::*; - match pos.func.dfg.insts[inst] { - Binary { opcode, args } => { - fold_binary(&mut pos.func.dfg, inst, opcode, args); - } - Unary { opcode, arg } => { - fold_unary(&mut pos.func.dfg, inst, opcode, arg); - } - Branch { - opcode, - arg, - destination, - } => { - fold_branch(&mut pos, inst, opcode, arg, destination); - } - _ => {} - } - } - } -} - -fn resolve_value_to_imm(dfg: &ir::DataFlowGraph, value: ir::Value) -> Option { - let original = dfg.resolve_aliases(value); - - let inst = match dfg.value_def(original) { - ValueDef::Result(inst, _) => inst, - ValueDef::Param(_, _) => return None, - ValueDef::Union(_, _) => return None, - }; - - use self::ir::{InstructionData::*, Opcode::*}; - match dfg.insts[inst] { - UnaryImm { - opcode: Iconst, - imm, - } => Some(ConstImm::I64(imm.into())), - UnaryIeee32 { - opcode: F32const, - imm, - } => { - // See https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits for caveats. - let ieee_f32 = f32::from_bits(imm.bits()); - Some(ConstImm::Ieee32(ieee_f32)) - } - UnaryIeee64 { - opcode: F64const, - imm, - } => { - // See https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits for caveats. - let ieee_f64 = f64::from_bits(imm.bits()); - Some(ConstImm::Ieee64(ieee_f64)) - } - _ => None, - } -} - -fn evaluate_binary(opcode: ir::Opcode, imm0: ConstImm, imm1: ConstImm) -> Option { - use core::num::Wrapping; - - match opcode { - ir::Opcode::Iadd => { - let imm0 = Wrapping(imm0.unwrap_i64()); - let imm1 = Wrapping(imm1.unwrap_i64()); - Some(ConstImm::I64((imm0 + imm1).0)) - } - ir::Opcode::Isub => { - let imm0 = Wrapping(imm0.unwrap_i64()); - let imm1 = Wrapping(imm1.unwrap_i64()); - Some(ConstImm::I64((imm0 - imm1).0)) - } - ir::Opcode::Imul => { - let imm0 = Wrapping(imm0.unwrap_i64()); - let imm1 = Wrapping(imm1.unwrap_i64()); - Some(ConstImm::I64((imm0 * imm1).0)) - } - ir::Opcode::Udiv => { - let imm0 = Wrapping(imm0.unwrap_i64()); - let imm1 = Wrapping(imm1.unwrap_i64()); - if imm1.0 == 0 { - panic!("Cannot divide by a zero.") - } - Some(ConstImm::I64((imm0 / imm1).0)) - } - ir::Opcode::Fadd => match (imm0, imm1) { - (ConstImm::Ieee32(imm0), ConstImm::Ieee32(imm1)) => Some(ConstImm::Ieee32(imm0 + imm1)), - (ConstImm::Ieee64(imm0), ConstImm::Ieee64(imm1)) => Some(ConstImm::Ieee64(imm0 + imm1)), - _ => unreachable!(), - }, - ir::Opcode::Fsub => match (imm0, imm1) { - (ConstImm::Ieee32(imm0), ConstImm::Ieee32(imm1)) => Some(ConstImm::Ieee32(imm0 - imm1)), - (ConstImm::Ieee64(imm0), ConstImm::Ieee64(imm1)) => Some(ConstImm::Ieee64(imm0 - imm1)), - _ => unreachable!(), - }, - ir::Opcode::Fmul => match (imm0, imm1) { - (ConstImm::Ieee32(imm0), ConstImm::Ieee32(imm1)) => Some(ConstImm::Ieee32(imm0 * imm1)), - (ConstImm::Ieee64(imm0), ConstImm::Ieee64(imm1)) => Some(ConstImm::Ieee64(imm0 * imm1)), - _ => unreachable!(), - }, - ir::Opcode::Fdiv => match (imm0, imm1) { - (ConstImm::Ieee32(imm0), ConstImm::Ieee32(imm1)) => Some(ConstImm::Ieee32(imm0 / imm1)), - (ConstImm::Ieee64(imm0), ConstImm::Ieee64(imm1)) => Some(ConstImm::Ieee64(imm0 / imm1)), - _ => unreachable!(), - }, - _ => None, - } -} - -fn evaluate_unary(opcode: ir::Opcode, imm: ConstImm) -> Option { - match opcode { - ir::Opcode::Fneg => match imm { - ConstImm::Ieee32(imm) => Some(ConstImm::Ieee32(-imm)), - ConstImm::Ieee64(imm) => Some(ConstImm::Ieee64(-imm)), - _ => unreachable!(), - }, - ir::Opcode::Fabs => match imm { - ConstImm::Ieee32(imm) => Some(ConstImm::Ieee32(imm.abs())), - ConstImm::Ieee64(imm) => Some(ConstImm::Ieee64(imm.abs())), - _ => unreachable!(), - }, - _ => None, - } -} - -fn replace_inst(dfg: &mut ir::DataFlowGraph, inst: ir::Inst, const_imm: ConstImm) { - use self::ConstImm::*; - match const_imm { - I64(imm) => { - let typevar = dfg.ctrl_typevar(inst); - dfg.replace(inst).iconst(typevar, imm); - } - Ieee32(imm) => { - dfg.replace(inst) - .f32const(ir::immediates::Ieee32::with_bits(imm.to_bits())); - } - Ieee64(imm) => { - dfg.replace(inst) - .f64const(ir::immediates::Ieee64::with_bits(imm.to_bits())); - } - } -} - -/// Fold a binary instruction. -fn fold_binary( - dfg: &mut ir::DataFlowGraph, - inst: ir::Inst, - opcode: ir::Opcode, - args: [ir::Value; 2], -) { - let (imm0, imm1) = if let (Some(imm0), Some(imm1)) = ( - resolve_value_to_imm(dfg, args[0]), - resolve_value_to_imm(dfg, args[1]), - ) { - (imm0, imm1) - } else { - return; - }; - - if let Some(const_imm) = evaluate_binary(opcode, imm0, imm1) { - replace_inst(dfg, inst, const_imm); - } -} - -/// Fold a unary instruction. -fn fold_unary(dfg: &mut ir::DataFlowGraph, inst: ir::Inst, opcode: ir::Opcode, arg: ir::Value) { - let imm = if let Some(imm) = resolve_value_to_imm(dfg, arg) { - imm - } else { - return; - }; - - if let Some(const_imm) = evaluate_unary(opcode, imm) { - replace_inst(dfg, inst, const_imm); - } -} - -fn fold_branch( - pos: &mut FuncCursor, - inst: ir::Inst, - opcode: ir::Opcode, - cond: ir::Value, - block: ir::BlockCall, -) { - let cond = match resolve_value_to_imm(&pos.func.dfg, cond) { - Some(imm) => imm, - None => return, - }; - - let truthiness = cond.evaluate_truthiness(); - let branch_if_zero = match opcode { - ir::Opcode::Brz => true, - ir::Opcode::Brnz => false, - _ => unreachable!(), - }; - - if (branch_if_zero && !truthiness) || (!branch_if_zero && truthiness) { - pos.func - .dfg - .replace(inst) - .Jump(Opcode::Jump, types::INVALID, block); - // remove the rest of the block to avoid verifier errors - while let Some(next_inst) = pos.func.layout.next_inst(inst) { - pos.func.layout.remove_inst(next_inst); - } - } else { - pos.remove_inst_and_step_back(); - } -} diff --git a/cranelift/preopt/src/lib.rs b/cranelift/preopt/src/lib.rs deleted file mode 100644 index bb24d75254..0000000000 --- a/cranelift/preopt/src/lib.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! Performs early-stage optimizations on Cranelift IR. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr(feature = "std", deny(unstable_features))] -#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] -#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] -#![no_std] - -mod constant_folding; - -use cranelift_codegen::{isa::TargetIsa, settings::FlagsOrIsa, CodegenResult, Context}; - -/// Optimize the function with available optimizations. -/// -/// Since this can be resource intensive (and code-size inflating), -/// it is separated from `Context::compile` to allow DCE to remove it -/// if it's not used. -pub fn optimize(ctx: &mut Context, isa: &dyn TargetIsa) -> CodegenResult<()> { - ctx.verify_if(isa)?; - fold_constants(ctx, isa)?; - - Ok(()) -} - -/// Fold constants -pub fn fold_constants<'a, FOI>(ctx: &mut Context, fisa: FOI) -> CodegenResult<()> -where - FOI: Into>, -{ - constant_folding::fold_constants(&mut ctx.func); - ctx.verify_if(fisa)?; - Ok(()) -} diff --git a/scripts/publish.rs b/scripts/publish.rs index 1de6f94bee..7e78c72c16 100644 --- a/scripts/publish.rs +++ b/scripts/publish.rs @@ -29,7 +29,6 @@ const CRATES_TO_PUBLISH: &[&str] = &[ "cranelift-reader", "cranelift-serde", "cranelift-module", - "cranelift-preopt", "cranelift-frontend", "cranelift-wasm", "cranelift-native", @@ -99,7 +98,6 @@ const PUBLIC_CRATES: &[&str] = &[ "cranelift-reader", "cranelift-serde", "cranelift-module", - "cranelift-preopt", "cranelift-frontend", "cranelift-wasm", "cranelift-native",