Issue better error messages in use_var and def_var.
Include the name of the variable when diagnosing uses and defs of undeclared variables. And, add an assert to def_var to check that the declared type of a variable matches the value type of the def. With this change, `Variable` implementations must now implement `Debug`.
This commit is contained in:
@@ -10,6 +10,7 @@ use cretonne_codegen::ir::{DataFlowGraph, Ebb, ExtFuncData, FuncRef, Function, G
|
|||||||
use cretonne_codegen::isa::TargetIsa;
|
use cretonne_codegen::isa::TargetIsa;
|
||||||
use cretonne_codegen::packed_option::PackedOption;
|
use cretonne_codegen::packed_option::PackedOption;
|
||||||
use ssa::{Block, SSABuilder, SideEffects};
|
use ssa::{Block, SSABuilder, SideEffects};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// Structure used for translating a series of functions into Cretonne IR.
|
/// Structure used for translating a series of functions into Cretonne IR.
|
||||||
///
|
///
|
||||||
@@ -22,7 +23,7 @@ use ssa::{Block, SSABuilder, SideEffects};
|
|||||||
/// use here, `variable::Variable` can be used.
|
/// use here, `variable::Variable` can be used.
|
||||||
pub struct FunctionBuilderContext<Variable>
|
pub struct FunctionBuilderContext<Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
ssa: SSABuilder<Variable>,
|
ssa: SSABuilder<Variable>,
|
||||||
ebbs: EntityMap<Ebb, EbbData>,
|
ebbs: EntityMap<Ebb, EbbData>,
|
||||||
@@ -32,7 +33,7 @@ where
|
|||||||
/// Temporary object used to build a single Cretonne IR `Function`.
|
/// Temporary object used to build a single Cretonne IR `Function`.
|
||||||
pub struct FunctionBuilder<'a, Variable: 'a>
|
pub struct FunctionBuilder<'a, Variable: 'a>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
/// The function currently being built.
|
/// The function currently being built.
|
||||||
/// This field is public so the function can be re-borrowed.
|
/// This field is public so the function can be re-borrowed.
|
||||||
@@ -79,7 +80,7 @@ impl Position {
|
|||||||
|
|
||||||
impl<Variable> FunctionBuilderContext<Variable>
|
impl<Variable> FunctionBuilderContext<Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
/// Creates a FunctionBuilderContext structure. The structure is automatically cleared after
|
/// Creates a FunctionBuilderContext structure. The structure is automatically cleared after
|
||||||
/// each [`FunctionBuilder`](struct.FunctionBuilder.html) completes translating a function.
|
/// each [`FunctionBuilder`](struct.FunctionBuilder.html) completes translating a function.
|
||||||
@@ -106,7 +107,7 @@ where
|
|||||||
/// one convenience method per Cretonne IR instruction.
|
/// one convenience method per Cretonne IR instruction.
|
||||||
pub struct FuncInstBuilder<'short, 'long: 'short, Variable: 'long>
|
pub struct FuncInstBuilder<'short, 'long: 'short, Variable: 'long>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
builder: &'short mut FunctionBuilder<'long, Variable>,
|
builder: &'short mut FunctionBuilder<'long, Variable>,
|
||||||
ebb: Ebb,
|
ebb: Ebb,
|
||||||
@@ -114,7 +115,7 @@ where
|
|||||||
|
|
||||||
impl<'short, 'long, Variable> FuncInstBuilder<'short, 'long, Variable>
|
impl<'short, 'long, Variable> FuncInstBuilder<'short, 'long, Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
fn new<'s, 'l>(
|
fn new<'s, 'l>(
|
||||||
builder: &'s mut FunctionBuilder<'l, Variable>,
|
builder: &'s mut FunctionBuilder<'l, Variable>,
|
||||||
@@ -126,7 +127,7 @@ where
|
|||||||
|
|
||||||
impl<'short, 'long, Variable> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long, Variable>
|
impl<'short, 'long, Variable> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long, Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
fn data_flow_graph(&self) -> &DataFlowGraph {
|
fn data_flow_graph(&self) -> &DataFlowGraph {
|
||||||
&self.builder.func.dfg
|
&self.builder.func.dfg
|
||||||
@@ -228,7 +229,7 @@ where
|
|||||||
/// return instruction with arguments that don't match the function's signature.
|
/// return instruction with arguments that don't match the function's signature.
|
||||||
impl<'a, Variable> FunctionBuilder<'a, Variable>
|
impl<'a, Variable> FunctionBuilder<'a, Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
/// Creates a new FunctionBuilder structure that will operate on a `Function` using a
|
/// Creates a new FunctionBuilder structure that will operate on a `Function` using a
|
||||||
/// `FunctionBuilderContext`.
|
/// `FunctionBuilderContext`.
|
||||||
@@ -316,22 +317,40 @@ where
|
|||||||
/// Returns the Cretonne IR value corresponding to the utilization at the current program
|
/// Returns the Cretonne IR value corresponding to the utilization at the current program
|
||||||
/// position of a previously defined user variable.
|
/// position of a previously defined user variable.
|
||||||
pub fn use_var(&mut self, var: Variable) -> Value {
|
pub fn use_var(&mut self, var: Variable) -> Value {
|
||||||
let ty = *self.func_ctx.types.get(var).expect(
|
let (val, side_effects) = {
|
||||||
"this variable is used but its type has not been declared",
|
let ty = *self.func_ctx.types.get(var).unwrap_or_else(|| {
|
||||||
);
|
panic!(
|
||||||
let (val, side_effects) = self.func_ctx.ssa.use_var(
|
"variable {:?} is used but its type has not been declared",
|
||||||
|
var
|
||||||
|
)
|
||||||
|
});
|
||||||
|
self.func_ctx.ssa.use_var(
|
||||||
self.func,
|
self.func,
|
||||||
var,
|
var,
|
||||||
ty,
|
ty,
|
||||||
self.position.basic_block.unwrap(),
|
self.position.basic_block.unwrap(),
|
||||||
);
|
)
|
||||||
|
};
|
||||||
self.handle_ssa_side_effects(side_effects);
|
self.handle_ssa_side_effects(side_effects);
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a new definition of a user variable. Panics if the type of the value is not the
|
/// Register a new definition of a user variable. The type of the value must be
|
||||||
/// same as the type registered for the variable.
|
/// the same as the type registered for the variable.
|
||||||
pub fn def_var(&mut self, var: Variable, val: Value) {
|
pub fn def_var(&mut self, var: Variable, val: Value) {
|
||||||
|
debug_assert_eq!(
|
||||||
|
*self.func_ctx.types.get(var).unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"variable {:?} is used but its type has not been declared",
|
||||||
|
var
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
self.func.dfg.value_type(val),
|
||||||
|
"declared type of variable {:?} doesn't match type of value {}",
|
||||||
|
var,
|
||||||
|
val
|
||||||
|
);
|
||||||
|
|
||||||
self.func_ctx.ssa.def_var(
|
self.func_ctx.ssa.def_var(
|
||||||
var,
|
var,
|
||||||
val,
|
val,
|
||||||
@@ -470,7 +489,7 @@ where
|
|||||||
/// in ways that can be unsafe if used incorrectly.
|
/// in ways that can be unsafe if used incorrectly.
|
||||||
impl<'a, Variable> FunctionBuilder<'a, Variable>
|
impl<'a, Variable> FunctionBuilder<'a, Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
/// Retrieves all the parameters for an `Ebb` currently inferred from the jump instructions
|
/// Retrieves all the parameters for an `Ebb` currently inferred from the jump instructions
|
||||||
/// inserted that target it and the SSA construction.
|
/// inserted that target it and the SSA construction.
|
||||||
@@ -560,7 +579,7 @@ where
|
|||||||
// Helper functions
|
// Helper functions
|
||||||
impl<'a, Variable> FunctionBuilder<'a, Variable>
|
impl<'a, Variable> FunctionBuilder<'a, Variable>
|
||||||
where
|
where
|
||||||
Variable: EntityRef,
|
Variable: EntityRef + Debug,
|
||||||
{
|
{
|
||||||
fn move_to_next_basic_block(&mut self) {
|
fn move_to_next_basic_block(&mut self) {
|
||||||
self.position.basic_block = PackedOption::from(self.func_ctx.ssa.declare_ebb_body_block(
|
self.position.basic_block = PackedOption::from(self.func_ctx.ssa.declare_ebb_body_block(
|
||||||
|
|||||||
Reference in New Issue
Block a user