Write and parse value locations for EBB arguments

Fixes #56.

We now have complete support for value location annotations in the
textual IL format. Values defined by instructions as well as EBB
arguments are covered.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-15 11:21:29 -07:00
parent 24a5a02752
commit cc3707706c
6 changed files with 52 additions and 16 deletions

View File

@@ -25,6 +25,14 @@ impl Default for ValueLoc {
}
impl ValueLoc {
/// Is this an assigned location? (That is, not `Unassigned`).
pub fn is_assigned(&self) -> bool {
match *self {
ValueLoc::Unassigned => false,
_ => true,
}
}
/// Get the register unit of this location, or panic.
pub fn unwrap_reg(self) -> RegUnit {
match self {

View File

@@ -91,11 +91,22 @@ fn write_preamble(
//
// ====--------------------------------------------------------------------------------------====//
pub fn write_arg(w: &mut Write, func: &Function, arg: Value) -> Result {
write!(w, "{}: {}", arg, func.dfg.value_type(arg))
pub fn write_arg(w: &mut Write, func: &Function, regs: Option<&RegInfo>, arg: Value) -> Result {
write!(w, "{}: {}", arg, func.dfg.value_type(arg))?;
let loc = func.locations[arg];
if loc.is_assigned() {
write!(w, " [{}]", loc.display(regs))?
}
Ok(())
}
pub fn write_ebb_header(w: &mut Write, func: &Function, ebb: Ebb) -> Result {
pub fn write_ebb_header(
w: &mut Write,
func: &Function,
isa: Option<&TargetIsa>,
ebb: Ebb,
) -> Result {
// Write out the basic block header, outdented:
//
// ebb1:
@@ -108,24 +119,27 @@ pub fn write_ebb_header(w: &mut Write, func: &Function, ebb: Ebb) -> Result {
write!(w, " ")?;
}
let regs = isa.map(TargetIsa::register_info);
let regs = regs.as_ref();
let mut args = func.dfg.ebb_args(ebb).iter().cloned();
match args.next() {
None => return writeln!(w, "{}:", ebb),
Some(arg) => {
write!(w, "{}(", ebb)?;
write_arg(w, func, arg)?;
write_arg(w, func, regs, arg)?;
}
}
// Remaining arguments.
for arg in args {
write!(w, ", ")?;
write_arg(w, func, arg)?;
write_arg(w, func, regs, arg)?;
}
writeln!(w, "):")
}
pub fn write_ebb(w: &mut Write, func: &Function, isa: Option<&TargetIsa>, ebb: Ebb) -> Result {
write_ebb_header(w, func, ebb)?;
write_ebb_header(w, func, isa, ebb)?;
for inst in func.layout.ebb_insts(ebb) {
write_instruction(w, func, isa, inst)?;
}

View File

@@ -1449,22 +1449,35 @@ impl<'a> Parser<'a> {
// Parse a single EBB argument declaration, and append it to `ebb`.
//
// ebb-arg ::= * Value(v) ":" Type(t)
// ebb-arg ::= * Value(v) ":" Type(t) arg-loc?
// arg-loc ::= "[" value-location "]"
//
fn parse_ebb_arg(&mut self, ctx: &mut Context, ebb: Ebb) -> Result<()> {
// ebb-arg ::= * Value(v) ":" Type(t)
// ebb-arg ::= * Value(v) ":" Type(t) arg-loc?
let v = self.match_value("EBB argument must be a value")?;
let v_location = self.loc;
// ebb-arg ::= Value(v) * ":" Type(t)
// ebb-arg ::= Value(v) * ":" Type(t) arg-loc?
self.match_token(
Token::Colon,
"expected ':' after EBB argument",
)?;
// ebb-arg ::= Value(v) ":" * Type(t)
// ebb-arg ::= Value(v) ":" * Type(t) arg-loc?
let t = self.match_type("expected EBB argument type")?;
// Allocate the EBB argument and add the mapping.
let value = ctx.function.dfg.append_ebb_arg(ebb, t);
ctx.map.def_value(v, value, &v_location)
ctx.map.def_value(v, value, &v_location)?;
// ebb-arg ::= Value(v) ":" Type(t) * arg-loc?
if self.optional(Token::LBracket) {
let loc = self.parse_value_location(ctx)?;
ctx.function.locations[value] = loc;
self.match_token(
Token::RBracket,
"expected ']' after value location",
)?;
}
Ok(())
}
fn parse_value_location(&mut self, ctx: &Context) -> Result<ValueLoc> {