Rewrite EBB and value references after parsing.
We llow forward references to values and EBBs, so it is not possible to rewrite these from the source domain to the in-memory domain during parsing. Instead go through all the instructions after parsing everything and rewrite the value and EBB references when everything has been created and mapped.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use entities::*;
|
||||
use immediates::*;
|
||||
@@ -230,6 +231,21 @@ impl VariableArgs {
|
||||
}
|
||||
}
|
||||
|
||||
// Coerce VariableArgs into a &[Value] slice.
|
||||
impl Deref for VariableArgs {
|
||||
type Target = [Value];
|
||||
|
||||
fn deref<'a>(&'a self) -> &'a [Value] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for VariableArgs {
|
||||
fn deref_mut<'a>(&'a mut self) -> &'a mut [Value] {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for VariableArgs {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
try!(write!(fmt, "("));
|
||||
@@ -294,7 +310,7 @@ pub struct CallData {
|
||||
second_result: Value,
|
||||
|
||||
// Dynamically sized array containing call argument values.
|
||||
arguments: VariableArgs,
|
||||
pub arguments: VariableArgs,
|
||||
}
|
||||
|
||||
impl Display for CallData {
|
||||
|
||||
@@ -101,10 +101,6 @@ impl Function {
|
||||
inst
|
||||
}
|
||||
|
||||
fn inst_mut(&mut self, inst: Inst) -> &mut InstructionData {
|
||||
&mut self.instructions[inst.index()]
|
||||
}
|
||||
|
||||
/// Create result values for an instruction that produces multiple results.
|
||||
///
|
||||
/// Instructions that produce 0 or 1 result values only need to be created with `make_inst`. If
|
||||
@@ -147,11 +143,11 @@ impl Function {
|
||||
|
||||
// Update the second_result pointer in `inst`.
|
||||
if head != NO_VALUE {
|
||||
*self.inst_mut(inst)
|
||||
*self[inst]
|
||||
.second_result_mut()
|
||||
.expect("instruction format doesn't allow multiple results") = head;
|
||||
}
|
||||
*self.inst_mut(inst).first_type_mut() = first_type;
|
||||
*self[inst].first_type_mut() = first_type;
|
||||
|
||||
fixed_results
|
||||
}
|
||||
@@ -456,6 +452,13 @@ impl Index<Inst> for Function {
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow mutable access to instructions via function indexing.
|
||||
impl IndexMut<Inst> for Function {
|
||||
fn index_mut<'a>(&'a mut self, inst: Inst) -> &'a mut InstructionData {
|
||||
&mut self.instructions[inst.index()]
|
||||
}
|
||||
}
|
||||
|
||||
/// A node in a double linked list of instructions is a basic block.
|
||||
#[derive(Debug)]
|
||||
struct InstNode {
|
||||
|
||||
Reference in New Issue
Block a user