Track regmove instruction during binemit.

Register locations can change throughout an EBB. Make sure the
emit_inst() function considers this when encoding instructions and
update the register diversion tracker.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-18 12:52:53 -07:00
parent c4db4c124b
commit 53d9232d39
14 changed files with 73 additions and 19 deletions

View File

@@ -10,6 +10,7 @@ pub use self::relaxation::relax_branches;
pub use self::memorysink::{MemoryCodeSink, RelocSink};
use ir::{Ebb, FuncRef, JumpTable, Function, Inst};
use regalloc::RegDiversions;
/// Offset in bytes from the beginning of the function.
///
@@ -64,13 +65,14 @@ pub fn bad_encoding(func: &Function, inst: Inst) -> ! {
/// appropriate instruction emitter.
pub fn emit_function<CS, EI>(func: &Function, emit_inst: EI, sink: &mut CS)
where CS: CodeSink,
EI: Fn(&Function, Inst, &mut CS)
EI: Fn(&Function, Inst, &mut RegDiversions, &mut CS)
{
let mut divert = RegDiversions::new();
for ebb in func.layout.ebbs() {
divert.clear();
assert_eq!(func.offsets[ebb], sink.offset());
for inst in func.layout.ebb_insts(ebb) {
emit_inst(func, inst, sink);
emit_inst(func, inst, &mut divert, sink);
}
}
}

View File

@@ -2,6 +2,7 @@
use binemit::{CodeSink, bad_encoding};
use ir::{Function, Inst};
use regalloc::RegDiversions;
include!(concat!(env!("OUT_DIR"), "/binemit-arm32.rs"));

View File

@@ -91,8 +91,12 @@ impl TargetIsa for Isa {
abi::allocatable_registers(func)
}
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
binemit::emit_inst(func, inst, sink)
fn emit_inst(&self,
func: &ir::Function,
inst: ir::Inst,
divert: &mut regalloc::RegDiversions,
sink: &mut CodeSink) {
binemit::emit_inst(func, inst, divert, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {

View File

@@ -2,6 +2,7 @@
use binemit::{CodeSink, bad_encoding};
use ir::{Function, Inst};
use regalloc::RegDiversions;
include!(concat!(env!("OUT_DIR"), "/binemit-arm64.rs"));

View File

@@ -84,8 +84,12 @@ impl TargetIsa for Isa {
abi::allocatable_registers(func)
}
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
binemit::emit_inst(func, inst, sink)
fn emit_inst(&self,
func: &ir::Function,
inst: ir::Inst,
divert: &mut regalloc::RegDiversions,
sink: &mut CodeSink) {
binemit::emit_inst(func, inst, divert, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {

View File

@@ -3,6 +3,7 @@
use binemit::{CodeSink, Reloc, bad_encoding};
use ir::{Function, Inst, InstructionData};
use isa::RegUnit;
use regalloc::RegDiversions;
include!(concat!(env!("OUT_DIR"), "/binemit-intel.rs"));

View File

@@ -91,8 +91,12 @@ impl TargetIsa for Isa {
abi::allocatable_registers(func, &self.shared_flags)
}
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
binemit::emit_inst(func, inst, sink)
fn emit_inst(&self,
func: &ir::Function,
inst: ir::Inst,
divert: &mut regalloc::RegDiversions,
sink: &mut CodeSink) {
binemit::emit_inst(func, inst, divert, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {

View File

@@ -215,7 +215,11 @@ pub trait TargetIsa {
///
/// Note that this will call `put*` methods on the trait object via its vtable which is not the
/// fastest way of emitting code.
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut binemit::CodeSink);
fn emit_inst(&self,
func: &ir::Function,
inst: ir::Inst,
divert: &mut regalloc::RegDiversions,
sink: &mut binemit::CodeSink);
/// Emit a whole function into memory.
///

View File

@@ -4,6 +4,7 @@ use binemit::{CodeSink, Reloc, bad_encoding};
use ir::{Function, Inst, InstructionData};
use isa::RegUnit;
use predicates::is_signed_int;
use regalloc::RegDiversions;
include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));

View File

@@ -91,8 +91,12 @@ impl TargetIsa for Isa {
abi::allocatable_registers(func, &self.isa_flags)
}
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
binemit::emit_inst(func, inst, sink)
fn emit_inst(&self,
func: &ir::Function,
inst: ir::Inst,
divert: &mut regalloc::RegDiversions,
sink: &mut CodeSink) {
binemit::emit_inst(func, inst, divert, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {