From 9128290fb4fe73104b9a48e3986b28e0d6f8f0cb Mon Sep 17 00:00:00 2001 From: Afnan Enayet Date: Wed, 14 Mar 2018 10:48:06 -0700 Subject: [PATCH] Rename `ILBuilder` to `FunctionBuilderContext` (#268) * Rename `ILBuilder` to `FunctionBuilderContext` and update corresponding code * Refactor usages of ILBuilder to become FunctionBuilderContext, update variable names to reflect this change * Reformat to ensure that lines stay under 100 char limit * Apply corrections from `rustfmt` to pass tests * Rename variables to be more consistent with refactor of ILBuilder --- lib/frontend/src/frontend.rs | 103 ++++++++++++++++---------------- lib/frontend/src/lib.rs | 14 ++--- lib/frontend/src/variable.rs | 2 +- lib/wasm/src/func_translator.rs | 10 ++-- 4 files changed, 65 insertions(+), 64 deletions(-) diff --git a/lib/frontend/src/frontend.rs b/lib/frontend/src/frontend.rs index 6802884b6a..de89698f15 100644 --- a/lib/frontend/src/frontend.rs +++ b/lib/frontend/src/frontend.rs @@ -13,13 +13,13 @@ use cretonne::packed_option::PackedOption; /// Structure used for translating a series of functions into Cretonne IL. /// /// In order to reduce memory reallocations when compiling multiple functions, -/// `ILBuilder` holds various data structures which are cleared between +/// `FunctionBuilderContext` holds various data structures which are cleared between /// functions, rather than dropped, preserving the underlying allocations. /// /// The `Variable` parameter can be any index-like type that can be made to /// implement `EntityRef`. For frontends that don't have an obvious type to /// use here, `variable::Variable` can be used. -pub struct ILBuilder +pub struct FunctionBuilderContext where Variable: EntityRef, { @@ -41,7 +41,7 @@ where /// Source location to assign to all new instructions. srcloc: ir::SourceLoc, - builder: &'a mut ILBuilder, + func_ctx: &'a mut FunctionBuilderContext, position: Position, } @@ -77,12 +77,12 @@ impl Position { } } -impl ILBuilder +impl FunctionBuilderContext where Variable: EntityRef, { - /// Creates a ILBuilder structure. The structure is automatically cleared after each - /// [`FunctionBuilder`](struct.FunctionBuilder.html) completes translating a function. + /// Creates a FunctionBuilderContext structure. The structure is automatically cleared after + /// each [`FunctionBuilder`](struct.FunctionBuilder.html) completes translating a function. pub fn new() -> Self { Self { ssa: SSABuilder::new(), @@ -172,7 +172,7 @@ impl<'short, 'long, Variable> InstBuilderBase<'short> for FuncInstBuilder<'short .entries() .map(|(_, ebb)| ebb) .filter(|dest_ebb| unique.insert(*dest_ebb)) { - self.builder.builder.ssa.declare_ebb_predecessor( + self.builder.func_ctx.ssa.declare_ebb_predecessor( dest_ebb, self.builder.position.basic_block.unwrap(), inst, @@ -213,9 +213,10 @@ impl<'short, 'long, Variable> InstBuilderBase<'short> for FuncInstBuilder<'short /// /// At creation, a `FunctionBuilder` instance borrows an already allocated `Function` which it /// modifies with the information stored in the mutable borrowed -/// [`ILBuilder`](struct.ILBuilder.html). The function passed in argument should be newly created -/// with [`Function::with_name_signature()`](../function/struct.Function.html), whereas the -/// `ILBuilder` can be kept as is between two function translations. +/// [`FunctionBuilderContext`](struct.FunctionBuilderContext.html). The function passed in +/// argument should be newly created with +/// [`Function::with_name_signature()`](../function/struct.Function.html), whereas the +/// `FunctionBuilderContext` can be kept as is between two function translations. /// /// # Errors /// @@ -228,16 +229,16 @@ where Variable: EntityRef, { /// Creates a new FunctionBuilder structure that will operate on a `Function` using a - /// `IlBuilder`. + /// `FunctionBuilderContext`. pub fn new( func: &'a mut Function, - builder: &'a mut ILBuilder, + func_ctx: &'a mut FunctionBuilderContext, ) -> FunctionBuilder<'a, Variable> { - debug_assert!(builder.is_empty()); + debug_assert!(func_ctx.is_empty()); FunctionBuilder { func: func, srcloc: Default::default(), - builder: builder, + func_ctx: func_ctx, position: Position::default(), } } @@ -250,8 +251,8 @@ where /// Creates a new `Ebb` and returns its reference. pub fn create_ebb(&mut self) -> Ebb { let ebb = self.func.dfg.make_ebb(); - self.builder.ssa.declare_ebb_header_block(ebb); - self.builder.ebbs[ebb] = EbbData { + self.func_ctx.ssa.declare_ebb_header_block(ebb); + self.func_ctx.ebbs[ebb] = EbbData { filled: false, pristine: true, user_param_count: 0, @@ -275,11 +276,11 @@ where ); // We cannot switch to a filled block debug_assert!( - !self.builder.ebbs[ebb].filled, + !self.func_ctx.ebbs[ebb].filled, "you cannot switch to a block which is already filled" ); - let basic_block = self.builder.ssa.header_block(ebb); + let basic_block = self.func_ctx.ssa.header_block(ebb); // Then we change the cursor position. self.position = Position::at(ebb, basic_block); } @@ -290,7 +291,7 @@ where /// created. Forgetting to call this method on every block will cause inconsistencies in the /// produced functions. pub fn seal_block(&mut self, ebb: Ebb) { - let side_effects = self.builder.ssa.seal_ebb_header_block(ebb, self.func); + let side_effects = self.func_ctx.ssa.seal_ebb_header_block(ebb, self.func); self.handle_ssa_side_effects(side_effects); } @@ -301,22 +302,22 @@ where /// function can be used at the end of translating all blocks to ensure /// that everything is sealed. pub fn seal_all_blocks(&mut self) { - let side_effects = self.builder.ssa.seal_all_ebb_header_blocks(self.func); + let side_effects = self.func_ctx.ssa.seal_all_ebb_header_blocks(self.func); self.handle_ssa_side_effects(side_effects); } /// In order to use a variable in a `use_var`, you need to declare its type with this method. pub fn declare_var(&mut self, var: Variable, ty: Type) { - self.builder.types[var] = ty; + self.func_ctx.types[var] = ty; } /// Returns the Cretonne IL value corresponding to the utilization at the current program /// position of a previously defined user variable. pub fn use_var(&mut self, var: Variable) -> Value { - let ty = *self.builder.types.get(var).expect( + let ty = *self.func_ctx.types.get(var).expect( "this variable is used but its type has not been declared", ); - let (val, side_effects) = self.builder.ssa.use_var( + let (val, side_effects) = self.func_ctx.ssa.use_var( self.func, var, ty, @@ -329,7 +330,7 @@ where /// Register a new definition of a user variable. Panics if the type of the value is not the /// same as the type registered for the variable. pub fn def_var(&mut self, var: Variable, val: Value) { - self.builder.ssa.def_var( + self.func_ctx.ssa.def_var( var, val, self.position.basic_block.unwrap(), @@ -382,14 +383,14 @@ where /// Make sure that the current EBB is inserted in the layout. pub fn ensure_inserted_ebb(&mut self) { let ebb = self.position.ebb.unwrap(); - if self.builder.ebbs[ebb].pristine { + if self.func_ctx.ebbs[ebb].pristine { if !self.func.layout.is_ebb_inserted(ebb) { self.func.layout.append_ebb(ebb); } - self.builder.ebbs[ebb].pristine = false; + self.func_ctx.ebbs[ebb].pristine = false; } else { debug_assert!( - !self.builder.ebbs[ebb].filled, + !self.func_ctx.ebbs[ebb].filled, "you cannot add an instruction to a block already filled" ); } @@ -412,7 +413,7 @@ where pub fn append_ebb_params_for_function_params(&mut self, ebb: Ebb) { // These parameters count as "user" parameters here because they aren't // inserted by the SSABuilder. - let user_param_count = &mut self.builder.ebbs[ebb].user_param_count; + let user_param_count = &mut self.func_ctx.ebbs[ebb].user_param_count; for argtyp in &self.func.signature.params { *user_param_count += 1; self.func.dfg.append_ebb_param(ebb, argtyp.value_type); @@ -425,7 +426,7 @@ where pub fn append_ebb_params_for_function_returns(&mut self, ebb: Ebb) { // These parameters count as "user" parameters here because they aren't // inserted by the SSABuilder. - let user_param_count = &mut self.builder.ebbs[ebb].user_param_count; + let user_param_count = &mut self.func_ctx.ebbs[ebb].user_param_count; for argtyp in &self.func.signature.returns { *user_param_count += 1; self.func.dfg.append_ebb_param(ebb, argtyp.value_type); @@ -438,21 +439,21 @@ where pub fn finalize(&mut self) { // Check that all the `Ebb`s are filled and sealed. debug_assert!( - self.builder.ebbs.keys().all(|ebb| { - self.builder.ebbs[ebb].pristine || self.builder.ssa.is_sealed(ebb) + self.func_ctx.ebbs.keys().all(|ebb| { + self.func_ctx.ebbs[ebb].pristine || self.func_ctx.ssa.is_sealed(ebb) }), "all blocks should be sealed before dropping a FunctionBuilder" ); debug_assert!( - self.builder.ebbs.keys().all(|ebb| { - self.builder.ebbs[ebb].pristine || self.builder.ebbs[ebb].filled + self.func_ctx.ebbs.keys().all(|ebb| { + self.func_ctx.ebbs[ebb].pristine || self.func_ctx.ebbs[ebb].filled }), "all blocks should be filled before dropping a FunctionBuilder" ); // Clear the state (but preserve the allocated buffers) in preparation // for translation another function. - self.builder.clear(); + self.func_ctx.clear(); // Reset srcloc and position to initial states. self.srcloc = Default::default(); @@ -486,12 +487,12 @@ where /// **Note:** this function has to be called at the creation of the `Ebb` before adding /// instructions to it, otherwise this could interfere with SSA construction. pub fn append_ebb_param(&mut self, ebb: Ebb, ty: Type) -> Value { - debug_assert!(self.builder.ebbs[ebb].pristine); + debug_assert!(self.func_ctx.ebbs[ebb].pristine); debug_assert_eq!( - self.builder.ebbs[ebb].user_param_count, + self.func_ctx.ebbs[ebb].user_param_count, self.func.dfg.num_ebb_params(ebb) ); - self.builder.ebbs[ebb].user_param_count += 1; + self.func_ctx.ebbs[ebb].user_param_count += 1; self.func.dfg.append_ebb_param(ebb, ty) } @@ -508,9 +509,9 @@ where let old_dest = self.func.dfg[inst].branch_destination_mut().expect( "you want to change the jump destination of a non-jump instruction", ); - let pred = self.builder.ssa.remove_ebb_predecessor(*old_dest, inst); + let pred = self.func_ctx.ssa.remove_ebb_predecessor(*old_dest, inst); *old_dest = new_dest; - self.builder.ssa.declare_ebb_predecessor( + self.func_ctx.ssa.declare_ebb_predecessor( new_dest, pred, inst, @@ -525,8 +526,8 @@ where None => false, Some(entry) => self.position.ebb.unwrap() == entry, }; - !is_entry && self.builder.ssa.is_sealed(self.position.ebb.unwrap()) && - self.builder + !is_entry && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap()) && + self.func_ctx .ssa .predecessors(self.position.ebb.unwrap()) .is_empty() @@ -535,13 +536,13 @@ where /// Returns `true` if and only if no instructions have been added since the last call to /// `switch_to_block`. pub fn is_pristine(&self) -> bool { - self.builder.ebbs[self.position.ebb.unwrap()].pristine + self.func_ctx.ebbs[self.position.ebb.unwrap()].pristine } /// Returns `true` if and only if a terminator instruction has been inserted since the /// last call to `switch_to_block`. pub fn is_filled(&self) -> bool { - self.builder.ebbs[self.position.ebb.unwrap()].filled + self.func_ctx.ebbs[self.position.ebb.unwrap()].filled } /// Returns a displayable object for the function as it is. @@ -558,17 +559,17 @@ where Variable: EntityRef, { fn move_to_next_basic_block(&mut self) { - self.position.basic_block = PackedOption::from(self.builder.ssa.declare_ebb_body_block( + self.position.basic_block = PackedOption::from(self.func_ctx.ssa.declare_ebb_body_block( self.position.basic_block.unwrap(), )); } fn fill_current_block(&mut self) { - self.builder.ebbs[self.position.ebb.unwrap()].filled = true; + self.func_ctx.ebbs[self.position.ebb.unwrap()].filled = true; } fn declare_successor(&mut self, dest_ebb: Ebb, jump_inst: Inst) { - self.builder.ssa.declare_ebb_predecessor( + self.func_ctx.ssa.declare_ebb_predecessor( dest_ebb, self.position.basic_block.unwrap(), jump_inst, @@ -577,10 +578,10 @@ where fn handle_ssa_side_effects(&mut self, side_effects: SideEffects) { for split_ebb in side_effects.split_ebbs_created { - self.builder.ebbs[split_ebb].filled = true + self.func_ctx.ebbs[split_ebb].filled = true } for modified_ebb in side_effects.instructions_added_to_ebbs { - self.builder.ebbs[modified_ebb].pristine = false + self.func_ctx.ebbs[modified_ebb].pristine = false } } } @@ -591,7 +592,7 @@ mod tests { use cretonne::entity::EntityRef; use cretonne::ir::{ExternalName, Function, CallConv, Signature, AbiParam, InstBuilder}; use cretonne::ir::types::*; - use frontend::{ILBuilder, FunctionBuilder}; + use frontend::{FunctionBuilderContext, FunctionBuilder}; use cretonne::verifier::verify_function; use cretonne::settings; use Variable; @@ -601,10 +602,10 @@ mod tests { sig.returns.push(AbiParam::new(I32)); sig.params.push(AbiParam::new(I32)); - let mut il_builder = ILBuilder::::new(); + let mut fn_ctx = FunctionBuilderContext::::new(); let mut func = Function::with_name_signature(ExternalName::testcase("sample"), sig); { - let mut builder = FunctionBuilder::::new(&mut func, &mut il_builder); + let mut builder = FunctionBuilder::::new(&mut func, &mut fn_ctx); let block0 = builder.create_ebb(); let block1 = builder.create_ebb(); diff --git a/lib/frontend/src/lib.rs b/lib/frontend/src/lib.rs index a95d662893..f5b4514e56 100644 --- a/lib/frontend/src/lib.rs +++ b/lib/frontend/src/lib.rs @@ -4,8 +4,8 @@ //! translated from another language. Contains an SSA construction module that lets you translate //! your non-SSA variables into SSA Cretonne IL values via `use_var` and `def_var` calls. //! -//! To get started, create an [`IlBuilder`](struct.ILBuilder.html) and pass it as an argument -//! to a [`FunctionBuilder`](struct.FunctionBuilder.html). +//! To get started, create an [`FunctionBuilderContext`](struct.FunctionBuilderContext.html) and +//! pass it as an argument to a [`FunctionBuilder`](struct.FunctionBuilder.html). //! //! # Example //! @@ -29,7 +29,7 @@ //! } //! ``` //! -//! Here is how you build the corresponding Cretonne IL function using `ILBuilder`: +//! Here is how you build the corresponding Cretonne IL function using `FunctionBuilderContext`: //! //! ```rust //! extern crate cretonne; @@ -39,17 +39,17 @@ //! use cretonne::ir::{ExternalName, CallConv, Function, Signature, AbiParam, InstBuilder}; //! use cretonne::ir::types::*; //! use cretonne::settings; -//! use cton_frontend::{ILBuilder, FunctionBuilder, Variable}; +//! use cton_frontend::{FunctionBuilderContext, FunctionBuilder, Variable}; //! use cretonne::verifier::verify_function; //! //! fn main() { //! let mut sig = Signature::new(CallConv::Native); //! sig.returns.push(AbiParam::new(I32)); //! sig.params.push(AbiParam::new(I32)); -//! let mut il_builder = ILBuilder::::new(); +//! let mut fn_builder_ctx = FunctionBuilderContext::::new(); //! let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig); //! { -//! let mut builder = FunctionBuilder::::new(&mut func, &mut il_builder); +//! let mut builder = FunctionBuilder::::new(&mut func, &mut fn_builder_ctx); //! //! let block0 = builder.create_ebb(); //! let block1 = builder.create_ebb(); @@ -133,7 +133,7 @@ extern crate cretonne; -pub use frontend::{ILBuilder, FunctionBuilder}; +pub use frontend::{FunctionBuilderContext, FunctionBuilder}; pub use variable::Variable; mod frontend; diff --git a/lib/frontend/src/variable.rs b/lib/frontend/src/variable.rs index b69a63afeb..b4e3c75da2 100644 --- a/lib/frontend/src/variable.rs +++ b/lib/frontend/src/variable.rs @@ -1,6 +1,6 @@ //! A basic `Variable` implementation. //! -//! `ILBuilder`, `FunctionBuilder`, and related types have a `Variable` +//! `FunctionBuilderContext`, `FunctionBuilder`, and related types have a `Variable` //! type parameter, to allow frontends that identify variables with //! their own index types to use them directly. Frontends which don't //! can use the `Variable` defined here. diff --git a/lib/wasm/src/func_translator.rs b/lib/wasm/src/func_translator.rs index cef629c7dc..5ac69b07b8 100644 --- a/lib/wasm/src/func_translator.rs +++ b/lib/wasm/src/func_translator.rs @@ -9,7 +9,7 @@ use cretonne::entity::EntityRef; use cretonne::ir::{self, InstBuilder, Ebb}; use cretonne::result::{CtonResult, CtonError}; use cretonne::timing; -use cton_frontend::{ILBuilder, FunctionBuilder, Variable}; +use cton_frontend::{FunctionBuilderContext, FunctionBuilder, Variable}; use environ::FuncEnvironment; use state::TranslationState; use wasmparser::{self, BinaryReader}; @@ -20,7 +20,7 @@ use wasmparser::{self, BinaryReader}; /// by a `FuncEnvironment` object. A single translator instance can be reused to translate multiple /// functions which will reduce heap allocation traffic. pub struct FuncTranslator { - il_builder: ILBuilder, + func_ctx: FunctionBuilderContext, state: TranslationState, } @@ -28,7 +28,7 @@ impl FuncTranslator { /// Create a new translator. pub fn new() -> Self { Self { - il_builder: ILBuilder::new(), + func_ctx: FunctionBuilderContext::new(), state: TranslationState::new(), } } @@ -77,8 +77,8 @@ impl FuncTranslator { debug_assert_eq!(func.dfg.num_ebbs(), 0, "Function must be empty"); debug_assert_eq!(func.dfg.num_insts(), 0, "Function must be empty"); - // This clears the `ILBuilder`. - let mut builder = FunctionBuilder::new(func, &mut self.il_builder); + // This clears the `FunctionBuilderContext`. + let mut builder = FunctionBuilder::new(func, &mut self.func_ctx); let entry_block = builder.create_ebb(); builder.append_ebb_params_for_function_params(entry_block); builder.switch_to_block(entry_block); // This also creates values for the arguments.