Add the dyn keyword before trait objects;
This commit is contained in:
@@ -49,7 +49,7 @@ impl<F: Forest> Path<F> {
|
|||||||
key: F::Key,
|
key: F::Key,
|
||||||
root: Node,
|
root: Node,
|
||||||
pool: &NodePool<F>,
|
pool: &NodePool<F>,
|
||||||
comp: &Comparator<F::Key>,
|
comp: &dyn Comparator<F::Key>,
|
||||||
) -> Option<F::Value> {
|
) -> Option<F::Value> {
|
||||||
let mut node = root;
|
let mut node = root;
|
||||||
for level in 0.. {
|
for level in 0.. {
|
||||||
|
|||||||
@@ -410,7 +410,7 @@ fn gen_transform_group<'a>(
|
|||||||
fmt.line("inst: crate::ir::Inst,");
|
fmt.line("inst: crate::ir::Inst,");
|
||||||
fmt.line("func: &mut crate::ir::Function,");
|
fmt.line("func: &mut crate::ir::Function,");
|
||||||
fmt.line("cfg: &mut crate::flowgraph::ControlFlowGraph,");
|
fmt.line("cfg: &mut crate::flowgraph::ControlFlowGraph,");
|
||||||
fmt.line("isa: &crate::isa::TargetIsa,");
|
fmt.line("isa: &dyn crate::isa::TargetIsa,");
|
||||||
});
|
});
|
||||||
fmtln!(fmt, ") -> bool {");
|
fmtln!(fmt, ") -> bool {");
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ pub struct MemoryCodeSink<'a> {
|
|||||||
data: *mut u8,
|
data: *mut u8,
|
||||||
/// Offset is isize because its major consumer needs it in that form.
|
/// Offset is isize because its major consumer needs it in that form.
|
||||||
offset: isize,
|
offset: isize,
|
||||||
relocs: &'a mut RelocSink,
|
relocs: &'a mut dyn RelocSink,
|
||||||
traps: &'a mut TrapSink,
|
traps: &'a mut dyn TrapSink,
|
||||||
/// Information about the generated code and read-only data.
|
/// Information about the generated code and read-only data.
|
||||||
pub info: CodeInfo,
|
pub info: CodeInfo,
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,11 @@ impl<'a> MemoryCodeSink<'a> {
|
|||||||
///
|
///
|
||||||
/// This function is unsafe since `MemoryCodeSink` does not perform bounds checking on the
|
/// This function is unsafe since `MemoryCodeSink` does not perform bounds checking on the
|
||||||
/// memory buffer, and it can't guarantee that the `data` pointer is valid.
|
/// memory buffer, and it can't guarantee that the `data` pointer is valid.
|
||||||
pub unsafe fn new(data: *mut u8, relocs: &'a mut RelocSink, traps: &'a mut TrapSink) -> Self {
|
pub unsafe fn new(
|
||||||
|
data: *mut u8,
|
||||||
|
relocs: &'a mut dyn RelocSink,
|
||||||
|
traps: &'a mut dyn TrapSink,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data,
|
data,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ use log::debug;
|
|||||||
/// Relax branches and compute the final layout of EBB headers in `func`.
|
/// Relax branches and compute the final layout of EBB headers in `func`.
|
||||||
///
|
///
|
||||||
/// Fill in the `func.offsets` table so the function is ready for binary emission.
|
/// Fill in the `func.offsets` table so the function is ready for binary emission.
|
||||||
pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> CodegenResult<CodeInfo> {
|
pub fn relax_branches(func: &mut Function, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
|
||||||
let _tt = timing::relax_branches();
|
let _tt = timing::relax_branches();
|
||||||
|
|
||||||
let encinfo = isa.encoding_info();
|
let encinfo = isa.encoding_info();
|
||||||
@@ -174,7 +174,7 @@ fn relax_branch(
|
|||||||
offset: CodeOffset,
|
offset: CodeOffset,
|
||||||
dest_offset: CodeOffset,
|
dest_offset: CodeOffset,
|
||||||
encinfo: &EncInfo,
|
encinfo: &EncInfo,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> CodeOffset {
|
) -> CodeOffset {
|
||||||
let inst = cur.current_inst().unwrap();
|
let inst = cur.current_inst().unwrap();
|
||||||
debug!(
|
debug!(
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::timing;
|
|||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
/// Pick the smallest valid encodings for instructions.
|
/// Pick the smallest valid encodings for instructions.
|
||||||
pub fn shrink_instructions(func: &mut Function, isa: &TargetIsa) {
|
pub fn shrink_instructions(func: &mut Function, isa: &dyn TargetIsa) {
|
||||||
let _tt = timing::shrink_instructions();
|
let _tt = timing::shrink_instructions();
|
||||||
|
|
||||||
let encinfo = isa.encoding_info();
|
let encinfo = isa.encoding_info();
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ impl<'a> CFGPrinter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write the CFG for this function to `w`.
|
/// Write the CFG for this function to `w`.
|
||||||
pub fn write(&self, w: &mut Write) -> Result {
|
pub fn write(&self, w: &mut dyn Write) -> Result {
|
||||||
self.header(w)?;
|
self.header(w)?;
|
||||||
self.ebb_nodes(w)?;
|
self.ebb_nodes(w)?;
|
||||||
self.cfg_connections(w)?;
|
self.cfg_connections(w)?;
|
||||||
writeln!(w, "}}")
|
writeln!(w, "}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header(&self, w: &mut Write) -> Result {
|
fn header(&self, w: &mut dyn Write) -> Result {
|
||||||
writeln!(w, "digraph \"{}\" {{", self.func.name)?;
|
writeln!(w, "digraph \"{}\" {{", self.func.name)?;
|
||||||
if let Some(entry) = self.func.layout.entry_block() {
|
if let Some(entry) = self.func.layout.entry_block() {
|
||||||
writeln!(w, " {{rank=min; {}}}", entry)?;
|
writeln!(w, " {{rank=min; {}}}", entry)?;
|
||||||
@@ -38,7 +38,7 @@ impl<'a> CFGPrinter<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ebb_nodes(&self, w: &mut Write) -> Result {
|
fn ebb_nodes(&self, w: &mut dyn Write) -> Result {
|
||||||
for ebb in &self.func.layout {
|
for ebb in &self.func.layout {
|
||||||
write!(w, " {} [shape=record, label=\"{{{}", ebb, ebb)?;
|
write!(w, " {} [shape=record, label=\"{{{}", ebb, ebb)?;
|
||||||
// Add all outgoing branch instructions to the label.
|
// Add all outgoing branch instructions to the label.
|
||||||
@@ -62,7 +62,7 @@ impl<'a> CFGPrinter<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cfg_connections(&self, w: &mut Write) -> Result {
|
fn cfg_connections(&self, w: &mut dyn Write) -> Result {
|
||||||
for ebb in &self.func.layout {
|
for ebb in &self.func.layout {
|
||||||
for BasicBlock { ebb: parent, inst } in self.cfg.pred_iter(ebb) {
|
for BasicBlock { ebb: parent, inst } in self.cfg.pred_iter(ebb) {
|
||||||
writeln!(w, " {}:{} -> {}", parent, inst, ebb)?;
|
writeln!(w, " {}:{} -> {}", parent, inst, ebb)?;
|
||||||
|
|||||||
@@ -96,10 +96,10 @@ impl Context {
|
|||||||
/// Returns information about the function's code and read-only data.
|
/// Returns information about the function's code and read-only data.
|
||||||
pub fn compile_and_emit(
|
pub fn compile_and_emit(
|
||||||
&mut self,
|
&mut self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
mem: &mut Vec<u8>,
|
mem: &mut Vec<u8>,
|
||||||
relocs: &mut RelocSink,
|
relocs: &mut dyn RelocSink,
|
||||||
traps: &mut TrapSink,
|
traps: &mut dyn TrapSink,
|
||||||
) -> CodegenResult<CodeInfo> {
|
) -> CodegenResult<CodeInfo> {
|
||||||
let info = self.compile(isa)?;
|
let info = self.compile(isa)?;
|
||||||
let old_len = mem.len();
|
let old_len = mem.len();
|
||||||
@@ -117,7 +117,7 @@ impl Context {
|
|||||||
/// code sink.
|
/// code sink.
|
||||||
///
|
///
|
||||||
/// Returns information about the function's code and read-only data.
|
/// Returns information about the function's code and read-only data.
|
||||||
pub fn compile(&mut self, isa: &TargetIsa) -> CodegenResult<CodeInfo> {
|
pub fn compile(&mut self, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
|
||||||
let _tt = timing::compile();
|
let _tt = timing::compile();
|
||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
|
|
||||||
@@ -164,10 +164,10 @@ impl Context {
|
|||||||
/// Returns information about the emitted code and data.
|
/// Returns information about the emitted code and data.
|
||||||
pub unsafe fn emit_to_memory(
|
pub unsafe fn emit_to_memory(
|
||||||
&self,
|
&self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
mem: *mut u8,
|
mem: *mut u8,
|
||||||
relocs: &mut RelocSink,
|
relocs: &mut dyn RelocSink,
|
||||||
traps: &mut TrapSink,
|
traps: &mut dyn TrapSink,
|
||||||
) -> CodeInfo {
|
) -> CodeInfo {
|
||||||
let _tt = timing::binemit();
|
let _tt = timing::binemit();
|
||||||
let mut sink = MemoryCodeSink::new(mem, relocs, traps);
|
let mut sink = MemoryCodeSink::new(mem, relocs, traps);
|
||||||
@@ -199,7 +199,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run the locations verifier on the function.
|
/// Run the locations verifier on the function.
|
||||||
pub fn verify_locations(&self, isa: &TargetIsa) -> VerifierResult<()> {
|
pub fn verify_locations(&self, isa: &dyn TargetIsa) -> VerifierResult<()> {
|
||||||
let mut errors = VerifierErrors::default();
|
let mut errors = VerifierErrors::default();
|
||||||
let _ = verify_locations(isa, &self.func, None, &mut errors);
|
let _ = verify_locations(isa, &self.func, None, &mut errors);
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run the locations verifier only if the `enable_verifier` setting is true.
|
/// Run the locations verifier only if the `enable_verifier` setting is true.
|
||||||
pub fn verify_locations_if(&self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn verify_locations_if(&self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
if isa.flags().enable_verifier() {
|
if isa.flags().enable_verifier() {
|
||||||
self.verify_locations(isa)?;
|
self.verify_locations(isa)?;
|
||||||
}
|
}
|
||||||
@@ -226,20 +226,20 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform pre-legalization rewrites on the function.
|
/// Perform pre-legalization rewrites on the function.
|
||||||
pub fn preopt(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn preopt(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
do_preopt(&mut self.func, &mut self.cfg);
|
do_preopt(&mut self.func, &mut self.cfg);
|
||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform NaN canonicalizing rewrites on the function.
|
/// Perform NaN canonicalizing rewrites on the function.
|
||||||
pub fn canonicalize_nans(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn canonicalize_nans(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
do_nan_canonicalization(&mut self.func);
|
do_nan_canonicalization(&mut self.func);
|
||||||
self.verify_if(isa)
|
self.verify_if(isa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the legalizer for `isa` on the function.
|
/// Run the legalizer for `isa` on the function.
|
||||||
pub fn legalize(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn legalize(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
// Legalization invalidates the domtree and loop_analysis by mutating the CFG.
|
// Legalization invalidates the domtree and loop_analysis by mutating the CFG.
|
||||||
// TODO: Avoid doing this when legalization doesn't actually mutate the CFG.
|
// TODO: Avoid doing this when legalization doesn't actually mutate the CFG.
|
||||||
self.domtree.clear();
|
self.domtree.clear();
|
||||||
@@ -249,7 +249,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform post-legalization rewrites on the function.
|
/// Perform post-legalization rewrites on the function.
|
||||||
pub fn postopt(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn postopt(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
do_postopt(&mut self.func, isa);
|
do_postopt(&mut self.func, isa);
|
||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -284,7 +284,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform LICM on the function.
|
/// Perform LICM on the function.
|
||||||
pub fn licm(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn licm(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
do_licm(
|
do_licm(
|
||||||
isa,
|
isa,
|
||||||
&mut self.func,
|
&mut self.func,
|
||||||
@@ -305,13 +305,13 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run the register allocator.
|
/// Run the register allocator.
|
||||||
pub fn regalloc(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn regalloc(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
self.regalloc
|
self.regalloc
|
||||||
.run(isa, &mut self.func, &self.cfg, &mut self.domtree)
|
.run(isa, &mut self.func, &self.cfg, &mut self.domtree)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert prologue and epilogues after computing the stack frame layout.
|
/// Insert prologue and epilogues after computing the stack frame layout.
|
||||||
pub fn prologue_epilogue(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn prologue_epilogue(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
isa.prologue_epilogue(&mut self.func)?;
|
isa.prologue_epilogue(&mut self.func)?;
|
||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
self.verify_locations_if(isa)?;
|
self.verify_locations_if(isa)?;
|
||||||
@@ -319,7 +319,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run the instruction shrinking pass.
|
/// Run the instruction shrinking pass.
|
||||||
pub fn shrink_instructions(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn shrink_instructions(&mut self, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
shrink_instructions(&mut self.func, isa);
|
shrink_instructions(&mut self.func, isa);
|
||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
self.verify_locations_if(isa)?;
|
self.verify_locations_if(isa)?;
|
||||||
@@ -328,7 +328,7 @@ impl Context {
|
|||||||
|
|
||||||
/// Run the branch relaxation pass and return information about the function's code and
|
/// Run the branch relaxation pass and return information about the function's code and
|
||||||
/// read-only data.
|
/// read-only data.
|
||||||
pub fn relax_branches(&mut self, isa: &TargetIsa) -> CodegenResult<CodeInfo> {
|
pub fn relax_branches(&mut self, isa: &dyn TargetIsa) -> CodegenResult<CodeInfo> {
|
||||||
let info = relax_branches(&mut self.func, isa)?;
|
let info = relax_branches(&mut self.func, isa)?;
|
||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
self.verify_locations_if(isa)?;
|
self.verify_locations_if(isa)?;
|
||||||
@@ -336,7 +336,10 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Builds ranges and location for specified value labels.
|
/// Builds ranges and location for specified value labels.
|
||||||
pub fn build_value_labels_ranges(&self, isa: &TargetIsa) -> CodegenResult<ValueLabelsRanges> {
|
pub fn build_value_labels_ranges(
|
||||||
|
&self,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
|
) -> CodegenResult<ValueLabelsRanges> {
|
||||||
Ok(build_value_labels_ranges::<ComparableSourceLoc>(
|
Ok(build_value_labels_ranges::<ComparableSourceLoc>(
|
||||||
&self.func,
|
&self.func,
|
||||||
&self.regalloc,
|
&self.regalloc,
|
||||||
|
|||||||
@@ -657,12 +657,12 @@ pub struct EncCursor<'f> {
|
|||||||
pub func: &'f mut ir::Function,
|
pub func: &'f mut ir::Function,
|
||||||
|
|
||||||
/// The target ISA that will be used to encode instructions.
|
/// The target ISA that will be used to encode instructions.
|
||||||
pub isa: &'f TargetIsa,
|
pub isa: &'f dyn TargetIsa,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'f> EncCursor<'f> {
|
impl<'f> EncCursor<'f> {
|
||||||
/// Create a new `EncCursor` pointing nowhere.
|
/// Create a new `EncCursor` pointing nowhere.
|
||||||
pub fn new(func: &'f mut ir::Function, isa: &'f TargetIsa) -> Self {
|
pub fn new(func: &'f mut ir::Function, isa: &'f dyn TargetIsa) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pos: CursorPosition::Nowhere,
|
pos: CursorPosition::Nowhere,
|
||||||
srcloc: Default::default(),
|
srcloc: Default::default(),
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ impl DataFlowGraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an object that displays `inst`.
|
/// Returns an object that displays `inst`.
|
||||||
pub fn display_inst<'a, I: Into<Option<&'a TargetIsa>>>(
|
pub fn display_inst<'a, I: Into<Option<&'a dyn TargetIsa>>>(
|
||||||
&'a self,
|
&'a self,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
isa: I,
|
isa: I,
|
||||||
@@ -909,7 +909,7 @@ impl EbbData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Object that can display an instruction.
|
/// Object that can display an instruction.
|
||||||
pub struct DisplayInst<'a>(&'a DataFlowGraph, Option<&'a TargetIsa>, Inst);
|
pub struct DisplayInst<'a>(&'a DataFlowGraph, Option<&'a dyn TargetIsa>, Inst);
|
||||||
|
|
||||||
impl<'a> fmt::Display for DisplayInst<'a> {
|
impl<'a> fmt::Display for DisplayInst<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ impl fmt::Display for AnyEntity {
|
|||||||
|
|
||||||
impl fmt::Debug for AnyEntity {
|
impl fmt::Debug for AnyEntity {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
(self as &fmt::Display).fmt(f)
|
(self as &dyn fmt::Display).fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,10 @@ impl Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return an object that can display this function with correct ISA-specific annotations.
|
/// Return an object that can display this function with correct ISA-specific annotations.
|
||||||
pub fn display<'a, I: Into<Option<&'a TargetIsa>>>(&'a self, isa: I) -> DisplayFunction<'a> {
|
pub fn display<'a, I: Into<Option<&'a dyn TargetIsa>>>(
|
||||||
|
&'a self,
|
||||||
|
isa: I,
|
||||||
|
) -> DisplayFunction<'a> {
|
||||||
DisplayFunction(self, isa.into().into())
|
DisplayFunction(self, isa.into().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,13 +205,13 @@ impl Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper around `encode` which assigns `inst` the resulting encoding.
|
/// Wrapper around `encode` which assigns `inst` the resulting encoding.
|
||||||
pub fn update_encoding(&mut self, inst: ir::Inst, isa: &TargetIsa) -> Result<(), Legalize> {
|
pub fn update_encoding(&mut self, inst: ir::Inst, isa: &dyn TargetIsa) -> Result<(), Legalize> {
|
||||||
self.encode(inst, isa).map(|e| self.encodings[inst] = e)
|
self.encode(inst, isa).map(|e| self.encodings[inst] = e)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper around `TargetIsa::encode` for encoding an existing instruction
|
/// Wrapper around `TargetIsa::encode` for encoding an existing instruction
|
||||||
/// in the `Function`.
|
/// in the `Function`.
|
||||||
pub fn encode(&self, inst: ir::Inst, isa: &TargetIsa) -> Result<Encoding, Legalize> {
|
pub fn encode(&self, inst: ir::Inst, isa: &dyn TargetIsa) -> Result<Encoding, Legalize> {
|
||||||
isa.encode(&self, &self.dfg[inst], self.dfg.ctrl_typevar(inst))
|
isa.encode(&self, &self.dfg[inst], self.dfg.ctrl_typevar(inst))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,7 +224,7 @@ impl Function {
|
|||||||
/// Additional annotations for function display.
|
/// Additional annotations for function display.
|
||||||
pub struct DisplayFunctionAnnotations<'a> {
|
pub struct DisplayFunctionAnnotations<'a> {
|
||||||
/// Enable ISA annotations.
|
/// Enable ISA annotations.
|
||||||
pub isa: Option<&'a TargetIsa>,
|
pub isa: Option<&'a dyn TargetIsa>,
|
||||||
|
|
||||||
/// Enable value labels annotations.
|
/// Enable value labels annotations.
|
||||||
pub value_ranges: Option<&'a ValueLabelsRanges>,
|
pub value_ranges: Option<&'a ValueLabelsRanges>,
|
||||||
@@ -237,8 +240,8 @@ impl<'a> DisplayFunctionAnnotations<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<Option<&'a TargetIsa>> for DisplayFunctionAnnotations<'a> {
|
impl<'a> From<Option<&'a dyn TargetIsa>> for DisplayFunctionAnnotations<'a> {
|
||||||
fn from(isa: Option<&'a TargetIsa>) -> DisplayFunctionAnnotations {
|
fn from(isa: Option<&'a dyn TargetIsa>) -> DisplayFunctionAnnotations {
|
||||||
DisplayFunctionAnnotations {
|
DisplayFunctionAnnotations {
|
||||||
isa,
|
isa,
|
||||||
value_ranges: None,
|
value_ranges: None,
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ impl GlobalValueData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the type of this global.
|
/// Return the type of this global.
|
||||||
pub fn global_type(&self, isa: &TargetIsa) -> Type {
|
pub fn global_type(&self, isa: &dyn TargetIsa) -> Type {
|
||||||
match *self {
|
match *self {
|
||||||
GlobalValueData::VMContext { .. } | GlobalValueData::Symbol { .. } => {
|
GlobalValueData::VMContext { .. } | GlobalValueData::Symbol { .. } => {
|
||||||
isa.pointer_type()
|
isa.pointer_type()
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ pub fn get_libcall_funcref(
|
|||||||
libcall: LibCall,
|
libcall: LibCall,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> FuncRef {
|
) -> FuncRef {
|
||||||
find_funcref(libcall, func).unwrap_or_else(|| make_funcref_for_inst(libcall, func, inst, isa))
|
find_funcref(libcall, func).unwrap_or_else(|| make_funcref_for_inst(libcall, func, inst, isa))
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ pub fn get_probestack_funcref(
|
|||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
reg_type: Type,
|
reg_type: Type,
|
||||||
arg_reg: RegUnit,
|
arg_reg: RegUnit,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> FuncRef {
|
) -> FuncRef {
|
||||||
find_funcref(LibCall::Probestack, func)
|
find_funcref(LibCall::Probestack, func)
|
||||||
.unwrap_or_else(|| make_funcref_for_probestack(func, reg_type, arg_reg, isa))
|
.unwrap_or_else(|| make_funcref_for_probestack(func, reg_type, arg_reg, isa))
|
||||||
@@ -147,7 +147,7 @@ fn make_funcref_for_probestack(
|
|||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
reg_type: Type,
|
reg_type: Type,
|
||||||
arg_reg: RegUnit,
|
arg_reg: RegUnit,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> FuncRef {
|
) -> FuncRef {
|
||||||
let mut sig = Signature::new(CallConv::Probestack);
|
let mut sig = Signature::new(CallConv::Probestack);
|
||||||
let rax = AbiParam::special_reg(reg_type, ArgumentPurpose::Normal, arg_reg);
|
let rax = AbiParam::special_reg(reg_type, ArgumentPurpose::Normal, arg_reg);
|
||||||
@@ -163,7 +163,7 @@ fn make_funcref_for_inst(
|
|||||||
libcall: LibCall,
|
libcall: LibCall,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> FuncRef {
|
) -> FuncRef {
|
||||||
let mut sig = Signature::new(isa.default_call_conv());
|
let mut sig = Signature::new(isa.default_call_conv());
|
||||||
for &v in func.dfg.inst_args(inst) {
|
for &v in func.dfg.inst_args(inst) {
|
||||||
@@ -177,7 +177,12 @@ fn make_funcref_for_inst(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a funcref for `libcall`.
|
/// Create a funcref for `libcall`.
|
||||||
fn make_funcref(libcall: LibCall, func: &mut Function, sig: Signature, isa: &TargetIsa) -> FuncRef {
|
fn make_funcref(
|
||||||
|
libcall: LibCall,
|
||||||
|
func: &mut Function,
|
||||||
|
sig: Signature,
|
||||||
|
isa: &dyn TargetIsa,
|
||||||
|
) -> FuncRef {
|
||||||
let sigref = func.import_signature(sig);
|
let sigref = func.import_signature(sig);
|
||||||
|
|
||||||
func.import_function(ExtFuncData {
|
func.import_function(ExtFuncData {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fn isa_constructor(
|
|||||||
triple: Triple,
|
triple: Triple,
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
builder: shared_settings::Builder,
|
builder: shared_settings::Builder,
|
||||||
) -> Box<TargetIsa> {
|
) -> Box<dyn TargetIsa> {
|
||||||
let level1 = match triple.architecture {
|
let level1 = match triple.architecture {
|
||||||
Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => {
|
Architecture::Thumbv6m | Architecture::Thumbv7em | Architecture::Thumbv7m => {
|
||||||
&enc_tables::LEVEL1_T32[..]
|
&enc_tables::LEVEL1_T32[..]
|
||||||
@@ -119,7 +119,7 @@ impl TargetIsa for Isa {
|
|||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
divert: &mut regalloc::RegDiversions,
|
divert: &mut regalloc::RegDiversions,
|
||||||
sink: &mut CodeSink,
|
sink: &mut dyn CodeSink,
|
||||||
) {
|
) {
|
||||||
binemit::emit_inst(func, inst, divert, sink)
|
binemit::emit_inst(func, inst, divert, sink)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ fn isa_constructor(
|
|||||||
triple: Triple,
|
triple: Triple,
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
builder: shared_settings::Builder,
|
builder: shared_settings::Builder,
|
||||||
) -> Box<TargetIsa> {
|
) -> Box<dyn TargetIsa> {
|
||||||
Box::new(Isa {
|
Box::new(Isa {
|
||||||
triple,
|
triple,
|
||||||
isa_flags: settings::Flags::new(&shared_flags, builder),
|
isa_flags: settings::Flags::new(&shared_flags, builder),
|
||||||
@@ -106,7 +106,7 @@ impl TargetIsa for Isa {
|
|||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
divert: &mut regalloc::RegDiversions,
|
divert: &mut regalloc::RegDiversions,
|
||||||
sink: &mut CodeSink,
|
sink: &mut dyn CodeSink,
|
||||||
) {
|
) {
|
||||||
binemit::emit_inst(func, inst, divert, sink)
|
binemit::emit_inst(func, inst, divert, sink)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,13 +141,13 @@ pub enum LookupError {
|
|||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
triple: Triple,
|
triple: Triple,
|
||||||
setup: settings::Builder,
|
setup: settings::Builder,
|
||||||
constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<TargetIsa>,
|
constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<dyn TargetIsa>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Builder {
|
impl Builder {
|
||||||
/// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
|
/// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
|
||||||
/// fully configured `TargetIsa` trait object.
|
/// fully configured `TargetIsa` trait object.
|
||||||
pub fn finish(self, shared_flags: settings::Flags) -> Box<TargetIsa> {
|
pub fn finish(self, shared_flags: settings::Flags) -> Box<dyn TargetIsa> {
|
||||||
(self.constructor)(self.triple, shared_flags, self.setup)
|
(self.constructor)(self.triple, shared_flags, self.setup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ impl settings::Configurable for Builder {
|
|||||||
///
|
///
|
||||||
/// The `Encodings` iterator returns a legalization function to call.
|
/// The `Encodings` iterator returns a legalization function to call.
|
||||||
pub type Legalize =
|
pub type Legalize =
|
||||||
fn(ir::Inst, &mut ir::Function, &mut flowgraph::ControlFlowGraph, &TargetIsa) -> bool;
|
fn(ir::Inst, &mut ir::Function, &mut flowgraph::ControlFlowGraph, &dyn TargetIsa) -> bool;
|
||||||
|
|
||||||
/// This struct provides information that a frontend may need to know about a target to
|
/// This struct provides information that a frontend may need to know about a target to
|
||||||
/// produce Cranelift IR for the target.
|
/// produce Cranelift IR for the target.
|
||||||
@@ -367,7 +367,7 @@ pub trait TargetIsa: fmt::Display + Sync {
|
|||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
divert: &mut regalloc::RegDiversions,
|
divert: &mut regalloc::RegDiversions,
|
||||||
sink: &mut binemit::CodeSink,
|
sink: &mut dyn binemit::CodeSink,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Emit a whole function into memory.
|
/// Emit a whole function into memory.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fn isa_constructor(
|
|||||||
triple: Triple,
|
triple: Triple,
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
builder: shared_settings::Builder,
|
builder: shared_settings::Builder,
|
||||||
) -> Box<TargetIsa> {
|
) -> Box<dyn TargetIsa> {
|
||||||
let level1 = match triple.pointer_width().unwrap() {
|
let level1 = match triple.pointer_width().unwrap() {
|
||||||
PointerWidth::U16 => panic!("16-bit RISC-V unrecognized"),
|
PointerWidth::U16 => panic!("16-bit RISC-V unrecognized"),
|
||||||
PointerWidth::U32 => &enc_tables::LEVEL1_RV32[..],
|
PointerWidth::U32 => &enc_tables::LEVEL1_RV32[..],
|
||||||
@@ -113,7 +113,7 @@ impl TargetIsa for Isa {
|
|||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
divert: &mut regalloc::RegDiversions,
|
divert: &mut regalloc::RegDiversions,
|
||||||
sink: &mut CodeSink,
|
sink: &mut dyn CodeSink,
|
||||||
) {
|
) {
|
||||||
binemit::emit_inst(func, inst, divert, sink)
|
binemit::emit_inst(func, inst, divert, sink)
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ mod tests {
|
|||||||
use std::string::{String, ToString};
|
use std::string::{String, ToString};
|
||||||
use target_lexicon::triple;
|
use target_lexicon::triple;
|
||||||
|
|
||||||
fn encstr(isa: &isa::TargetIsa, enc: Result<isa::Encoding, isa::Legalize>) -> String {
|
fn encstr(isa: &dyn isa::TargetIsa, enc: Result<isa::Encoding, isa::Legalize>) -> String {
|
||||||
match enc {
|
match enc {
|
||||||
Ok(e) => isa.encoding_info().display(e).to_string(),
|
Ok(e) => isa.encoding_info().display(e).to_string(),
|
||||||
Err(_) => "no encoding".to_string(),
|
Err(_) => "no encoding".to_string(),
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ pub fn allocatable_registers(_func: &ir::Function, triple: &Triple) -> RegisterS
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the set of callee-saved registers.
|
/// Get the set of callee-saved registers.
|
||||||
fn callee_saved_gprs(isa: &TargetIsa, call_conv: CallConv) -> &'static [RU] {
|
fn callee_saved_gprs(isa: &dyn TargetIsa, call_conv: CallConv) -> &'static [RU] {
|
||||||
match isa.triple().pointer_width().unwrap() {
|
match isa.triple().pointer_width().unwrap() {
|
||||||
PointerWidth::U16 => panic!(),
|
PointerWidth::U16 => panic!(),
|
||||||
PointerWidth::U32 => &[RU::rbx, RU::rsi, RU::rdi],
|
PointerWidth::U32 => &[RU::rbx, RU::rsi, RU::rdi],
|
||||||
@@ -227,7 +227,7 @@ fn callee_saved_gprs(isa: &TargetIsa, call_conv: CallConv) -> &'static [RU] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the set of callee-saved registers that are used.
|
/// Get the set of callee-saved registers that are used.
|
||||||
fn callee_saved_gprs_used(isa: &TargetIsa, func: &ir::Function) -> RegisterSet {
|
fn callee_saved_gprs_used(isa: &dyn TargetIsa, func: &ir::Function) -> RegisterSet {
|
||||||
let mut all_callee_saved = RegisterSet::empty();
|
let mut all_callee_saved = RegisterSet::empty();
|
||||||
for reg in callee_saved_gprs(isa, func.signature.call_conv) {
|
for reg in callee_saved_gprs(isa, func.signature.call_conv) {
|
||||||
all_callee_saved.free(GPR, *reg as RegUnit);
|
all_callee_saved.free(GPR, *reg as RegUnit);
|
||||||
@@ -269,7 +269,7 @@ fn callee_saved_gprs_used(isa: &TargetIsa, func: &ir::Function) -> RegisterSet {
|
|||||||
used
|
used
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
match func.signature.call_conv {
|
match func.signature.call_conv {
|
||||||
// For now, just translate fast and cold as system_v.
|
// For now, just translate fast and cold as system_v.
|
||||||
CallConv::Fast | CallConv::Cold | CallConv::SystemV => {
|
CallConv::Fast | CallConv::Cold | CallConv::SystemV => {
|
||||||
@@ -281,7 +281,7 @@ pub fn prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenRes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
|
fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
!isa.flags().probestack_enabled(),
|
!isa.flags().probestack_enabled(),
|
||||||
"baldrdash does not expect cranelift to emit stack probes"
|
"baldrdash does not expect cranelift to emit stack probes"
|
||||||
@@ -302,7 +302,7 @@ fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> Code
|
|||||||
|
|
||||||
/// Implementation of the fastcall-based Win64 calling convention described at [1]
|
/// Implementation of the fastcall-based Win64 calling convention described at [1]
|
||||||
/// [1] https://msdn.microsoft.com/en-us/library/ms235286.aspx
|
/// [1] https://msdn.microsoft.com/en-us/library/ms235286.aspx
|
||||||
fn fastcall_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
|
fn fastcall_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
if isa.triple().pointer_width().unwrap() != PointerWidth::U64 {
|
if isa.triple().pointer_width().unwrap() != PointerWidth::U64 {
|
||||||
panic!("TODO: windows-fastcall: x86-32 not implemented yet");
|
panic!("TODO: windows-fastcall: x86-32 not implemented yet");
|
||||||
}
|
}
|
||||||
@@ -374,7 +374,7 @@ fn fastcall_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> Codeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a System V-compatible prologue and epilogue.
|
/// Insert a System V-compatible prologue and epilogue.
|
||||||
fn system_v_prologue_epilogue(func: &mut ir::Function, isa: &TargetIsa) -> CodegenResult<()> {
|
fn system_v_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
// The original 32-bit x86 ELF ABI had a 4-byte aligned stack pointer, but
|
// The original 32-bit x86 ELF ABI had a 4-byte aligned stack pointer, but
|
||||||
// newer versions use a 16-byte aligned stack pointer.
|
// newer versions use a 16-byte aligned stack pointer.
|
||||||
let stack_align = 16;
|
let stack_align = 16;
|
||||||
@@ -435,7 +435,7 @@ fn insert_common_prologue(
|
|||||||
stack_size: i64,
|
stack_size: i64,
|
||||||
reg_type: ir::types::Type,
|
reg_type: ir::types::Type,
|
||||||
csrs: &RegisterSet,
|
csrs: &RegisterSet,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
if stack_size > 0 {
|
if stack_size > 0 {
|
||||||
// Check if there is a special stack limit parameter. If so insert stack check.
|
// Check if there is a special stack limit parameter. If so insert stack check.
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ fn expand_sdivrem(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
isa: &isa::TargetIsa,
|
isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
let (x, y, is_srem) = match func.dfg[inst] {
|
let (x, y, is_srem) = match func.dfg[inst] {
|
||||||
ir::InstructionData::Binary {
|
ir::InstructionData::Binary {
|
||||||
@@ -225,7 +225,7 @@ fn expand_udivrem(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
isa: &isa::TargetIsa,
|
isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
let (x, y, is_urem) = match func.dfg[inst] {
|
let (x, y, is_urem) = match func.dfg[inst] {
|
||||||
ir::InstructionData::Binary {
|
ir::InstructionData::Binary {
|
||||||
@@ -278,7 +278,7 @@ fn expand_minmax(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &isa::TargetIsa,
|
_isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] {
|
let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] {
|
||||||
ir::InstructionData::Binary {
|
ir::InstructionData::Binary {
|
||||||
@@ -370,7 +370,7 @@ fn expand_fcvt_from_uint(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &isa::TargetIsa,
|
_isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
let x;
|
let x;
|
||||||
match func.dfg[inst] {
|
match func.dfg[inst] {
|
||||||
@@ -441,7 +441,7 @@ fn expand_fcvt_to_sint(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &isa::TargetIsa,
|
_isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
use crate::ir::immediates::{Ieee32, Ieee64};
|
use crate::ir::immediates::{Ieee32, Ieee64};
|
||||||
|
|
||||||
@@ -536,7 +536,7 @@ fn expand_fcvt_to_sint_sat(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &isa::TargetIsa,
|
_isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
use crate::ir::immediates::{Ieee32, Ieee64};
|
use crate::ir::immediates::{Ieee32, Ieee64};
|
||||||
|
|
||||||
@@ -655,7 +655,7 @@ fn expand_fcvt_to_uint(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &isa::TargetIsa,
|
_isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
use crate::ir::immediates::{Ieee32, Ieee64};
|
use crate::ir::immediates::{Ieee32, Ieee64};
|
||||||
|
|
||||||
@@ -736,7 +736,7 @@ fn expand_fcvt_to_uint_sat(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &isa::TargetIsa,
|
_isa: &dyn isa::TargetIsa,
|
||||||
) {
|
) {
|
||||||
use crate::ir::immediates::{Ieee32, Ieee64};
|
use crate::ir::immediates::{Ieee32, Ieee64};
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ fn isa_constructor(
|
|||||||
triple: Triple,
|
triple: Triple,
|
||||||
shared_flags: shared_settings::Flags,
|
shared_flags: shared_settings::Flags,
|
||||||
builder: shared_settings::Builder,
|
builder: shared_settings::Builder,
|
||||||
) -> Box<TargetIsa> {
|
) -> Box<dyn TargetIsa> {
|
||||||
let level1 = match triple.pointer_width().unwrap() {
|
let level1 = match triple.pointer_width().unwrap() {
|
||||||
PointerWidth::U16 => unimplemented!("x86-16"),
|
PointerWidth::U16 => unimplemented!("x86-16"),
|
||||||
PointerWidth::U32 => &enc_tables::LEVEL1_I32[..],
|
PointerWidth::U32 => &enc_tables::LEVEL1_I32[..],
|
||||||
@@ -123,7 +123,7 @@ impl TargetIsa for Isa {
|
|||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
divert: &mut regalloc::RegDiversions,
|
divert: &mut regalloc::RegDiversions,
|
||||||
sink: &mut CodeSink,
|
sink: &mut dyn CodeSink,
|
||||||
) {
|
) {
|
||||||
binemit::emit_inst(func, inst, divert, sink)
|
binemit::emit_inst(func, inst, divert, sink)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ use std::vec::Vec;
|
|||||||
/// This changes all signatures to be ABI-compliant with full `ArgumentLoc` annotations. It doesn't
|
/// This changes all signatures to be ABI-compliant with full `ArgumentLoc` annotations. It doesn't
|
||||||
/// change the entry block arguments, calls, or return instructions, so this can leave the function
|
/// change the entry block arguments, calls, or return instructions, so this can leave the function
|
||||||
/// in a state with type discrepancies.
|
/// in a state with type discrepancies.
|
||||||
pub fn legalize_signatures(func: &mut Function, isa: &TargetIsa) {
|
pub fn legalize_signatures(func: &mut Function, isa: &dyn TargetIsa) {
|
||||||
legalize_signature(&mut func.signature, true, isa);
|
legalize_signature(&mut func.signature, true, isa);
|
||||||
for sig_data in func.dfg.signatures.values_mut() {
|
for sig_data in func.dfg.signatures.values_mut() {
|
||||||
legalize_signature(sig_data, false, isa);
|
legalize_signature(sig_data, false, isa);
|
||||||
@@ -49,14 +49,14 @@ pub fn legalize_signatures(func: &mut Function, isa: &TargetIsa) {
|
|||||||
|
|
||||||
/// Legalize the libcall signature, which we may generate on the fly after
|
/// Legalize the libcall signature, which we may generate on the fly after
|
||||||
/// `legalize_signatures` has been called.
|
/// `legalize_signatures` has been called.
|
||||||
pub fn legalize_libcall_signature(signature: &mut Signature, isa: &TargetIsa) {
|
pub fn legalize_libcall_signature(signature: &mut Signature, isa: &dyn TargetIsa) {
|
||||||
legalize_signature(signature, false, isa);
|
legalize_signature(signature, false, isa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Legalize the given signature.
|
/// Legalize the given signature.
|
||||||
///
|
///
|
||||||
/// `current` is true if this is the signature for the current function.
|
/// `current` is true if this is the signature for the current function.
|
||||||
fn legalize_signature(signature: &mut Signature, current: bool, isa: &TargetIsa) {
|
fn legalize_signature(signature: &mut Signature, current: bool, isa: &dyn TargetIsa) {
|
||||||
isa.legalize_signature(signature, current);
|
isa.legalize_signature(signature, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pub fn expand_call(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Unpack the instruction.
|
// Unpack the instruction.
|
||||||
let (func_ref, old_args) = match func.dfg[inst] {
|
let (func_ref, old_args) = match func.dfg[inst] {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub fn expand_global_value(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Unpack the instruction.
|
// Unpack the instruction.
|
||||||
let gv = match func.dfg[inst] {
|
let gv = match func.dfg[inst] {
|
||||||
@@ -90,7 +90,7 @@ fn load_addr(
|
|||||||
offset: ir::immediates::Offset32,
|
offset: ir::immediates::Offset32,
|
||||||
global_type: ir::Type,
|
global_type: ir::Type,
|
||||||
readonly: bool,
|
readonly: bool,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// We need to load a pointer from the `base` global value, so insert a new `global_value`
|
// We need to load a pointer from the `base` global value, so insert a new `global_value`
|
||||||
// instruction. This depends on the iterative legalization loop. Note that the IR verifier
|
// instruction. This depends on the iterative legalization loop. Note that the IR verifier
|
||||||
@@ -123,7 +123,7 @@ fn load_addr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Expand a `global_value` instruction for a symbolic name global.
|
/// Expand a `global_value` instruction for a symbolic name global.
|
||||||
fn symbol(inst: ir::Inst, func: &mut ir::Function, gv: ir::GlobalValue, isa: &TargetIsa) {
|
fn symbol(inst: ir::Inst, func: &mut ir::Function, gv: ir::GlobalValue, isa: &dyn TargetIsa) {
|
||||||
let ptr_ty = isa.pointer_type();
|
let ptr_ty = isa.pointer_type();
|
||||||
func.dfg.replace(inst).symbol_value(ptr_ty, gv);
|
func.dfg.replace(inst).symbol_value(ptr_ty, gv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pub fn expand_heap_addr(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Unpack the instruction.
|
// Unpack the instruction.
|
||||||
let (heap, offset, access_size) = match func.dfg[inst] {
|
let (heap, offset, access_size) = match func.dfg[inst] {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::legalizer::boundary::legalize_libcall_signature;
|
|||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
/// Try to expand `inst` as a library call, returning true is successful.
|
/// Try to expand `inst` as a library call, returning true is successful.
|
||||||
pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &TargetIsa) -> bool {
|
pub fn expand_as_libcall(inst: ir::Inst, func: &mut ir::Function, isa: &dyn TargetIsa) -> bool {
|
||||||
// Does the opcode/ctrl_type combo even have a well-known runtime library name.
|
// Does the opcode/ctrl_type combo even have a well-known runtime library name.
|
||||||
let libcall = match ir::LibCall::for_inst(func.dfg[inst].opcode(), func.dfg.ctrl_typevar(inst))
|
let libcall = match ir::LibCall::for_inst(func.dfg[inst].opcode(), func.dfg.ctrl_typevar(inst))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fn legalize_inst(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
pos: &mut FuncCursor,
|
pos: &mut FuncCursor,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let opcode = pos.func.dfg[inst].opcode();
|
let opcode = pos.func.dfg[inst].opcode();
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ fn legalize_inst(
|
|||||||
/// - Transform any instructions that don't have a legal representation in `isa`.
|
/// - Transform any instructions that don't have a legal representation in `isa`.
|
||||||
/// - Fill out `func.encodings`.
|
/// - Fill out `func.encodings`.
|
||||||
///
|
///
|
||||||
pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: &TargetIsa) {
|
pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: &dyn TargetIsa) {
|
||||||
let _tt = timing::legalize();
|
let _tt = timing::legalize();
|
||||||
debug_assert!(cfg.is_valid());
|
debug_assert!(cfg.is_valid());
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ fn expand_cond_trap(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Parse the instruction.
|
// Parse the instruction.
|
||||||
let trapz;
|
let trapz;
|
||||||
@@ -179,7 +179,7 @@ fn expand_br_table(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
if isa.flags().jump_tables_enabled() {
|
if isa.flags().jump_tables_enabled() {
|
||||||
expand_br_table_jt(inst, func, cfg, isa);
|
expand_br_table_jt(inst, func, cfg, isa);
|
||||||
@@ -193,7 +193,7 @@ fn expand_br_table_jt(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
use crate::ir::condcodes::IntCC;
|
use crate::ir::condcodes::IntCC;
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ fn expand_br_table_conds(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
use crate::ir::condcodes::IntCC;
|
use crate::ir::condcodes::IntCC;
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ fn expand_select(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
let (ctrl, tval, fval) = match func.dfg[inst] {
|
let (ctrl, tval, fval) = match func.dfg[inst] {
|
||||||
ir::InstructionData::Ternary {
|
ir::InstructionData::Ternary {
|
||||||
@@ -315,7 +315,7 @@ fn expand_br_icmp(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
let (cond, a, b, destination, ebb_args) = match func.dfg[inst] {
|
let (cond, a, b, destination, ebb_args) = match func.dfg[inst] {
|
||||||
ir::InstructionData::BranchIcmp {
|
ir::InstructionData::BranchIcmp {
|
||||||
@@ -350,7 +350,7 @@ fn expand_fconst(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
let ty = func.dfg.value_type(func.dfg.first_result(inst));
|
let ty = func.dfg.value_type(func.dfg.first_result(inst));
|
||||||
debug_assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);
|
debug_assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);
|
||||||
@@ -378,7 +378,7 @@ fn expand_stack_load(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
let ty = func.dfg.value_type(func.dfg.first_result(inst));
|
let ty = func.dfg.value_type(func.dfg.first_result(inst));
|
||||||
let addr_ty = isa.pointer_type();
|
let addr_ty = isa.pointer_type();
|
||||||
@@ -410,7 +410,7 @@ fn expand_stack_store(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
let addr_ty = isa.pointer_type();
|
let addr_ty = isa.pointer_type();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn expand_table_addr(
|
|||||||
inst: ir::Inst,
|
inst: ir::Inst,
|
||||||
func: &mut ir::Function,
|
func: &mut ir::Function,
|
||||||
_cfg: &mut ControlFlowGraph,
|
_cfg: &mut ControlFlowGraph,
|
||||||
_isa: &TargetIsa,
|
_isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Unpack the instruction.
|
// Unpack the instruction.
|
||||||
let (table, index, element_offset) = match func.dfg[inst] {
|
let (table, index, element_offset) = match func.dfg[inst] {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use std::vec::Vec;
|
|||||||
/// loop-invariant instructions out of them.
|
/// loop-invariant instructions out of them.
|
||||||
/// Changes the CFG and domtree in-place during the operation.
|
/// Changes the CFG and domtree in-place during the operation.
|
||||||
pub fn do_licm(
|
pub fn do_licm(
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
domtree: &mut DominatorTree,
|
domtree: &mut DominatorTree,
|
||||||
@@ -64,7 +64,7 @@ pub fn do_licm(
|
|||||||
// Insert a pre-header before the header, modifying the function layout and CFG to reflect it.
|
// Insert a pre-header before the header, modifying the function layout and CFG to reflect it.
|
||||||
// A jump instruction to the header is placed at the end of the pre-header.
|
// A jump instruction to the header is placed at the end of the pre-header.
|
||||||
fn create_pre_header(
|
fn create_pre_header(
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
header: Ebb,
|
header: Ebb,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
cfg: &mut ControlFlowGraph,
|
cfg: &mut ControlFlowGraph,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ fn optimize_cpu_flags(
|
|||||||
pos: &mut EncCursor,
|
pos: &mut EncCursor,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
last_flags_clobber: Option<Inst>,
|
last_flags_clobber: Option<Inst>,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) {
|
||||||
// Look for compare and branch patterns.
|
// Look for compare and branch patterns.
|
||||||
// This code could be considerably simplified with non-lexical lifetimes.
|
// This code could be considerably simplified with non-lexical lifetimes.
|
||||||
@@ -179,7 +179,7 @@ struct MemOpInfo {
|
|||||||
offset: Offset32,
|
offset: Offset32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn optimize_complex_addresses(pos: &mut EncCursor, inst: Inst, isa: &TargetIsa) {
|
fn optimize_complex_addresses(pos: &mut EncCursor, inst: Inst, isa: &dyn TargetIsa) {
|
||||||
// Look for simple loads and stores we can optimize.
|
// Look for simple loads and stores we can optimize.
|
||||||
let info = match pos.func.dfg[inst] {
|
let info = match pos.func.dfg[inst] {
|
||||||
InstructionData::Load {
|
InstructionData::Load {
|
||||||
@@ -357,7 +357,7 @@ fn optimize_complex_addresses(pos: &mut EncCursor, inst: Inst, isa: &TargetIsa)
|
|||||||
//
|
//
|
||||||
// The main post-opt pass.
|
// The main post-opt pass.
|
||||||
|
|
||||||
pub fn do_postopt(func: &mut Function, isa: &TargetIsa) {
|
pub fn do_postopt(func: &mut Function, isa: &dyn TargetIsa) {
|
||||||
let _tt = timing::postopt();
|
let _tt = timing::postopt();
|
||||||
let mut pos = EncCursor::new(func, isa);
|
let mut pos = EncCursor::new(func, isa);
|
||||||
while let Some(_ebb) = pos.next_ebb() {
|
while let Some(_ebb) = pos.next_ebb() {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ use std::vec::Vec;
|
|||||||
/// Pretty-print a verifier error.
|
/// Pretty-print a verifier error.
|
||||||
pub fn pretty_verifier_error<'a>(
|
pub fn pretty_verifier_error<'a>(
|
||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
func_w: Option<Box<FuncWriter + 'a>>,
|
func_w: Option<Box<dyn FuncWriter + 'a>>,
|
||||||
errors: VerifierErrors,
|
errors: VerifierErrors,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut errors = errors.0;
|
let mut errors = errors.0;
|
||||||
@@ -44,14 +44,14 @@ pub fn pretty_verifier_error<'a>(
|
|||||||
w
|
w
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PrettyVerifierError<'a>(Box<FuncWriter + 'a>, &'a mut Vec<VerifierError>);
|
struct PrettyVerifierError<'a>(Box<dyn FuncWriter + 'a>, &'a mut Vec<VerifierError>);
|
||||||
|
|
||||||
impl<'a> FuncWriter for PrettyVerifierError<'a> {
|
impl<'a> FuncWriter for PrettyVerifierError<'a> {
|
||||||
fn write_ebb_header(
|
fn write_ebb_header(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
ebb: Ebb,
|
ebb: Ebb,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -60,10 +60,10 @@ impl<'a> FuncWriter for PrettyVerifierError<'a> {
|
|||||||
|
|
||||||
fn write_instruction(
|
fn write_instruction(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -72,10 +72,10 @@ impl<'a> FuncWriter for PrettyVerifierError<'a> {
|
|||||||
|
|
||||||
fn write_entity_definition(
|
fn write_entity_definition(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
entity: AnyEntity,
|
entity: AnyEntity,
|
||||||
value: &fmt::Display,
|
value: &dyn fmt::Display,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
pretty_preamble_error(w, func, entity, value, &mut *self.0, self.1)
|
pretty_preamble_error(w, func, entity, value, &mut *self.0, self.1)
|
||||||
}
|
}
|
||||||
@@ -83,12 +83,12 @@ impl<'a> FuncWriter for PrettyVerifierError<'a> {
|
|||||||
|
|
||||||
/// Pretty-print a function verifier error for a given EBB.
|
/// Pretty-print a function verifier error for a given EBB.
|
||||||
fn pretty_ebb_header_error(
|
fn pretty_ebb_header_error(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
cur_ebb: Ebb,
|
cur_ebb: Ebb,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
func_w: &mut FuncWriter,
|
func_w: &mut dyn FuncWriter,
|
||||||
errors: &mut Vec<VerifierError>,
|
errors: &mut Vec<VerifierError>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
@@ -121,13 +121,13 @@ fn pretty_ebb_header_error(
|
|||||||
|
|
||||||
/// Pretty-print a function verifier error for a given instruction.
|
/// Pretty-print a function verifier error for a given instruction.
|
||||||
fn pretty_instruction_error(
|
fn pretty_instruction_error(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
cur_inst: Inst,
|
cur_inst: Inst,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
func_w: &mut FuncWriter,
|
func_w: &mut dyn FuncWriter,
|
||||||
errors: &mut Vec<VerifierError>,
|
errors: &mut Vec<VerifierError>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
@@ -159,11 +159,11 @@ fn pretty_instruction_error(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pretty_preamble_error(
|
fn pretty_preamble_error(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
entity: AnyEntity,
|
entity: AnyEntity,
|
||||||
value: &fmt::Display,
|
value: &dyn fmt::Display,
|
||||||
func_w: &mut FuncWriter,
|
func_w: &mut dyn FuncWriter,
|
||||||
errors: &mut Vec<VerifierError>,
|
errors: &mut Vec<VerifierError>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
@@ -195,7 +195,7 @@ fn pretty_preamble_error(
|
|||||||
|
|
||||||
/// Prints:
|
/// Prints:
|
||||||
/// ; ^~~~~~
|
/// ; ^~~~~~
|
||||||
fn print_arrow(w: &mut Write, entity: &str) -> fmt::Result {
|
fn print_arrow(w: &mut dyn Write, entity: &str) -> fmt::Result {
|
||||||
write!(w, ";")?;
|
write!(w, ";")?;
|
||||||
|
|
||||||
let indent = entity.len() - entity.trim_start().len();
|
let indent = entity.len() - entity.trim_start().len();
|
||||||
@@ -212,13 +212,13 @@ fn print_arrow(w: &mut Write, entity: &str) -> fmt::Result {
|
|||||||
|
|
||||||
/// Prints:
|
/// Prints:
|
||||||
/// ; error: [ERROR BODY]
|
/// ; error: [ERROR BODY]
|
||||||
fn print_error(w: &mut Write, err: VerifierError) -> fmt::Result {
|
fn print_error(w: &mut dyn Write, err: VerifierError) -> fmt::Result {
|
||||||
writeln!(w, "; error: {}", err.to_string())?;
|
writeln!(w, "; error: {}", err.to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pretty-print a Cranelift error.
|
/// Pretty-print a Cranelift error.
|
||||||
pub fn pretty_error(func: &ir::Function, isa: Option<&TargetIsa>, err: CodegenError) -> String {
|
pub fn pretty_error(func: &ir::Function, isa: Option<&dyn TargetIsa>, err: CodegenError) -> String {
|
||||||
if let CodegenError::Verifier(e) = err {
|
if let CodegenError::Verifier(e) = err {
|
||||||
pretty_verifier_error(func, isa, None, e)
|
pretty_verifier_error(func, isa, None, e)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl Affinity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create an affinity that matches an ABI argument for `isa`.
|
/// Create an affinity that matches an ABI argument for `isa`.
|
||||||
pub fn abi(arg: &AbiParam, isa: &TargetIsa) -> Self {
|
pub fn abi(arg: &AbiParam, isa: &dyn TargetIsa) -> Self {
|
||||||
match arg.location {
|
match arg.location {
|
||||||
ArgumentLoc::Unassigned => Affinity::Unassigned,
|
ArgumentLoc::Unassigned => Affinity::Unassigned,
|
||||||
ArgumentLoc::Reg(_) => Affinity::Reg(isa.regclass_for_abi_type(arg.value_type).into()),
|
ArgumentLoc::Reg(_) => Affinity::Reg(isa.regclass_for_abi_type(arg.value_type).into()),
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ pub struct Coalescing {
|
|||||||
|
|
||||||
/// One-shot context created once per invocation.
|
/// One-shot context created once per invocation.
|
||||||
struct Context<'a> {
|
struct Context<'a> {
|
||||||
isa: &'a TargetIsa,
|
isa: &'a dyn TargetIsa,
|
||||||
encinfo: EncInfo,
|
encinfo: EncInfo,
|
||||||
|
|
||||||
func: &'a mut Function,
|
func: &'a mut Function,
|
||||||
@@ -108,7 +108,7 @@ impl Coalescing {
|
|||||||
/// Convert `func` to Conventional SSA form and build virtual registers in the process.
|
/// Convert `func` to Conventional SSA form and build virtual registers in the process.
|
||||||
pub fn conventional_ssa(
|
pub fn conventional_ssa(
|
||||||
&mut self,
|
&mut self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
cfg: &ControlFlowGraph,
|
cfg: &ControlFlowGraph,
|
||||||
domtree: &DominatorTree,
|
domtree: &DominatorTree,
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ impl Coloring {
|
|||||||
/// Run the coloring algorithm over `func`.
|
/// Run the coloring algorithm over `func`.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
domtree: &DominatorTree,
|
domtree: &DominatorTree,
|
||||||
liveness: &mut Liveness,
|
liveness: &mut Liveness,
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ impl Context {
|
|||||||
/// location that is consistent with instruction encoding constraints.
|
/// location that is consistent with instruction encoding constraints.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
cfg: &ControlFlowGraph,
|
cfg: &ControlFlowGraph,
|
||||||
domtree: &mut DominatorTree,
|
domtree: &mut DominatorTree,
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ type LiveRangeSet = SparseMap<Value, LiveRange>;
|
|||||||
fn get_or_create<'a>(
|
fn get_or_create<'a>(
|
||||||
lrset: &'a mut LiveRangeSet,
|
lrset: &'a mut LiveRangeSet,
|
||||||
value: Value,
|
value: Value,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
encinfo: &EncInfo,
|
encinfo: &EncInfo,
|
||||||
) -> &'a mut LiveRange {
|
) -> &'a mut LiveRange {
|
||||||
@@ -389,7 +389,7 @@ impl Liveness {
|
|||||||
|
|
||||||
/// Compute the live ranges of all SSA values used in `func`.
|
/// Compute the live ranges of all SSA values used in `func`.
|
||||||
/// This clears out any existing analysis stored in this data structure.
|
/// This clears out any existing analysis stored in this data structure.
|
||||||
pub fn compute(&mut self, isa: &TargetIsa, func: &mut Function, cfg: &ControlFlowGraph) {
|
pub fn compute(&mut self, isa: &dyn TargetIsa, func: &mut Function, cfg: &ControlFlowGraph) {
|
||||||
let _tt = timing::ra_liveness();
|
let _tt = timing::ra_liveness();
|
||||||
self.ranges.clear();
|
self.ranges.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ mod tests {
|
|||||||
use target_lexicon::triple;
|
use target_lexicon::triple;
|
||||||
|
|
||||||
// Make an arm32 `TargetIsa`, if possible.
|
// Make an arm32 `TargetIsa`, if possible.
|
||||||
fn arm32() -> Option<Box<TargetIsa>> {
|
fn arm32() -> Option<Box<dyn TargetIsa>> {
|
||||||
use crate::isa;
|
use crate::isa;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get a register class by name.
|
// Get a register class by name.
|
||||||
fn rc_by_name(isa: &TargetIsa, name: &str) -> RegClass {
|
fn rc_by_name(isa: &dyn TargetIsa, name: &str) -> RegClass {
|
||||||
isa.register_info()
|
isa.register_info()
|
||||||
.classes
|
.classes
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ impl Reload {
|
|||||||
/// Run the reload algorithm over `func`.
|
/// Run the reload algorithm over `func`.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
domtree: &DominatorTree,
|
domtree: &DominatorTree,
|
||||||
liveness: &mut Liveness,
|
liveness: &mut Liveness,
|
||||||
@@ -466,7 +466,7 @@ fn handle_abi_args(
|
|||||||
abi_types: &[AbiParam],
|
abi_types: &[AbiParam],
|
||||||
var_args: &[Value],
|
var_args: &[Value],
|
||||||
offset: usize,
|
offset: usize,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
liveness: &Liveness,
|
liveness: &Liveness,
|
||||||
) {
|
) {
|
||||||
debug_assert_eq!(abi_types.len(), var_args.len());
|
debug_assert_eq!(abi_types.len(), var_args.len());
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ impl fmt::Display for Move {
|
|||||||
|
|
||||||
impl fmt::Debug for Move {
|
impl fmt::Debug for Move {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let as_display: &fmt::Display = self;
|
let as_display: &dyn fmt::Display = self;
|
||||||
as_display.fmt(f)
|
as_display.fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1139,7 +1139,7 @@ mod tests {
|
|||||||
use target_lexicon::triple;
|
use target_lexicon::triple;
|
||||||
|
|
||||||
// Make an arm32 `TargetIsa`, if possible.
|
// Make an arm32 `TargetIsa`, if possible.
|
||||||
fn arm32() -> Option<Box<TargetIsa>> {
|
fn arm32() -> Option<Box<dyn TargetIsa>> {
|
||||||
use crate::isa;
|
use crate::isa;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ impl Spilling {
|
|||||||
/// Run the spilling algorithm over `func`.
|
/// Run the spilling algorithm over `func`.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
domtree: &DominatorTree,
|
domtree: &DominatorTree,
|
||||||
liveness: &mut Liveness,
|
liveness: &mut Liveness,
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ pub struct FlagsOrIsa<'a> {
|
|||||||
pub flags: &'a Flags,
|
pub flags: &'a Flags,
|
||||||
|
|
||||||
/// The ISA may not be present.
|
/// The ISA may not be present.
|
||||||
pub isa: Option<&'a TargetIsa>,
|
pub isa: Option<&'a dyn TargetIsa>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Flags> for FlagsOrIsa<'a> {
|
impl<'a> From<&'a Flags> for FlagsOrIsa<'a> {
|
||||||
@@ -355,8 +355,8 @@ impl<'a> From<&'a Flags> for FlagsOrIsa<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a TargetIsa> for FlagsOrIsa<'a> {
|
impl<'a> From<&'a dyn TargetIsa> for FlagsOrIsa<'a> {
|
||||||
fn from(isa: &'a TargetIsa) -> FlagsOrIsa {
|
fn from(isa: &'a dyn TargetIsa) -> FlagsOrIsa {
|
||||||
FlagsOrIsa {
|
FlagsOrIsa {
|
||||||
flags: isa.flags(),
|
flags: isa.flags(),
|
||||||
isa: Some(isa),
|
isa: Some(isa),
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ where
|
|||||||
pub fn build_value_labels_ranges<T>(
|
pub fn build_value_labels_ranges<T>(
|
||||||
func: &Function,
|
func: &Function,
|
||||||
regalloc: &Context,
|
regalloc: &Context,
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> ValueLabelsRanges
|
) -> ValueLabelsRanges
|
||||||
where
|
where
|
||||||
T: From<SourceLoc> + Deref<Target = SourceLoc> + Ord + Copy,
|
T: From<SourceLoc> + Deref<Target = SourceLoc> + Ord + Copy,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use crate::verifier::{VerifierErrors, VerifierStepResult};
|
|||||||
pub fn verify_flags(
|
pub fn verify_flags(
|
||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
cfg: &ControlFlowGraph,
|
cfg: &ControlFlowGraph,
|
||||||
isa: Option<&isa::TargetIsa>,
|
isa: Option<&dyn isa::TargetIsa>,
|
||||||
errors: &mut VerifierErrors,
|
errors: &mut VerifierErrors,
|
||||||
) -> VerifierStepResult<()> {
|
) -> VerifierStepResult<()> {
|
||||||
let _tt = timing::verify_flags();
|
let _tt = timing::verify_flags();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use core::cmp::Ordering;
|
|||||||
/// We don't verify that live ranges are minimal. This would require recomputing live ranges for
|
/// We don't verify that live ranges are minimal. This would require recomputing live ranges for
|
||||||
/// all values.
|
/// all values.
|
||||||
pub fn verify_liveness(
|
pub fn verify_liveness(
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
cfg: &ControlFlowGraph,
|
cfg: &ControlFlowGraph,
|
||||||
liveness: &Liveness,
|
liveness: &Liveness,
|
||||||
@@ -42,7 +42,7 @@ pub fn verify_liveness(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct LivenessVerifier<'a> {
|
struct LivenessVerifier<'a> {
|
||||||
isa: &'a TargetIsa,
|
isa: &'a dyn TargetIsa,
|
||||||
func: &'a Function,
|
func: &'a Function,
|
||||||
cfg: &'a ControlFlowGraph,
|
cfg: &'a ControlFlowGraph,
|
||||||
liveness: &'a Liveness,
|
liveness: &'a Liveness,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::verifier::{VerifierErrors, VerifierStepResult};
|
|||||||
/// If a liveness analysis is provided, it is used to verify that there are no active register
|
/// If a liveness analysis is provided, it is used to verify that there are no active register
|
||||||
/// diversions across control flow edges.
|
/// diversions across control flow edges.
|
||||||
pub fn verify_locations(
|
pub fn verify_locations(
|
||||||
isa: &isa::TargetIsa,
|
isa: &dyn isa::TargetIsa,
|
||||||
func: &ir::Function,
|
func: &ir::Function,
|
||||||
liveness: Option<&Liveness>,
|
liveness: Option<&Liveness>,
|
||||||
errors: &mut VerifierErrors,
|
errors: &mut VerifierErrors,
|
||||||
@@ -37,7 +37,7 @@ pub fn verify_locations(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct LocationVerifier<'a> {
|
struct LocationVerifier<'a> {
|
||||||
isa: &'a isa::TargetIsa,
|
isa: &'a dyn isa::TargetIsa,
|
||||||
func: &'a ir::Function,
|
func: &'a ir::Function,
|
||||||
reginfo: isa::RegInfo,
|
reginfo: isa::RegInfo,
|
||||||
encinfo: isa::EncInfo,
|
encinfo: isa::EncInfo,
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ struct Verifier<'a> {
|
|||||||
func: &'a Function,
|
func: &'a Function,
|
||||||
expected_cfg: ControlFlowGraph,
|
expected_cfg: ControlFlowGraph,
|
||||||
expected_domtree: DominatorTree,
|
expected_domtree: DominatorTree,
|
||||||
isa: Option<&'a TargetIsa>,
|
isa: Option<&'a dyn TargetIsa>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Verifier<'a> {
|
impl<'a> Verifier<'a> {
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ pub trait FuncWriter {
|
|||||||
/// Write the extended basic block header for the current function.
|
/// Write the extended basic block header for the current function.
|
||||||
fn write_ebb_header(
|
fn write_ebb_header(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
ebb: Ebb,
|
ebb: Ebb,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result;
|
) -> fmt::Result;
|
||||||
@@ -32,10 +32,10 @@ pub trait FuncWriter {
|
|||||||
/// Write the given `inst` to `w`.
|
/// Write the given `inst` to `w`.
|
||||||
fn write_instruction(
|
fn write_instruction(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result;
|
) -> fmt::Result;
|
||||||
@@ -43,7 +43,7 @@ pub trait FuncWriter {
|
|||||||
/// Write the preamble to `w`. By default, this uses `write_entity_definition`.
|
/// Write the preamble to `w`. By default, this uses `write_entity_definition`.
|
||||||
fn write_preamble(
|
fn write_preamble(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
regs: Option<&RegInfo>,
|
regs: Option<&RegInfo>,
|
||||||
) -> Result<bool, fmt::Error> {
|
) -> Result<bool, fmt::Error> {
|
||||||
@@ -53,7 +53,7 @@ pub trait FuncWriter {
|
|||||||
/// Default impl of `write_preamble`
|
/// Default impl of `write_preamble`
|
||||||
fn super_preamble(
|
fn super_preamble(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
regs: Option<&RegInfo>,
|
regs: Option<&RegInfo>,
|
||||||
) -> Result<bool, fmt::Error> {
|
) -> Result<bool, fmt::Error> {
|
||||||
@@ -108,10 +108,10 @@ pub trait FuncWriter {
|
|||||||
/// Write an entity definition defined in the preamble to `w`.
|
/// Write an entity definition defined in the preamble to `w`.
|
||||||
fn write_entity_definition(
|
fn write_entity_definition(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
entity: AnyEntity,
|
entity: AnyEntity,
|
||||||
value: &fmt::Display,
|
value: &dyn fmt::Display,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
self.super_entity_definition(w, func, entity, value)
|
self.super_entity_definition(w, func, entity, value)
|
||||||
}
|
}
|
||||||
@@ -120,10 +120,10 @@ pub trait FuncWriter {
|
|||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn super_entity_definition(
|
fn super_entity_definition(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
entity: AnyEntity,
|
entity: AnyEntity,
|
||||||
value: &fmt::Display,
|
value: &dyn fmt::Display,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
writeln!(w, " {} = {}", entity, value)
|
writeln!(w, " {} = {}", entity, value)
|
||||||
}
|
}
|
||||||
@@ -135,10 +135,10 @@ pub struct PlainWriter;
|
|||||||
impl FuncWriter for PlainWriter {
|
impl FuncWriter for PlainWriter {
|
||||||
fn write_instruction(
|
fn write_instruction(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -147,9 +147,9 @@ impl FuncWriter for PlainWriter {
|
|||||||
|
|
||||||
fn write_ebb_header(
|
fn write_ebb_header(
|
||||||
&mut self,
|
&mut self,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
ebb: Ebb,
|
ebb: Ebb,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -160,7 +160,7 @@ impl FuncWriter for PlainWriter {
|
|||||||
/// Write `func` to `w` as equivalent text.
|
/// Write `func` to `w` as equivalent text.
|
||||||
/// Use `isa` to emit ISA-dependent annotations.
|
/// Use `isa` to emit ISA-dependent annotations.
|
||||||
pub fn write_function(
|
pub fn write_function(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
annotations: &DisplayFunctionAnnotations,
|
annotations: &DisplayFunctionAnnotations,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -184,7 +184,7 @@ fn alias_map(func: &Function) -> SecondaryMap<Value, Vec<Value>> {
|
|||||||
/// pretty_function_error is passed as 'closure' to add error decoration.
|
/// pretty_function_error is passed as 'closure' to add error decoration.
|
||||||
pub fn decorate_function<FW: FuncWriter>(
|
pub fn decorate_function<FW: FuncWriter>(
|
||||||
func_w: &mut FW,
|
func_w: &mut FW,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
annotations: &DisplayFunctionAnnotations,
|
annotations: &DisplayFunctionAnnotations,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -210,7 +210,7 @@ pub fn decorate_function<FW: FuncWriter>(
|
|||||||
//
|
//
|
||||||
// Function spec.
|
// Function spec.
|
||||||
|
|
||||||
fn write_spec(w: &mut Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Result {
|
fn write_spec(w: &mut dyn Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Result {
|
||||||
write!(w, "{}{}", func.name, func.signature.display(regs))
|
write!(w, "{}{}", func.name, func.signature.display(regs))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +218,12 @@ fn write_spec(w: &mut Write, func: &Function, regs: Option<&RegInfo>) -> fmt::Re
|
|||||||
//
|
//
|
||||||
// Basic blocks
|
// Basic blocks
|
||||||
|
|
||||||
fn write_arg(w: &mut Write, func: &Function, regs: Option<&RegInfo>, arg: Value) -> fmt::Result {
|
fn write_arg(
|
||||||
|
w: &mut dyn Write,
|
||||||
|
func: &Function,
|
||||||
|
regs: Option<&RegInfo>,
|
||||||
|
arg: Value,
|
||||||
|
) -> fmt::Result {
|
||||||
write!(w, "{}: {}", arg, func.dfg.value_type(arg))?;
|
write!(w, "{}: {}", arg, func.dfg.value_type(arg))?;
|
||||||
let loc = func.locations[arg];
|
let loc = func.locations[arg];
|
||||||
if loc.is_assigned() {
|
if loc.is_assigned() {
|
||||||
@@ -235,9 +240,9 @@ fn write_arg(w: &mut Write, func: &Function, regs: Option<&RegInfo>, arg: Value)
|
|||||||
/// ebb10(v4: f64, v5: b1):
|
/// ebb10(v4: f64, v5: b1):
|
||||||
///
|
///
|
||||||
pub fn write_ebb_header(
|
pub fn write_ebb_header(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
ebb: Ebb,
|
ebb: Ebb,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -263,7 +268,7 @@ pub fn write_ebb_header(
|
|||||||
writeln!(w, "):")
|
writeln!(w, "):")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_valueloc(w: &mut Write, loc: &ValueLoc, regs: &RegInfo) -> fmt::Result {
|
fn write_valueloc(w: &mut dyn Write, loc: &ValueLoc, regs: &RegInfo) -> fmt::Result {
|
||||||
match loc {
|
match loc {
|
||||||
ValueLoc::Reg(r) => write!(w, "{}", regs.display_regunit(*r)),
|
ValueLoc::Reg(r) => write!(w, "{}", regs.display_regunit(*r)),
|
||||||
ValueLoc::Stack(ss) => write!(w, "{}", ss),
|
ValueLoc::Stack(ss) => write!(w, "{}", ss),
|
||||||
@@ -272,7 +277,7 @@ fn write_valueloc(w: &mut Write, loc: &ValueLoc, regs: &RegInfo) -> fmt::Result
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_value_range_markers(
|
fn write_value_range_markers(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
val_ranges: &ValueLabelsRanges,
|
val_ranges: &ValueLabelsRanges,
|
||||||
regs: &RegInfo,
|
regs: &RegInfo,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
@@ -306,7 +311,7 @@ fn write_value_range_markers(
|
|||||||
|
|
||||||
fn decorate_ebb<FW: FuncWriter>(
|
fn decorate_ebb<FW: FuncWriter>(
|
||||||
func_w: &mut FW,
|
func_w: &mut FW,
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
annotations: &DisplayFunctionAnnotations,
|
annotations: &DisplayFunctionAnnotations,
|
||||||
@@ -385,7 +390,7 @@ fn type_suffix(func: &Function, inst: Inst) -> Option<Type> {
|
|||||||
|
|
||||||
/// Write out any aliases to the given target, including indirect aliases
|
/// Write out any aliases to the given target, including indirect aliases
|
||||||
fn write_value_aliases(
|
fn write_value_aliases(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
target: Value,
|
target: Value,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
@@ -402,10 +407,10 @@ fn write_value_aliases(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_instruction(
|
fn write_instruction(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
aliases: &SecondaryMap<Value, Vec<Value>>,
|
aliases: &SecondaryMap<Value, Vec<Value>>,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
@@ -472,9 +477,9 @@ fn write_instruction(
|
|||||||
|
|
||||||
/// Write the operands of `inst` to `w` with a prepended space.
|
/// Write the operands of `inst` to `w` with a prepended space.
|
||||||
pub fn write_operands(
|
pub fn write_operands(
|
||||||
w: &mut Write,
|
w: &mut dyn Write,
|
||||||
dfg: &DataFlowGraph,
|
dfg: &DataFlowGraph,
|
||||||
isa: Option<&TargetIsa>,
|
isa: Option<&dyn TargetIsa>,
|
||||||
inst: Inst,
|
inst: Inst,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
let pool = &dfg.value_lists;
|
let pool = &dfg.value_lists;
|
||||||
@@ -687,7 +692,7 @@ pub fn write_operands(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write EBB args using optional parantheses.
|
/// Write EBB args using optional parantheses.
|
||||||
fn write_ebb_args(w: &mut Write, args: &[Value]) -> fmt::Result {
|
fn write_ebb_args(w: &mut dyn Write, args: &[Value]) -> fmt::Result {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ macro_rules! entity_impl {
|
|||||||
|
|
||||||
impl $crate::__core::fmt::Debug for $entity {
|
impl $crate::__core::fmt::Debug for $entity {
|
||||||
fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
|
fn fmt(&self, f: &mut $crate::__core::fmt::Formatter) -> $crate::__core::fmt::Result {
|
||||||
(self as &$crate::__core::fmt::Display).fmt(f)
|
(self as &dyn $crate::__core::fmt::Display).fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ pub enum FaerieTrapCollection {
|
|||||||
|
|
||||||
/// A builder for `FaerieBackend`.
|
/// A builder for `FaerieBackend`.
|
||||||
pub struct FaerieBuilder {
|
pub struct FaerieBuilder {
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<dyn TargetIsa>,
|
||||||
name: String,
|
name: String,
|
||||||
collect_traps: FaerieTrapCollection,
|
collect_traps: FaerieTrapCollection,
|
||||||
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FaerieBuilder {
|
impl FaerieBuilder {
|
||||||
@@ -48,10 +48,10 @@ impl FaerieBuilder {
|
|||||||
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
||||||
/// argument, use `cranelift_module::default_libcall_names()`.
|
/// argument, use `cranelift_module::default_libcall_names()`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<dyn TargetIsa>,
|
||||||
name: String,
|
name: String,
|
||||||
collect_traps: FaerieTrapCollection,
|
collect_traps: FaerieTrapCollection,
|
||||||
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||||
) -> ModuleResult<Self> {
|
) -> ModuleResult<Self> {
|
||||||
if !isa.flags().is_pic() {
|
if !isa.flags().is_pic() {
|
||||||
return Err(ModuleError::Backend(
|
return Err(ModuleError::Backend(
|
||||||
@@ -71,10 +71,10 @@ impl FaerieBuilder {
|
|||||||
///
|
///
|
||||||
/// See the `FaerieBuilder` for a convenient way to construct `FaerieBackend` instances.
|
/// See the `FaerieBuilder` for a convenient way to construct `FaerieBackend` instances.
|
||||||
pub struct FaerieBackend {
|
pub struct FaerieBackend {
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<dyn TargetIsa>,
|
||||||
artifact: faerie::Artifact,
|
artifact: faerie::Artifact,
|
||||||
trap_manifest: Option<FaerieTrapManifest>,
|
trap_manifest: Option<FaerieTrapManifest>,
|
||||||
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FaerieCompiledFunction {
|
pub struct FaerieCompiledFunction {
|
||||||
@@ -117,7 +117,7 @@ impl Backend for FaerieBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn isa(&self) -> &TargetIsa {
|
fn isa(&self) -> &dyn TargetIsa {
|
||||||
&*self.isa
|
&*self.isa
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,7 +361,7 @@ struct FaerieRelocSink<'a> {
|
|||||||
artifact: &'a mut faerie::Artifact,
|
artifact: &'a mut faerie::Artifact,
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
namespace: &'a ModuleNamespace<'a, FaerieBackend>,
|
namespace: &'a ModuleNamespace<'a, FaerieBackend>,
|
||||||
libcall_names: &'a Fn(ir::LibCall) -> String,
|
libcall_names: &'a dyn Fn(ir::LibCall) -> String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RelocSink for FaerieRelocSink<'a> {
|
impl<'a> RelocSink for FaerieRelocSink<'a> {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ pub fn run_passes(
|
|||||||
///
|
///
|
||||||
/// This function knows how to create all of the possible `test <foo>` commands that can appear in
|
/// This function knows how to create all of the possible `test <foo>` commands that can appear in
|
||||||
/// a `.clif` test file.
|
/// a `.clif` test file.
|
||||||
fn new_subtest(parsed: &TestCommand) -> subtest::SubtestResult<Box<subtest::SubTest>> {
|
fn new_subtest(parsed: &TestCommand) -> subtest::SubtestResult<Box<dyn subtest::SubTest>> {
|
||||||
match parsed.command {
|
match parsed.command {
|
||||||
"binemit" => test_binemit::subtest(parsed),
|
"binemit" => test_binemit::subtest(parsed),
|
||||||
"cat" => test_cat::subtest(parsed),
|
"cat" => test_cat::subtest(parsed),
|
||||||
|
|||||||
@@ -102,10 +102,10 @@ pub fn run(path: &Path, passes: Option<&[String]>, target: Option<&str>) -> Test
|
|||||||
|
|
||||||
// Given a slice of tests, generate a vector of (test, flags, isa) tuples.
|
// Given a slice of tests, generate a vector of (test, flags, isa) tuples.
|
||||||
fn test_tuples<'a>(
|
fn test_tuples<'a>(
|
||||||
tests: &'a [Box<SubTest>],
|
tests: &'a [Box<dyn SubTest>],
|
||||||
isa_spec: &'a IsaSpec,
|
isa_spec: &'a IsaSpec,
|
||||||
no_isa_flags: &'a Flags,
|
no_isa_flags: &'a Flags,
|
||||||
) -> SubtestResult<Vec<(&'a SubTest, &'a Flags, Option<&'a TargetIsa>)>> {
|
) -> SubtestResult<Vec<(&'a dyn SubTest, &'a Flags, Option<&'a dyn TargetIsa>)>> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
for test in tests {
|
for test in tests {
|
||||||
if test.needs_isa() {
|
if test.needs_isa() {
|
||||||
@@ -131,7 +131,7 @@ fn test_tuples<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_one_test<'a>(
|
fn run_one_test<'a>(
|
||||||
tuple: (&'a SubTest, &'a Flags, Option<&'a TargetIsa>),
|
tuple: (&'a dyn SubTest, &'a Flags, Option<&'a dyn TargetIsa>),
|
||||||
func: Cow<Function>,
|
func: Cow<Function>,
|
||||||
context: &mut Context<'a>,
|
context: &mut Context<'a>,
|
||||||
) -> SubtestResult<()> {
|
) -> SubtestResult<()> {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub struct Context<'a> {
|
|||||||
|
|
||||||
/// Target ISA to test against. Only guaranteed to be present for sub-tests whose `needs_isa`
|
/// Target ISA to test against. Only guaranteed to be present for sub-tests whose `needs_isa`
|
||||||
/// method returned `true`. For other sub-tests, this is set if the test file has a unique ISA.
|
/// method returned `true`. For other sub-tests, this is set if the test file has a unique ISA.
|
||||||
pub isa: Option<&'a TargetIsa>,
|
pub isa: Option<&'a dyn TargetIsa>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<'a> Context<'a> {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
struct TestBinEmit;
|
struct TestBinEmit;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "binemit");
|
assert_eq!(parsed.command, "binemit");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use std::borrow::Cow;
|
|||||||
/// The result is verified by filecheck.
|
/// The result is verified by filecheck.
|
||||||
struct TestCat;
|
struct TestCat;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "cat");
|
assert_eq!(parsed.command, "cat");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestCompile;
|
struct TestCompile;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "compile");
|
assert_eq!(parsed.command, "compile");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestDCE;
|
struct TestDCE;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "dce");
|
assert_eq!(parsed.command, "dce");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use std::fmt::{self, Write};
|
|||||||
|
|
||||||
struct TestDomtree;
|
struct TestDomtree;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "domtree");
|
assert_eq!(parsed.command, "domtree");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestLegalizer;
|
struct TestLegalizer;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "legalizer");
|
assert_eq!(parsed.command, "legalizer");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestLICM;
|
struct TestLICM;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "licm");
|
assert_eq!(parsed.command, "licm");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestPostopt;
|
struct TestPostopt;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "postopt");
|
assert_eq!(parsed.command, "postopt");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestPreopt;
|
struct TestPreopt;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "preopt");
|
assert_eq!(parsed.command, "preopt");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use cranelift_reader::TestCommand;
|
|||||||
/// Object implementing the `test print-cfg` sub-test.
|
/// Object implementing the `test print-cfg` sub-test.
|
||||||
struct TestPrintCfg;
|
struct TestPrintCfg;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "print-cfg");
|
assert_eq!(parsed.command, "print-cfg");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestRegalloc;
|
struct TestRegalloc;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "regalloc");
|
assert_eq!(parsed.command, "regalloc");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestShrink;
|
struct TestShrink;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "shrink");
|
assert_eq!(parsed.command, "shrink");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestSimpleGVN;
|
struct TestSimpleGVN;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "simple-gvn");
|
assert_eq!(parsed.command, "simple-gvn");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
struct TestSimplePreopt;
|
struct TestSimplePreopt;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "simple_preopt");
|
assert_eq!(parsed.command, "simple_preopt");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
struct TestVerifier;
|
struct TestVerifier;
|
||||||
|
|
||||||
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<SubTest>> {
|
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
|
||||||
assert_eq!(parsed.command, "verifier");
|
assert_eq!(parsed.command, "verifier");
|
||||||
if !parsed.options.is_empty() {
|
if !parsed.options.is_empty() {
|
||||||
Err(format!("No options allowed on {}", parsed))
|
Err(format!("No options allowed on {}", parsed))
|
||||||
|
|||||||
@@ -571,7 +571,7 @@ impl<'a> FunctionBuilder<'a> {
|
|||||||
/// Useful for debug purposes. Use it with `None` for standard printing.
|
/// Useful for debug purposes. Use it with `None` for standard printing.
|
||||||
// Clippy thinks the lifetime that follows is needless, but rustc needs it
|
// Clippy thinks the lifetime that follows is needless, but rustc needs it
|
||||||
#[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_lifetimes))]
|
#[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_lifetimes))]
|
||||||
pub fn display<'b, I: Into<Option<&'b TargetIsa>>>(&'b self, isa: I) -> DisplayFunction {
|
pub fn display<'b, I: Into<Option<&'b dyn TargetIsa>>>(&'b self, isa: I) -> DisplayFunction {
|
||||||
self.func.display(isa)
|
self.func.display(isa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ where
|
|||||||
fn new(_: Self::Builder) -> Self;
|
fn new(_: Self::Builder) -> Self;
|
||||||
|
|
||||||
/// Return the `TargetIsa` to compile for.
|
/// Return the `TargetIsa` to compile for.
|
||||||
fn isa(&self) -> &TargetIsa;
|
fn isa(&self) -> &dyn TargetIsa;
|
||||||
|
|
||||||
/// Declare a function.
|
/// Declare a function.
|
||||||
fn declare_function(&mut self, name: &str, linkage: Linkage);
|
fn declare_function(&mut self, name: &str, linkage: Linkage);
|
||||||
@@ -135,7 +135,7 @@ where
|
|||||||
|
|
||||||
/// Default names for `ir::LibCall`s. A function by this name is imported into the object as
|
/// Default names for `ir::LibCall`s. A function by this name is imported into the object as
|
||||||
/// part of the translation of a `ir::ExternalName::LibCall` variant.
|
/// part of the translation of a `ir::ExternalName::LibCall` variant.
|
||||||
pub fn default_libcall_names() -> Box<Fn(ir::LibCall) -> String> {
|
pub fn default_libcall_names() -> Box<dyn Fn(ir::LibCall) -> String> {
|
||||||
Box::new(move |libcall| match libcall {
|
Box::new(move |libcall| match libcall {
|
||||||
ir::LibCall::Probestack => "__cranelift_probestack".to_owned(),
|
ir::LibCall::Probestack => "__cranelift_probestack".to_owned(),
|
||||||
ir::LibCall::CeilF32 => "ceilf".to_owned(),
|
ir::LibCall::CeilF32 => "ceilf".to_owned(),
|
||||||
|
|||||||
@@ -690,7 +690,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the target isa
|
/// Return the target isa
|
||||||
pub fn isa(&self) -> &isa::TargetIsa {
|
pub fn isa(&self) -> &dyn isa::TargetIsa {
|
||||||
self.backend.isa()
|
self.backend.isa()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ use cranelift_codegen::{isa::TargetIsa, settings::FlagsOrIsa, CodegenResult, Con
|
|||||||
/// Since this can be resource intensive (and code-size inflating),
|
/// Since this can be resource intensive (and code-size inflating),
|
||||||
/// it is separated from `Context::compile` to allow DCE to remove it
|
/// it is separated from `Context::compile` to allow DCE to remove it
|
||||||
/// if it's not used.
|
/// if it's not used.
|
||||||
pub fn optimize(ctx: &mut Context, isa: &TargetIsa) -> CodegenResult<()> {
|
pub fn optimize(ctx: &mut Context, isa: &dyn TargetIsa) -> CodegenResult<()> {
|
||||||
ctx.verify_if(isa)?;
|
ctx.verify_if(isa)?;
|
||||||
fold_constants(ctx, isa)?;
|
fold_constants(ctx, isa)?;
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ pub enum IsaSpec {
|
|||||||
|
|
||||||
/// The parsed file does contain `isa` commands.
|
/// The parsed file does contain `isa` commands.
|
||||||
/// Each `isa` command is used to configure a `TargetIsa` trait object.
|
/// Each `isa` command is used to configure a `TargetIsa` trait object.
|
||||||
Some(Vec<Box<TargetIsa>>),
|
Some(Vec<Box<dyn TargetIsa>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsaSpec {
|
impl IsaSpec {
|
||||||
/// If the `IsaSpec` contains exactly 1 `TargetIsa` we return a reference to it
|
/// If the `IsaSpec` contains exactly 1 `TargetIsa` we return a reference to it
|
||||||
pub fn unique_isa(&self) -> Option<&TargetIsa> {
|
pub fn unique_isa(&self) -> Option<&dyn TargetIsa> {
|
||||||
if let IsaSpec::Some(ref isa_vec) = *self {
|
if let IsaSpec::Some(ref isa_vec) = *self {
|
||||||
if isa_vec.len() == 1 {
|
if isa_vec.len() == 1 {
|
||||||
return Some(&*isa_vec[0]);
|
return Some(&*isa_vec[0]);
|
||||||
@@ -35,7 +35,11 @@ impl IsaSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an iterator of command line options and apply them to `config`.
|
/// Parse an iterator of command line options and apply them to `config`.
|
||||||
pub fn parse_options<'a, I>(iter: I, config: &mut Configurable, loc: Location) -> ParseResult<()>
|
pub fn parse_options<'a, I>(
|
||||||
|
iter: I,
|
||||||
|
config: &mut dyn Configurable,
|
||||||
|
loc: Location,
|
||||||
|
) -> ParseResult<()>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = &'a str>,
|
I: Iterator<Item = &'a str>,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,11 +113,11 @@ struct Context<'a> {
|
|||||||
/// information. This is only `Some` if exactly one set of `isa` directives were found in the
|
/// information. This is only `Some` if exactly one set of `isa` directives were found in the
|
||||||
/// prologue (it is valid to have directives for multiple different targets, but in that case
|
/// prologue (it is valid to have directives for multiple different targets, but in that case
|
||||||
/// we couldn't know which target the provided encodings are intended for)
|
/// we couldn't know which target the provided encodings are intended for)
|
||||||
unique_isa: Option<&'a TargetIsa>,
|
unique_isa: Option<&'a dyn TargetIsa>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<'a> Context<'a> {
|
||||||
fn new(f: Function, unique_isa: Option<&'a TargetIsa>) -> Self {
|
fn new(f: Function, unique_isa: Option<&'a dyn TargetIsa>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
function: f,
|
function: f,
|
||||||
map: SourceMap::new(),
|
map: SourceMap::new(),
|
||||||
@@ -720,7 +720,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Match and consume a register unit either by number `%15` or by name `%rax`.
|
// Match and consume a register unit either by number `%15` or by name `%rax`.
|
||||||
fn match_regunit(&mut self, isa: Option<&TargetIsa>) -> ParseResult<RegUnit> {
|
fn match_regunit(&mut self, isa: Option<&dyn TargetIsa>) -> ParseResult<RegUnit> {
|
||||||
if let Some(Token::Name(name)) = self.token() {
|
if let Some(Token::Name(name)) = self.token() {
|
||||||
self.consume();
|
self.consume();
|
||||||
match isa {
|
match isa {
|
||||||
@@ -891,7 +891,7 @@ impl<'a> Parser<'a> {
|
|||||||
/// This is the top-level parse function matching the whole contents of a file.
|
/// This is the top-level parse function matching the whole contents of a file.
|
||||||
pub fn parse_function_list(
|
pub fn parse_function_list(
|
||||||
&mut self,
|
&mut self,
|
||||||
unique_isa: Option<&TargetIsa>,
|
unique_isa: Option<&dyn TargetIsa>,
|
||||||
) -> ParseResult<Vec<(Function, Details<'a>)>> {
|
) -> ParseResult<Vec<(Function, Details<'a>)>> {
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
while self.token().is_some() {
|
while self.token().is_some() {
|
||||||
@@ -911,7 +911,7 @@ impl<'a> Parser<'a> {
|
|||||||
//
|
//
|
||||||
fn parse_function(
|
fn parse_function(
|
||||||
&mut self,
|
&mut self,
|
||||||
unique_isa: Option<&TargetIsa>,
|
unique_isa: Option<&dyn TargetIsa>,
|
||||||
) -> ParseResult<(Function, Details<'a>)> {
|
) -> ParseResult<(Function, Details<'a>)> {
|
||||||
// Begin gathering comments.
|
// Begin gathering comments.
|
||||||
// Make sure we don't include any comments before the `function` keyword.
|
// Make sure we don't include any comments before the `function` keyword.
|
||||||
@@ -999,7 +999,7 @@ impl<'a> Parser<'a> {
|
|||||||
//
|
//
|
||||||
// signature ::= * "(" [paramlist] ")" ["->" retlist] [callconv]
|
// signature ::= * "(" [paramlist] ")" ["->" retlist] [callconv]
|
||||||
//
|
//
|
||||||
fn parse_signature(&mut self, unique_isa: Option<&TargetIsa>) -> ParseResult<Signature> {
|
fn parse_signature(&mut self, unique_isa: Option<&dyn TargetIsa>) -> ParseResult<Signature> {
|
||||||
// Calling convention defaults to `fast`, but can be changed.
|
// Calling convention defaults to `fast`, but can be changed.
|
||||||
let mut sig = Signature::new(CallConv::Fast);
|
let mut sig = Signature::new(CallConv::Fast);
|
||||||
|
|
||||||
@@ -1033,7 +1033,7 @@ impl<'a> Parser<'a> {
|
|||||||
//
|
//
|
||||||
fn parse_abi_param_list(
|
fn parse_abi_param_list(
|
||||||
&mut self,
|
&mut self,
|
||||||
unique_isa: Option<&TargetIsa>,
|
unique_isa: Option<&dyn TargetIsa>,
|
||||||
) -> ParseResult<Vec<AbiParam>> {
|
) -> ParseResult<Vec<AbiParam>> {
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
@@ -1050,7 +1050,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse a single argument type with flags.
|
// Parse a single argument type with flags.
|
||||||
fn parse_abi_param(&mut self, unique_isa: Option<&TargetIsa>) -> ParseResult<AbiParam> {
|
fn parse_abi_param(&mut self, unique_isa: Option<&dyn TargetIsa>) -> ParseResult<AbiParam> {
|
||||||
// abi-param ::= * type { flag } [ argumentloc ]
|
// abi-param ::= * type { flag } [ argumentloc ]
|
||||||
let mut arg = AbiParam::new(self.match_type("expected parameter type")?);
|
let mut arg = AbiParam::new(self.match_type("expected parameter type")?);
|
||||||
|
|
||||||
@@ -1079,7 +1079,7 @@ impl<'a> Parser<'a> {
|
|||||||
// Parse an argument location specifier; either a register or a byte offset into the stack.
|
// Parse an argument location specifier; either a register or a byte offset into the stack.
|
||||||
fn parse_argument_location(
|
fn parse_argument_location(
|
||||||
&mut self,
|
&mut self,
|
||||||
unique_isa: Option<&TargetIsa>,
|
unique_isa: Option<&dyn TargetIsa>,
|
||||||
) -> ParseResult<ArgumentLoc> {
|
) -> ParseResult<ArgumentLoc> {
|
||||||
// argumentloc ::= '[' regname | uimm32 ']'
|
// argumentloc ::= '[' regname | uimm32 ']'
|
||||||
if self.optional(Token::LBracket) {
|
if self.optional(Token::LBracket) {
|
||||||
@@ -1426,7 +1426,7 @@ impl<'a> Parser<'a> {
|
|||||||
//
|
//
|
||||||
fn parse_signature_decl(
|
fn parse_signature_decl(
|
||||||
&mut self,
|
&mut self,
|
||||||
unique_isa: Option<&TargetIsa>,
|
unique_isa: Option<&dyn TargetIsa>,
|
||||||
) -> ParseResult<(SigRef, Signature)> {
|
) -> ParseResult<(SigRef, Signature)> {
|
||||||
let sig = self.match_sig("expected signature number: sig«n»")?;
|
let sig = self.match_sig("expected signature number: sig«n»")?;
|
||||||
self.match_token(Token::Equal, "expected '=' in signature decl")?;
|
self.match_token(Token::Equal, "expected '=' in signature decl")?;
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ const READONLY_DATA_ALIGNMENT: u8 = 0x1;
|
|||||||
|
|
||||||
/// A builder for `SimpleJITBackend`.
|
/// A builder for `SimpleJITBackend`.
|
||||||
pub struct SimpleJITBuilder {
|
pub struct SimpleJITBuilder {
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<dyn TargetIsa>,
|
||||||
symbols: HashMap<String, *const u8>,
|
symbols: HashMap<String, *const u8>,
|
||||||
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleJITBuilder {
|
impl SimpleJITBuilder {
|
||||||
@@ -35,7 +35,7 @@ impl SimpleJITBuilder {
|
|||||||
/// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
|
/// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
|
||||||
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
||||||
/// argument, use `cranelift_module::default_libcall_names()`.
|
/// argument, use `cranelift_module::default_libcall_names()`.
|
||||||
pub fn new(libcall_names: Box<Fn(ir::LibCall) -> String>) -> Self {
|
pub fn new(libcall_names: Box<dyn Fn(ir::LibCall) -> String>) -> Self {
|
||||||
let flag_builder = settings::builder();
|
let flag_builder = settings::builder();
|
||||||
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
|
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
|
||||||
panic!("host machine is not supported: {}", msg);
|
panic!("host machine is not supported: {}", msg);
|
||||||
@@ -56,7 +56,10 @@ impl SimpleJITBuilder {
|
|||||||
/// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
|
/// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
|
||||||
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
/// floating point instructions, and for stack probes. If you don't know what to use for this
|
||||||
/// argument, use `cranelift_module::default_libcall_names()`.
|
/// argument, use `cranelift_module::default_libcall_names()`.
|
||||||
pub fn with_isa(isa: Box<TargetIsa>, libcall_names: Box<Fn(ir::LibCall) -> String>) -> Self {
|
pub fn with_isa(
|
||||||
|
isa: Box<dyn TargetIsa>,
|
||||||
|
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||||
|
) -> Self {
|
||||||
debug_assert!(!isa.flags().is_pic(), "SimpleJIT requires non-PIC code");
|
debug_assert!(!isa.flags().is_pic(), "SimpleJIT requires non-PIC code");
|
||||||
let symbols = HashMap::new();
|
let symbols = HashMap::new();
|
||||||
Self {
|
Self {
|
||||||
@@ -108,9 +111,9 @@ impl SimpleJITBuilder {
|
|||||||
///
|
///
|
||||||
/// See the `SimpleJITBuilder` for a convenient way to construct `SimpleJITBackend` instances.
|
/// See the `SimpleJITBuilder` for a convenient way to construct `SimpleJITBackend` instances.
|
||||||
pub struct SimpleJITBackend {
|
pub struct SimpleJITBackend {
|
||||||
isa: Box<TargetIsa>,
|
isa: Box<dyn TargetIsa>,
|
||||||
symbols: HashMap<String, *const u8>,
|
symbols: HashMap<String, *const u8>,
|
||||||
libcall_names: Box<Fn(ir::LibCall) -> String>,
|
libcall_names: Box<dyn Fn(ir::LibCall) -> String>,
|
||||||
code_memory: Memory,
|
code_memory: Memory,
|
||||||
readonly_memory: Memory,
|
readonly_memory: Memory,
|
||||||
writable_memory: Memory,
|
writable_memory: Memory,
|
||||||
@@ -205,7 +208,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn isa(&self) -> &TargetIsa {
|
fn isa(&self) -> &dyn TargetIsa {
|
||||||
&*self.isa
|
&*self.isa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ cfg_if! {
|
|||||||
use capstone::prelude::*;
|
use capstone::prelude::*;
|
||||||
use target_lexicon::Architecture;
|
use target_lexicon::Architecture;
|
||||||
|
|
||||||
fn get_disassembler(isa: &TargetIsa) -> Result<Capstone, String> {
|
fn get_disassembler(isa: &dyn TargetIsa) -> Result<Capstone, String> {
|
||||||
let cs = match isa.triple().architecture {
|
let cs = match isa.triple().architecture {
|
||||||
Architecture::Riscv32 | Architecture::Riscv64 => {
|
Architecture::Riscv32 | Architecture::Riscv64 => {
|
||||||
return Err(String::from("No disassembler for RiscV"))
|
return Err(String::from("No disassembler for RiscV"))
|
||||||
@@ -117,7 +117,7 @@ cfg_if! {
|
|||||||
cs.map_err(|err| err.to_string())
|
cs.map_err(|err| err.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_disassembly(isa: &TargetIsa, mem: &[u8]) -> Result<(), String> {
|
pub fn print_disassembly(isa: &dyn TargetIsa, mem: &[u8]) -> Result<(), String> {
|
||||||
let mut cs = get_disassembler(isa)?;
|
let mut cs = get_disassembler(isa)?;
|
||||||
|
|
||||||
println!("\nDisassembly of {} bytes:", mem.len());
|
println!("\nDisassembly of {} bytes:", mem.len());
|
||||||
@@ -156,7 +156,7 @@ cfg_if! {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pub fn print_disassembly(_: &TargetIsa, _: &[u8]) -> Result<(), String> {
|
pub fn print_disassembly(_: &dyn TargetIsa, _: &[u8]) -> Result<(), String> {
|
||||||
println!("\nNo disassembly available.");
|
println!("\nNo disassembly available.");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ cfg_if! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_all(
|
pub fn print_all(
|
||||||
isa: &TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
mem: &[u8],
|
mem: &[u8],
|
||||||
code_size: u32,
|
code_size: u32,
|
||||||
rodata_size: u32,
|
rodata_size: u32,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub fn read_to_end<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
|
|||||||
/// Like `FlagsOrIsa`, but holds ownership.
|
/// Like `FlagsOrIsa`, but holds ownership.
|
||||||
pub enum OwnedFlagsOrIsa {
|
pub enum OwnedFlagsOrIsa {
|
||||||
Flags(settings::Flags),
|
Flags(settings::Flags),
|
||||||
Isa(Box<TargetIsa>),
|
Isa(Box<dyn TargetIsa>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedFlagsOrIsa {
|
impl OwnedFlagsOrIsa {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use wasmparser::{ModuleReader, SectionCode};
|
|||||||
/// [`Function`](../codegen/ir/function/struct.Function.html).
|
/// [`Function`](../codegen/ir/function/struct.Function.html).
|
||||||
pub fn translate_module<'data>(
|
pub fn translate_module<'data>(
|
||||||
data: &'data [u8],
|
data: &'data [u8],
|
||||||
environ: &mut ModuleEnvironment<'data>,
|
environ: &mut dyn ModuleEnvironment<'data>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
let _tt = timing::wasm_translate_module();
|
let _tt = timing::wasm_translate_module();
|
||||||
let mut reader = ModuleReader::new(data)?;
|
let mut reader = ModuleReader::new(data)?;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use wasmparser::{
|
|||||||
/// Parses the Type section of the wasm module.
|
/// Parses the Type section of the wasm module.
|
||||||
pub fn parse_type_section(
|
pub fn parse_type_section(
|
||||||
types: TypeSectionReader,
|
types: TypeSectionReader,
|
||||||
environ: &mut ModuleEnvironment,
|
environ: &mut dyn ModuleEnvironment,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_signatures(types.get_count());
|
environ.reserve_signatures(types.get_count());
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ pub fn parse_type_section(
|
|||||||
/// Parses the Import section of the wasm module.
|
/// Parses the Import section of the wasm module.
|
||||||
pub fn parse_import_section<'data>(
|
pub fn parse_import_section<'data>(
|
||||||
imports: ImportSectionReader<'data>,
|
imports: ImportSectionReader<'data>,
|
||||||
environ: &mut ModuleEnvironment<'data>,
|
environ: &mut dyn ModuleEnvironment<'data>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_imports(imports.get_count());
|
environ.reserve_imports(imports.get_count());
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ pub fn parse_import_section<'data>(
|
|||||||
/// Parses the Function section of the wasm module.
|
/// Parses the Function section of the wasm module.
|
||||||
pub fn parse_function_section(
|
pub fn parse_function_section(
|
||||||
functions: FunctionSectionReader,
|
functions: FunctionSectionReader,
|
||||||
environ: &mut ModuleEnvironment,
|
environ: &mut dyn ModuleEnvironment,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_func_types(functions.get_count());
|
environ.reserve_func_types(functions.get_count());
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ pub fn parse_function_section(
|
|||||||
/// Parses the Table section of the wasm module.
|
/// Parses the Table section of the wasm module.
|
||||||
pub fn parse_table_section(
|
pub fn parse_table_section(
|
||||||
tables: TableSectionReader,
|
tables: TableSectionReader,
|
||||||
environ: &mut ModuleEnvironment,
|
environ: &mut dyn ModuleEnvironment,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_tables(tables.get_count());
|
environ.reserve_tables(tables.get_count());
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ pub fn parse_table_section(
|
|||||||
/// Parses the Memory section of the wasm module.
|
/// Parses the Memory section of the wasm module.
|
||||||
pub fn parse_memory_section(
|
pub fn parse_memory_section(
|
||||||
memories: MemorySectionReader,
|
memories: MemorySectionReader,
|
||||||
environ: &mut ModuleEnvironment,
|
environ: &mut dyn ModuleEnvironment,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_memories(memories.get_count());
|
environ.reserve_memories(memories.get_count());
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ pub fn parse_memory_section(
|
|||||||
/// Parses the Global section of the wasm module.
|
/// Parses the Global section of the wasm module.
|
||||||
pub fn parse_global_section(
|
pub fn parse_global_section(
|
||||||
globals: GlobalSectionReader,
|
globals: GlobalSectionReader,
|
||||||
environ: &mut ModuleEnvironment,
|
environ: &mut dyn ModuleEnvironment,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_globals(globals.get_count());
|
environ.reserve_globals(globals.get_count());
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ pub fn parse_global_section(
|
|||||||
/// Parses the Export section of the wasm module.
|
/// Parses the Export section of the wasm module.
|
||||||
pub fn parse_export_section<'data>(
|
pub fn parse_export_section<'data>(
|
||||||
exports: ExportSectionReader<'data>,
|
exports: ExportSectionReader<'data>,
|
||||||
environ: &mut ModuleEnvironment<'data>,
|
environ: &mut dyn ModuleEnvironment<'data>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_exports(exports.get_count());
|
environ.reserve_exports(exports.get_count());
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ pub fn parse_export_section<'data>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the Start section of the wasm module.
|
/// Parses the Start section of the wasm module.
|
||||||
pub fn parse_start_section(index: u32, environ: &mut ModuleEnvironment) -> WasmResult<()> {
|
pub fn parse_start_section(index: u32, environ: &mut dyn ModuleEnvironment) -> WasmResult<()> {
|
||||||
environ.declare_start_func(FuncIndex::from_u32(index));
|
environ.declare_start_func(FuncIndex::from_u32(index));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ pub fn parse_start_section(index: u32, environ: &mut ModuleEnvironment) -> WasmR
|
|||||||
/// Parses the Element section of the wasm module.
|
/// Parses the Element section of the wasm module.
|
||||||
pub fn parse_element_section<'data>(
|
pub fn parse_element_section<'data>(
|
||||||
elements: ElementSectionReader<'data>,
|
elements: ElementSectionReader<'data>,
|
||||||
environ: &mut ModuleEnvironment,
|
environ: &mut dyn ModuleEnvironment,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_table_elements(elements.get_count());
|
environ.reserve_table_elements(elements.get_count());
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ pub fn parse_element_section<'data>(
|
|||||||
/// Parses the Code section of the wasm module.
|
/// Parses the Code section of the wasm module.
|
||||||
pub fn parse_code_section<'data>(
|
pub fn parse_code_section<'data>(
|
||||||
code: CodeSectionReader<'data>,
|
code: CodeSectionReader<'data>,
|
||||||
environ: &mut ModuleEnvironment<'data>,
|
environ: &mut dyn ModuleEnvironment<'data>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
for body in code {
|
for body in code {
|
||||||
let mut reader = body?.get_binary_reader();
|
let mut reader = body?.get_binary_reader();
|
||||||
@@ -306,7 +306,7 @@ pub fn parse_code_section<'data>(
|
|||||||
/// Parses the Data section of the wasm module.
|
/// Parses the Data section of the wasm module.
|
||||||
pub fn parse_data_section<'data>(
|
pub fn parse_data_section<'data>(
|
||||||
data: DataSectionReader<'data>,
|
data: DataSectionReader<'data>,
|
||||||
environ: &mut ModuleEnvironment<'data>,
|
environ: &mut dyn ModuleEnvironment<'data>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
environ.reserve_data_initializers(data.get_count());
|
environ.reserve_data_initializers(data.get_count());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user