Have FunctionBuilder clear the ILBuilder's state in its drop().
This commit is contained in:
@@ -11,6 +11,10 @@ use ssa::{SSABuilder, SideEffects, Block};
|
|||||||
use cretonne::entity::{EntityRef, EntityMap, EntitySet};
|
use cretonne::entity::{EntityRef, EntityMap, EntitySet};
|
||||||
|
|
||||||
/// Permanent structure used for translating into Cretonne IL.
|
/// Permanent structure used for translating into Cretonne IL.
|
||||||
|
///
|
||||||
|
/// In order to reduce memory reallocations whem compiling multiple functions,
|
||||||
|
/// `ILBuilder` holds various data structures which are cleared between
|
||||||
|
/// functions, rather than dropped, preserving the underlying allocations.
|
||||||
pub struct ILBuilder<Variable>
|
pub struct ILBuilder<Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef + Default,
|
Variable: EntityRef + Default,
|
||||||
@@ -55,8 +59,8 @@ impl<Variable> ILBuilder<Variable>
|
|||||||
where
|
where
|
||||||
Variable: EntityRef + Default,
|
Variable: EntityRef + Default,
|
||||||
{
|
{
|
||||||
/// Creates a ILBuilder structure. The structure is automatically cleared each time it is
|
/// Creates a ILBuilder structure. The structure is automatically cleared after each
|
||||||
/// passed to a [`FunctionBuilder`](struct.FunctionBuilder.html) for creation.
|
/// [`FunctionBuilder`](struct.FunctionBuilder.html) completes translating a function.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
ssa: SSABuilder::new(),
|
ssa: SSABuilder::new(),
|
||||||
@@ -72,6 +76,11 @@ where
|
|||||||
self.types.clear();
|
self.types.clear();
|
||||||
self.function_args_values.clear();
|
self.function_args_values.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.ssa.is_empty() && self.ebbs.is_empty() && self.types.is_empty() &&
|
||||||
|
self.function_args_values.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of the [`InstBuilder`](../cretonne/ir/builder/trait.InstBuilder.html) that has
|
/// Implementation of the [`InstBuilder`](../cretonne/ir/builder/trait.InstBuilder.html) that has
|
||||||
@@ -216,7 +225,7 @@ where
|
|||||||
func: &'a mut Function,
|
func: &'a mut Function,
|
||||||
builder: &'a mut ILBuilder<Variable>,
|
builder: &'a mut ILBuilder<Variable>,
|
||||||
) -> FunctionBuilder<'a, Variable> {
|
) -> FunctionBuilder<'a, Variable> {
|
||||||
builder.clear();
|
debug_assert!(builder.is_empty());
|
||||||
FunctionBuilder {
|
FunctionBuilder {
|
||||||
func: func,
|
func: func,
|
||||||
srcloc: Default::default(),
|
srcloc: Default::default(),
|
||||||
@@ -491,15 +500,19 @@ where
|
|||||||
Variable: EntityRef + Default,
|
Variable: EntityRef + Default,
|
||||||
{
|
{
|
||||||
/// When a `FunctionBuilder` goes out of scope, it means that the function is fully built.
|
/// When a `FunctionBuilder` goes out of scope, it means that the function is fully built.
|
||||||
/// We then proceed to check if all the `Ebb`s are filled and sealed
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
// Check that all the `Ebb`s are filled and sealed.
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.builder.ebbs.keys().all(|ebb| {
|
self.builder.ebbs.keys().all(|ebb| {
|
||||||
self.builder.ebbs[ebb].pristine ||
|
self.builder.ebbs[ebb].pristine ||
|
||||||
(self.builder.ssa.is_sealed(ebb) && self.builder.ebbs[ebb].filled)
|
(self.builder.ssa.is_sealed(ebb) && self.builder.ebbs[ebb].filled)
|
||||||
}),
|
}),
|
||||||
"all blocks should be filled and sealed before dropping a FunctionBuilder"
|
"all blocks should be filled and sealed before dropping a FunctionBuilder"
|
||||||
)
|
);
|
||||||
|
|
||||||
|
// Clear the state (but preserve the allocated buffers) in preparation
|
||||||
|
// for translation another function.
|
||||||
|
self.builder.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,13 @@ where
|
|||||||
debug_assert!(self.results.is_empty());
|
debug_assert!(self.results.is_empty());
|
||||||
debug_assert!(self.side_effects.is_empty());
|
debug_assert!(self.side_effects.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests whether an `SSABuilder` is in a cleared state.
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.variables.is_empty() && self.blocks.is_empty() && self.ebb_headers.is_empty() &&
|
||||||
|
self.calls.is_empty() &&
|
||||||
|
self.results.is_empty() && self.side_effects.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Small enum used for clarity in some functions.
|
// Small enum used for clarity in some functions.
|
||||||
|
|||||||
Reference in New Issue
Block a user