diff --git a/cranelift/filetests/parser/instruction_encoding.cton b/cranelift/filetests/parser/instruction_encoding.cton index c808892701..c9c668dc3f 100644 --- a/cranelift/filetests/parser/instruction_encoding.cton +++ b/cranelift/filetests/parser/instruction_encoding.cton @@ -5,7 +5,7 @@ isa riscv ; regex: WS=[ \t]* function %foo(i32, i32) { -ebb1(v0: i32, v1: i32): +ebb1(v0: i32 [%x8], v1: i32): [-,-] v2 = iadd v0, v1 [-] trap [R#1234, %x5, %x11] v6, v7 = iadd_cout v2, v0 @@ -14,7 +14,7 @@ ebb1(v0: i32, v1: i32): [Iret#5] return v0, v8 } ; sameln: function %foo(i32, i32) native { -; nextln: $ebb1($v0: i32, $v1: i32): +; nextln: $ebb1($v0: i32 [%x8], $v1: i32): ; nextln: [-,-]$WS $v2 = iadd $v0, $v1 ; nextln: [-]$WS trap ; nextln: [R#1234,%x5,%x11]$WS $v6, $v7 = iadd_cout $v2, $v0 diff --git a/cranelift/filetests/regalloc/coalesce.cton b/cranelift/filetests/regalloc/coalesce.cton index 80cd38e62e..7624eaef7c 100644 --- a/cranelift/filetests/regalloc/coalesce.cton +++ b/cranelift/filetests/regalloc/coalesce.cton @@ -4,6 +4,7 @@ isa riscv ; Test the coalescer. ; regex: V=v\d+ ; regex: WS=\s+ +; regex: LOC=%\w+ ; This function is already CSSA, so no copies should be inserted. function %cssa(i32) -> i32 { @@ -81,7 +82,7 @@ ebb0(v0: i32): ebb1(v10: i32, v11: i32): ; v11 needs to be isolated because it interferes with v10. - ; check: $ebb1($v10: i32, $(nv11a=$V): i32) + ; check: $ebb1($v10: i32 [$LOC], $(nv11a=$V): i32 [$LOC]) ; check: $v11 = copy $nv11a v12 = iadd v10, v11 v13 = icmp ult v12, v0 diff --git a/cranelift/filetests/regalloc/spill.cton b/cranelift/filetests/regalloc/spill.cton index 901509a8d4..8f00c93184 100644 --- a/cranelift/filetests/regalloc/spill.cton +++ b/cranelift/filetests/regalloc/spill.cton @@ -25,7 +25,7 @@ function %pyramid(i32) -> i32 { ; check: ss2 = spill_slot 4 ; not: spill_slot ebb0(v1: i32): -; check: $ebb0($(rv1=$V): i32, $(rlink=$V): i32) +; check: $ebb0($(rv1=$V): i32 [%x10], $(rlink=$V): i32 [%x1]) ; check: ,ss0]$WS $v1 = spill $rv1 ; nextln: ,ss1]$WS $(link=$V) = spill $rlink ; not: spill @@ -155,7 +155,7 @@ function %use_spilled_value(i32) -> i32 { ; check: ss1 = spill_slot 4 ; check: ss2 = spill_slot 4 ebb0(v1: i32): -; check: $ebb0($(rv1=$V): i32, $(rlink=$V): i32) +; check: $ebb0($(rv1=$V): i32 [%x10], $(rlink=$V): i32 [%x1]) ; check: ,ss0]$WS $v1 = spill $rv1 ; nextln: ,ss1]$WS $(link=$V) = spill $rlink ; not: spill diff --git a/lib/cretonne/src/ir/valueloc.rs b/lib/cretonne/src/ir/valueloc.rs index a6a358e14b..1e3cf20f87 100644 --- a/lib/cretonne/src/ir/valueloc.rs +++ b/lib/cretonne/src/ir/valueloc.rs @@ -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 { diff --git a/lib/cretonne/src/write.rs b/lib/cretonne/src/write.rs index 77f0209da3..3467f79adb 100644 --- a/lib/cretonne/src/write.rs +++ b/lib/cretonne/src/write.rs @@ -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)?; } diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index e5c59530fc..f9b3f334e1 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -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 {