Merge pull request #1494 from cfallin/arm64-merge

Add new `MachInst` backend and ARM64 support.
This commit is contained in:
Chris Fallin
2020-04-16 10:02:02 -07:00
committed by GitHub
63 changed files with 16668 additions and 322 deletions

View File

@@ -19,8 +19,10 @@ use crate::flowgraph::ControlFlowGraph;
use crate::ir::Function;
use crate::isa::TargetIsa;
use crate::legalize_function;
use crate::legalizer::simple_legalize;
use crate::licm::do_licm;
use crate::loop_analysis::LoopAnalysis;
use crate::machinst::MachCompileResult;
use crate::nan_canonicalization::do_nan_canonicalization;
use crate::postopt::do_postopt;
use crate::redundant_reload_remover::RedundantReloadRemover;
@@ -55,6 +57,12 @@ pub struct Context {
/// Redundant-reload remover context.
pub redundant_reload_remover: RedundantReloadRemover,
/// Result of MachBackend compilation, if computed.
pub mach_compile_result: Option<MachCompileResult>,
/// Flag: do we want a disassembly with the MachCompileResult?
pub want_disasm: bool,
}
impl Context {
@@ -78,6 +86,8 @@ impl Context {
regalloc: regalloc::Context::new(),
loop_analysis: LoopAnalysis::new(),
redundant_reload_remover: RedundantReloadRemover::new(),
mach_compile_result: None,
want_disasm: false,
}
}
@@ -89,6 +99,14 @@ impl Context {
self.regalloc.clear();
self.loop_analysis.clear();
self.redundant_reload_remover.clear();
self.mach_compile_result = None;
self.want_disasm = false;
}
/// Set the flag to request a disassembly when compiling with a
/// `MachBackend` backend.
pub fn set_disasm(&mut self, val: bool) {
self.want_disasm = val;
}
/// Compile the function, and emit machine code into a `Vec<u8>`.
@@ -130,9 +148,13 @@ impl Context {
pub fn compile(&mut self, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
let _tt = timing::compile();
self.verify_if(isa)?;
debug!("Compiling:\n{}", self.func.display(isa));
let opt_level = isa.flags().opt_level();
debug!(
"Compiling (opt level {:?}):\n{}",
opt_level,
self.func.display(isa)
);
self.compute_cfg();
if opt_level != OptLevel::None {
@@ -141,6 +163,7 @@ impl Context {
if isa.flags().enable_nan_canonicalization() {
self.canonicalize_nans(isa)?;
}
self.legalize(isa)?;
if opt_level != OptLevel::None {
self.postopt(isa)?;
@@ -149,23 +172,32 @@ impl Context {
self.licm(isa)?;
self.simple_gvn(isa)?;
}
self.compute_domtree();
self.eliminate_unreachable_code(isa)?;
if opt_level != OptLevel::None {
self.dce(isa)?;
}
self.regalloc(isa)?;
self.prologue_epilogue(isa)?;
if opt_level == OptLevel::Speed || opt_level == OptLevel::SpeedAndSize {
self.redundant_reload_remover(isa)?;
}
if opt_level == OptLevel::SpeedAndSize {
self.shrink_instructions(isa)?;
}
let result = self.relax_branches(isa);
debug!("Compiled:\n{}", self.func.display(isa));
result
if let Some(backend) = isa.get_mach_backend() {
let result = backend.compile_function(&mut self.func, self.want_disasm)?;
let info = result.code_info();
self.mach_compile_result = Some(result);
Ok(info)
} else {
self.regalloc(isa)?;
self.prologue_epilogue(isa)?;
if opt_level == OptLevel::Speed || opt_level == OptLevel::SpeedAndSize {
self.redundant_reload_remover(isa)?;
}
if opt_level == OptLevel::SpeedAndSize {
self.shrink_instructions(isa)?;
}
let result = self.relax_branches(isa);
debug!("Compiled:\n{}", self.func.display(isa));
result
}
}
/// Emit machine code directly into raw memory.
@@ -191,7 +223,11 @@ impl Context {
) -> CodeInfo {
let _tt = timing::binemit();
let mut sink = MemoryCodeSink::new(mem, relocs, traps, stackmaps);
isa.emit_function_to_memory(&self.func, &mut sink);
if let Some(ref result) = &self.mach_compile_result {
result.sections.emit(&mut sink);
} else {
isa.emit_function_to_memory(&self.func, &mut sink);
}
sink.info
}
@@ -279,9 +315,15 @@ impl Context {
// TODO: Avoid doing this when legalization doesn't actually mutate the CFG.
self.domtree.clear();
self.loop_analysis.clear();
legalize_function(&mut self.func, &mut self.cfg, isa);
debug!("Legalized:\n{}", self.func.display(isa));
self.verify_if(isa)
if isa.get_mach_backend().is_some() {
// Run some specific legalizations only.
simple_legalize(&mut self.func, &mut self.cfg, isa);
self.verify_if(isa)
} else {
legalize_function(&mut self.func, &mut self.cfg, isa);
debug!("Legalized:\n{}", self.func.display(isa));
self.verify_if(isa)
}
}
/// Perform post-legalization rewrites on the function.