cranelift: Introduce a feature to enable trace logs (#4484)
* Don't use `log::trace` directly but a feature-enabled `trace` macro * Don't emit disassembly based on the log level
This commit is contained in:
@@ -54,6 +54,9 @@ core = ["hashbrown"]
|
|||||||
# can significantly increase the size of the library.
|
# can significantly increase the size of the library.
|
||||||
testing_hooks = []
|
testing_hooks = []
|
||||||
|
|
||||||
|
# Enables detailed logging which can be somewhat expensive.
|
||||||
|
trace-log = []
|
||||||
|
|
||||||
# This enables unwind info generation functionality.
|
# This enables unwind info generation functionality.
|
||||||
unwind = ["gimli"]
|
unwind = ["gimli"]
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ use crate::{
|
|||||||
has_memory_fence_semantics, inst_addr_offset_type, inst_store_data, visit_block_succs,
|
has_memory_fence_semantics, inst_addr_offset_type, inst_store_data, visit_block_succs,
|
||||||
},
|
},
|
||||||
ir::{immediates::Offset32, Block, Function, Inst, Opcode, Type, Value},
|
ir::{immediates::Offset32, Block, Function, Inst, Opcode, Type, Value},
|
||||||
|
trace,
|
||||||
};
|
};
|
||||||
use cranelift_entity::{packed_option::PackedOption, EntityRef};
|
use cranelift_entity::{packed_option::PackedOption, EntityRef};
|
||||||
|
|
||||||
@@ -198,7 +199,7 @@ pub struct AliasAnalysis<'a> {
|
|||||||
impl<'a> AliasAnalysis<'a> {
|
impl<'a> AliasAnalysis<'a> {
|
||||||
/// Perform an alias analysis pass.
|
/// Perform an alias analysis pass.
|
||||||
pub fn new(func: &'a mut Function, domtree: &'a DominatorTree) -> AliasAnalysis<'a> {
|
pub fn new(func: &'a mut Function, domtree: &'a DominatorTree) -> AliasAnalysis<'a> {
|
||||||
log::trace!("alias analysis: input is:\n{:?}", func);
|
trace!("alias analysis: input is:\n{:?}", func);
|
||||||
let mut analysis = AliasAnalysis {
|
let mut analysis = AliasAnalysis {
|
||||||
func,
|
func,
|
||||||
domtree,
|
domtree,
|
||||||
@@ -225,7 +226,7 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
.or_insert_with(|| LastStores::default())
|
.or_insert_with(|| LastStores::default())
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
log::trace!(
|
trace!(
|
||||||
"alias analysis: input to block{} is {:?}",
|
"alias analysis: input to block{} is {:?}",
|
||||||
block.index(),
|
block.index(),
|
||||||
state
|
state
|
||||||
@@ -233,7 +234,7 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
|
|
||||||
for inst in self.func.layout.block_insts(block) {
|
for inst in self.func.layout.block_insts(block) {
|
||||||
state.update(self.func, inst);
|
state.update(self.func, inst);
|
||||||
log::trace!("after inst{}: state is {:?}", inst.index(), state);
|
trace!("after inst{}: state is {:?}", inst.index(), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
visit_block_succs(self.func, block, |_inst, succ| {
|
visit_block_succs(self.func, block, |_inst, succ| {
|
||||||
@@ -279,7 +280,7 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
.unwrap_or_else(|| LastStores::default());
|
.unwrap_or_else(|| LastStores::default());
|
||||||
|
|
||||||
while let Some(inst) = pos.next_inst() {
|
while let Some(inst) = pos.next_inst() {
|
||||||
log::trace!(
|
trace!(
|
||||||
"alias analysis: scanning at inst{} with state {:?} ({:?})",
|
"alias analysis: scanning at inst{} with state {:?} ({:?})",
|
||||||
inst.index(),
|
inst.index(),
|
||||||
state,
|
state,
|
||||||
@@ -300,7 +301,7 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
ty,
|
ty,
|
||||||
extending_opcode: get_ext_opcode(opcode),
|
extending_opcode: get_ext_opcode(opcode),
|
||||||
};
|
};
|
||||||
log::trace!(
|
trace!(
|
||||||
"alias analysis: at inst{}: store with data v{} at loc {:?}",
|
"alias analysis: at inst{}: store with data v{} at loc {:?}",
|
||||||
inst.index(),
|
inst.index(),
|
||||||
store_data.index(),
|
store_data.index(),
|
||||||
@@ -317,7 +318,7 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
ty,
|
ty,
|
||||||
extending_opcode: get_ext_opcode(opcode),
|
extending_opcode: get_ext_opcode(opcode),
|
||||||
};
|
};
|
||||||
log::trace!(
|
trace!(
|
||||||
"alias analysis: at inst{}: load with last_store inst{} at loc {:?}",
|
"alias analysis: at inst{}: load with last_store inst{} at loc {:?}",
|
||||||
inst.index(),
|
inst.index(),
|
||||||
last_store.map(|inst| inst.index()).unwrap_or(usize::MAX),
|
last_store.map(|inst| inst.index()).unwrap_or(usize::MAX),
|
||||||
@@ -337,13 +338,13 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
let aliased = if let Some((def_inst, value)) =
|
let aliased = if let Some((def_inst, value)) =
|
||||||
self.mem_values.get(&mem_loc).cloned()
|
self.mem_values.get(&mem_loc).cloned()
|
||||||
{
|
{
|
||||||
log::trace!(
|
trace!(
|
||||||
" -> sees known value v{} from inst{}",
|
" -> sees known value v{} from inst{}",
|
||||||
value.index(),
|
value.index(),
|
||||||
def_inst.index()
|
def_inst.index()
|
||||||
);
|
);
|
||||||
if self.domtree.dominates(def_inst, inst, &pos.func.layout) {
|
if self.domtree.dominates(def_inst, inst, &pos.func.layout) {
|
||||||
log::trace!(
|
trace!(
|
||||||
" -> dominates; value equiv from v{} to v{} inserted",
|
" -> dominates; value equiv from v{} to v{} inserted",
|
||||||
load_result.index(),
|
load_result.index(),
|
||||||
value.index()
|
value.index()
|
||||||
@@ -363,7 +364,7 @@ impl<'a> AliasAnalysis<'a> {
|
|||||||
// Otherwise, we can keep *this* load around
|
// Otherwise, we can keep *this* load around
|
||||||
// as a new equivalent value.
|
// as a new equivalent value.
|
||||||
if !aliased {
|
if !aliased {
|
||||||
log::trace!(
|
trace!(
|
||||||
" -> inserting load result v{} at loc {:?}",
|
" -> inserting load result v{} at loc {:?}",
|
||||||
load_result.index(),
|
load_result.index(),
|
||||||
mem_loc
|
mem_loc
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::ir::dfg::DataFlowGraph;
|
|||||||
use crate::ir::progpoint::{ExpandedProgramPoint, ProgramOrder};
|
use crate::ir::progpoint::{ExpandedProgramPoint, ProgramOrder};
|
||||||
use crate::ir::{Block, Inst};
|
use crate::ir::{Block, Inst};
|
||||||
use crate::packed_option::PackedOption;
|
use crate::packed_option::PackedOption;
|
||||||
use crate::timing;
|
use crate::{timing, trace};
|
||||||
use core::cmp;
|
use core::cmp;
|
||||||
use core::iter::{IntoIterator, Iterator};
|
use core::iter::{IntoIterator, Iterator};
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ impl Layout {
|
|||||||
next_inst = self.insts[inst].next.expand();
|
next_inst = self.insts[inst].next.expand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log::trace!("Renumbered {} program points", seq / MAJOR_STRIDE);
|
trace!("Renumbered {} program points", seq / MAJOR_STRIDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use crate::ir::types::*;
|
|||||||
use crate::ir::{LibCall, MemFlags, TrapCode};
|
use crate::ir::{LibCall, MemFlags, TrapCode};
|
||||||
use crate::isa::aarch64::inst::*;
|
use crate::isa::aarch64::inst::*;
|
||||||
use crate::machinst::{ty_bits, Reg, RegClass, Writable};
|
use crate::machinst::{ty_bits, Reg, RegClass, Writable};
|
||||||
|
use crate::trace;
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
|
|
||||||
/// Memory label/reference finalization: convert a MemLabel to a PC-relative
|
/// Memory label/reference finalization: convert a MemLabel to a PC-relative
|
||||||
@@ -39,7 +40,7 @@ pub fn mem_finalize(
|
|||||||
};
|
};
|
||||||
let adj = match mem {
|
let adj = match mem {
|
||||||
&AMode::NominalSPOffset(..) => {
|
&AMode::NominalSPOffset(..) => {
|
||||||
log::trace!(
|
trace!(
|
||||||
"mem_finalize: nominal SP offset {} + adj {} -> {}",
|
"mem_finalize: nominal SP offset {} + adj {} -> {}",
|
||||||
off,
|
off,
|
||||||
state.virtual_sp_offset,
|
state.virtual_sp_offset,
|
||||||
@@ -3068,7 +3069,7 @@ impl MachInstEmit for Inst {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Inst::VirtualSPOffsetAdj { offset } => {
|
&Inst::VirtualSPOffsetAdj { offset } => {
|
||||||
log::trace!(
|
trace!(
|
||||||
"virtual sp offset adjusted by {} -> {}",
|
"virtual sp offset adjusted by {} -> {}",
|
||||||
offset,
|
offset,
|
||||||
state.virtual_sp_offset + offset,
|
state.virtual_sp_offset + offset,
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ use crate::ir::{Opcode, Type, Value};
|
|||||||
use crate::isa::aarch64::inst::*;
|
use crate::isa::aarch64::inst::*;
|
||||||
use crate::isa::aarch64::AArch64Backend;
|
use crate::isa::aarch64::AArch64Backend;
|
||||||
use crate::machinst::lower::*;
|
use crate::machinst::lower::*;
|
||||||
use crate::machinst::*;
|
|
||||||
use crate::machinst::{Reg, Writable};
|
use crate::machinst::{Reg, Writable};
|
||||||
|
use crate::{machinst::*, trace};
|
||||||
use crate::{CodegenError, CodegenResult};
|
use crate::{CodegenError, CodegenResult};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@@ -236,7 +236,7 @@ fn lower_value_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
value: Value,
|
value: Value,
|
||||||
) -> (ValueRegs<Reg>, Type, bool) {
|
) -> (ValueRegs<Reg>, Type, bool) {
|
||||||
log::trace!("lower_value_to_regs: value {:?}", value);
|
trace!("lower_value_to_regs: value {:?}", value);
|
||||||
let ty = ctx.value_ty(value);
|
let ty = ctx.value_ty(value);
|
||||||
let inputs = ctx.get_value_as_source_or_const(value);
|
let inputs = ctx.get_value_as_source_or_const(value);
|
||||||
let is_const = inputs.constant.is_some();
|
let is_const = inputs.constant.is_some();
|
||||||
@@ -608,7 +608,7 @@ pub(crate) fn lower_pair_address<C: LowerCtx<I = Inst>>(
|
|||||||
let (mut addends64, mut addends32, args_offset) = collect_address_addends(ctx, roots);
|
let (mut addends64, mut addends32, args_offset) = collect_address_addends(ctx, roots);
|
||||||
let offset = args_offset + (offset as i64);
|
let offset = args_offset + (offset as i64);
|
||||||
|
|
||||||
log::trace!(
|
trace!(
|
||||||
"lower_pair_address: addends64 {:?}, addends32 {:?}, offset {}",
|
"lower_pair_address: addends64 {:?}, addends32 {:?}, offset {}",
|
||||||
addends64,
|
addends64,
|
||||||
addends32,
|
addends32,
|
||||||
@@ -669,7 +669,7 @@ pub(crate) fn lower_address<C: LowerCtx<I = Inst>>(
|
|||||||
let (mut addends64, mut addends32, args_offset) = collect_address_addends(ctx, roots);
|
let (mut addends64, mut addends32, args_offset) = collect_address_addends(ctx, roots);
|
||||||
let mut offset = args_offset + (offset as i64);
|
let mut offset = args_offset + (offset as i64);
|
||||||
|
|
||||||
log::trace!(
|
trace!(
|
||||||
"lower_address: addends64 {:?}, addends32 {:?}, offset {}",
|
"lower_address: addends64 {:?}, addends32 {:?}, offset {}",
|
||||||
addends64,
|
addends64,
|
||||||
addends32,
|
addends32,
|
||||||
@@ -1120,7 +1120,7 @@ pub(crate) fn maybe_input_insn<C: LowerCtx<I = Inst>>(
|
|||||||
op: Opcode,
|
op: Opcode,
|
||||||
) -> Option<IRInst> {
|
) -> Option<IRInst> {
|
||||||
let inputs = c.get_input_as_source_or_const(input.insn, input.input);
|
let inputs = c.get_input_as_source_or_const(input.insn, input.input);
|
||||||
log::trace!(
|
trace!(
|
||||||
"maybe_input_insn: input {:?} has options {:?}; looking for op {:?}",
|
"maybe_input_insn: input {:?} has options {:?}; looking for op {:?}",
|
||||||
input,
|
input,
|
||||||
inputs,
|
inputs,
|
||||||
@@ -1128,7 +1128,7 @@ pub(crate) fn maybe_input_insn<C: LowerCtx<I = Inst>>(
|
|||||||
);
|
);
|
||||||
if let Some((src_inst, _)) = inputs.inst.as_inst() {
|
if let Some((src_inst, _)) = inputs.inst.as_inst() {
|
||||||
let data = c.data(src_inst);
|
let data = c.data(src_inst);
|
||||||
log::trace!(" -> input inst {:?}", data);
|
trace!(" -> input inst {:?}", data);
|
||||||
if data.opcode() == op {
|
if data.opcode() == op {
|
||||||
return Some(src_inst);
|
return Some(src_inst);
|
||||||
}
|
}
|
||||||
@@ -1228,7 +1228,7 @@ pub(crate) fn lower_icmp<C: LowerCtx<I = Inst>>(
|
|||||||
condcode: IntCC,
|
condcode: IntCC,
|
||||||
output: IcmpOutput,
|
output: IcmpOutput,
|
||||||
) -> CodegenResult<IcmpResult> {
|
) -> CodegenResult<IcmpResult> {
|
||||||
log::trace!(
|
trace!(
|
||||||
"lower_icmp: insn {}, condcode: {}, output: {:?}",
|
"lower_icmp: insn {}, condcode: {}, output: {:?}",
|
||||||
insn,
|
insn,
|
||||||
condcode,
|
condcode,
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ impl TargetIsa for AArch64Backend {
|
|||||||
let flags = self.flags();
|
let flags = self.flags();
|
||||||
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
|
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
|
||||||
|
|
||||||
let want_disasm = want_disasm || log::log_enabled!(log::Level::Debug);
|
|
||||||
let emit_result = vcode.emit(®alloc_result, want_disasm, flags.machine_code_cfg_info());
|
let emit_result = vcode.emit(®alloc_result, want_disasm, flags.machine_code_cfg_info());
|
||||||
let frame_size = emit_result.frame_size;
|
let frame_size = emit_result.frame_size;
|
||||||
let value_labels_ranges = emit_result.value_labels_ranges;
|
let value_labels_ranges = emit_result.value_labels_ranges;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use crate::isa::s390x::inst::*;
|
|||||||
use crate::isa::s390x::settings as s390x_settings;
|
use crate::isa::s390x::settings as s390x_settings;
|
||||||
use crate::machinst::reg::count_operands;
|
use crate::machinst::reg::count_operands;
|
||||||
use crate::machinst::{Reg, RegClass};
|
use crate::machinst::{Reg, RegClass};
|
||||||
|
use crate::trace;
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use regalloc2::Allocation;
|
use regalloc2::Allocation;
|
||||||
|
|
||||||
@@ -3239,7 +3240,7 @@ impl MachInstEmit for Inst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&Inst::VirtualSPOffsetAdj { offset } => {
|
&Inst::VirtualSPOffsetAdj { offset } => {
|
||||||
log::trace!(
|
trace!(
|
||||||
"virtual sp offset adjusted by {} -> {}",
|
"virtual sp offset adjusted by {} -> {}",
|
||||||
offset,
|
offset,
|
||||||
state.virtual_sp_offset + offset
|
state.virtual_sp_offset + offset
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ impl TargetIsa for S390xBackend {
|
|||||||
let flags = self.flags();
|
let flags = self.flags();
|
||||||
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
|
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
|
||||||
|
|
||||||
let want_disasm = want_disasm || log::log_enabled!(log::Level::Debug);
|
|
||||||
let emit_result = vcode.emit(®alloc_result, want_disasm, flags.machine_code_cfg_info());
|
let emit_result = vcode.emit(®alloc_result, want_disasm, flags.machine_code_cfg_info());
|
||||||
let frame_size = emit_result.frame_size;
|
let frame_size = emit_result.frame_size;
|
||||||
let value_labels_ranges = emit_result.value_labels_ranges;
|
let value_labels_ranges = emit_result.value_labels_ranges;
|
||||||
|
|||||||
@@ -2789,7 +2789,7 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inst::VirtualSPOffsetAdj { offset } => {
|
Inst::VirtualSPOffsetAdj { offset } => {
|
||||||
log::trace!(
|
trace!(
|
||||||
"virtual sp offset adjusted by {} -> {}",
|
"virtual sp offset adjusted by {} -> {}",
|
||||||
offset,
|
offset,
|
||||||
state.virtual_sp_offset + offset
|
state.virtual_sp_offset + offset
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use crate::isa::x64::abi::X64ABIMachineSpec;
|
|||||||
use crate::isa::x64::inst::regs::pretty_print_reg;
|
use crate::isa::x64::inst::regs::pretty_print_reg;
|
||||||
use crate::isa::x64::settings as x64_settings;
|
use crate::isa::x64::settings as x64_settings;
|
||||||
use crate::isa::CallConv;
|
use crate::isa::CallConv;
|
||||||
use crate::machinst::*;
|
use crate::{machinst::*, trace};
|
||||||
use crate::{settings, CodegenError, CodegenResult};
|
use crate::{settings, CodegenError, CodegenResult};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@@ -2236,7 +2236,7 @@ impl MachInst for Inst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn gen_move(dst_reg: Writable<Reg>, src_reg: Reg, ty: Type) -> Inst {
|
fn gen_move(dst_reg: Writable<Reg>, src_reg: Reg, ty: Type) -> Inst {
|
||||||
log::trace!(
|
trace!(
|
||||||
"Inst::gen_move {:?} -> {:?} (type: {:?})",
|
"Inst::gen_move {:?} -> {:?} (type: {:?})",
|
||||||
src_reg,
|
src_reg,
|
||||||
dst_reg.to_reg(),
|
dst_reg.to_reg(),
|
||||||
|
|||||||
@@ -14,11 +14,10 @@ use crate::isa::x64::inst::args::*;
|
|||||||
use crate::isa::x64::inst::*;
|
use crate::isa::x64::inst::*;
|
||||||
use crate::isa::{x64::settings as x64_settings, x64::X64Backend, CallConv};
|
use crate::isa::{x64::settings as x64_settings, x64::X64Backend, CallConv};
|
||||||
use crate::machinst::lower::*;
|
use crate::machinst::lower::*;
|
||||||
use crate::machinst::*;
|
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
use crate::settings::{Flags, TlsModel};
|
use crate::settings::{Flags, TlsModel};
|
||||||
|
use crate::{machinst::*, trace};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use log::trace;
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ impl TargetIsa for X64Backend {
|
|||||||
let flags = self.flags();
|
let flags = self.flags();
|
||||||
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
|
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
|
||||||
|
|
||||||
let want_disasm = want_disasm || log::log_enabled!(log::Level::Debug);
|
|
||||||
let emit_result = vcode.emit(®alloc_result, want_disasm, flags.machine_code_cfg_info());
|
let emit_result = vcode.emit(®alloc_result, want_disasm, flags.machine_code_cfg_info());
|
||||||
let frame_size = emit_result.frame_size;
|
let frame_size = emit_result.frame_size;
|
||||||
let value_labels_ranges = emit_result.value_labels_ranges;
|
let value_labels_ranges = emit_result.value_labels_ranges;
|
||||||
|
|||||||
@@ -116,4 +116,15 @@ mod souper_harvest;
|
|||||||
|
|
||||||
pub use crate::result::{CodegenError, CodegenResult};
|
pub use crate::result::{CodegenError, CodegenResult};
|
||||||
|
|
||||||
|
/// Even when trace logging is disabled, the trace macro has a significant performance cost so we
|
||||||
|
/// disable it by default.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! trace {
|
||||||
|
($($tt:tt)*) => {
|
||||||
|
if cfg!(feature = "trace-log") {
|
||||||
|
::log::trace!($($tt)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/version.rs"));
|
include!(concat!(env!("OUT_DIR"), "/version.rs"));
|
||||||
|
|||||||
@@ -128,10 +128,10 @@ use crate::binemit::StackMap;
|
|||||||
use crate::ir::types::*;
|
use crate::ir::types::*;
|
||||||
use crate::ir::{ArgumentExtension, ArgumentPurpose, DynamicStackSlot, Signature, StackSlot};
|
use crate::ir::{ArgumentExtension, ArgumentPurpose, DynamicStackSlot, Signature, StackSlot};
|
||||||
use crate::isa::TargetIsa;
|
use crate::isa::TargetIsa;
|
||||||
use crate::machinst::*;
|
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
use crate::CodegenResult;
|
use crate::CodegenResult;
|
||||||
use crate::{ir, isa};
|
use crate::{ir, isa};
|
||||||
|
use crate::{machinst::*, trace};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use regalloc2::{PReg, PRegSet};
|
use regalloc2::{PReg, PRegSet};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
@@ -596,7 +596,7 @@ impl ABISig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!(
|
trace!(
|
||||||
"ABISig: sig {:?} => args = {:?} rets = {:?} arg stack = {} ret stack = {} stack_ret_arg = {:?} copy_to_arg_order = {:?}",
|
"ABISig: sig {:?} => args = {:?} rets = {:?} arg stack = {} ret stack = {} stack_ret_arg = {:?} copy_to_arg_order = {:?}",
|
||||||
sig,
|
sig,
|
||||||
args,
|
args,
|
||||||
@@ -791,7 +791,7 @@ fn get_special_purpose_param_register(
|
|||||||
impl<M: ABIMachineSpec> ABICalleeImpl<M> {
|
impl<M: ABIMachineSpec> ABICalleeImpl<M> {
|
||||||
/// Create a new body ABI instance.
|
/// Create a new body ABI instance.
|
||||||
pub fn new(f: &ir::Function, isa: &dyn TargetIsa) -> CodegenResult<Self> {
|
pub fn new(f: &ir::Function, isa: &dyn TargetIsa) -> CodegenResult<Self> {
|
||||||
log::trace!("ABI: func signature {:?}", f.signature);
|
trace!("ABI: func signature {:?}", f.signature);
|
||||||
|
|
||||||
let flags = isa.flags().clone();
|
let flags = isa.flags().clone();
|
||||||
let ir_sig = ensure_struct_return_ptr_is_returned(&f.signature);
|
let ir_sig = ensure_struct_return_ptr_is_returned(&f.signature);
|
||||||
@@ -1265,14 +1265,14 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
|
|||||||
if let Some(i) = self.sig.stack_ret_arg {
|
if let Some(i) = self.sig.stack_ret_arg {
|
||||||
let insts = self.gen_copy_arg_to_regs(i, ValueRegs::one(self.ret_area_ptr.unwrap()));
|
let insts = self.gen_copy_arg_to_regs(i, ValueRegs::one(self.ret_area_ptr.unwrap()));
|
||||||
let inst = insts.into_iter().next().unwrap();
|
let inst = insts.into_iter().next().unwrap();
|
||||||
log::trace!(
|
trace!(
|
||||||
"gen_retval_area_setup: inst {:?}; ptr reg is {:?}",
|
"gen_retval_area_setup: inst {:?}; ptr reg is {:?}",
|
||||||
inst,
|
inst,
|
||||||
self.ret_area_ptr.unwrap().to_reg()
|
self.ret_area_ptr.unwrap().to_reg()
|
||||||
);
|
);
|
||||||
Some(inst)
|
Some(inst)
|
||||||
} else {
|
} else {
|
||||||
log::trace!("gen_retval_area_setup: not needed");
|
trace!("gen_retval_area_setup: not needed");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1347,7 +1347,7 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
|
|||||||
let islot = slot.index() as i64;
|
let islot = slot.index() as i64;
|
||||||
let spill_off = islot * M::word_bytes() as i64;
|
let spill_off = islot * M::word_bytes() as i64;
|
||||||
let sp_off = self.stackslots_size as i64 + spill_off;
|
let sp_off = self.stackslots_size as i64 + spill_off;
|
||||||
log::trace!("load_spillslot: slot {:?} -> sp_off {}", slot, sp_off);
|
trace!("load_spillslot: slot {:?} -> sp_off {}", slot, sp_off);
|
||||||
|
|
||||||
gen_load_stack_multi::<M>(StackAMode::NominalSPOffset(sp_off, ty), into_regs, ty)
|
gen_load_stack_multi::<M>(StackAMode::NominalSPOffset(sp_off, ty), into_regs, ty)
|
||||||
}
|
}
|
||||||
@@ -1363,7 +1363,7 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
|
|||||||
let islot = slot.index() as i64;
|
let islot = slot.index() as i64;
|
||||||
let spill_off = islot * M::word_bytes() as i64;
|
let spill_off = islot * M::word_bytes() as i64;
|
||||||
let sp_off = self.stackslots_size as i64 + spill_off;
|
let sp_off = self.stackslots_size as i64 + spill_off;
|
||||||
log::trace!("store_spillslot: slot {:?} -> sp_off {}", slot, sp_off);
|
trace!("store_spillslot: slot {:?} -> sp_off {}", slot, sp_off);
|
||||||
|
|
||||||
gen_store_stack_multi::<M>(StackAMode::NominalSPOffset(sp_off, ty), from_regs, ty)
|
gen_store_stack_multi::<M>(StackAMode::NominalSPOffset(sp_off, ty), from_regs, ty)
|
||||||
}
|
}
|
||||||
@@ -1376,7 +1376,7 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
|
|||||||
let virtual_sp_offset = M::get_virtual_sp_offset_from_state(state);
|
let virtual_sp_offset = M::get_virtual_sp_offset_from_state(state);
|
||||||
let nominal_sp_to_fp = M::get_nominal_sp_to_fp(state);
|
let nominal_sp_to_fp = M::get_nominal_sp_to_fp(state);
|
||||||
assert!(virtual_sp_offset >= 0);
|
assert!(virtual_sp_offset >= 0);
|
||||||
log::trace!(
|
trace!(
|
||||||
"spillslots_to_stackmap: slots = {:?}, state = {:?}",
|
"spillslots_to_stackmap: slots = {:?}, state = {:?}",
|
||||||
slots,
|
slots,
|
||||||
state
|
state
|
||||||
@@ -1508,7 +1508,7 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
|
|||||||
insts.push(M::gen_ret(vec![]));
|
insts.push(M::gen_ret(vec![]));
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!("Epilogue: {:?}", insts);
|
trace!("Epilogue: {:?}", insts);
|
||||||
insts
|
insts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ use crate::entity::SecondaryMap;
|
|||||||
use crate::fx::{FxHashMap, FxHashSet};
|
use crate::fx::{FxHashMap, FxHashSet};
|
||||||
use crate::inst_predicates::visit_block_succs;
|
use crate::inst_predicates::visit_block_succs;
|
||||||
use crate::ir::{Block, Function, Inst, Opcode};
|
use crate::ir::{Block, Function, Inst, Opcode};
|
||||||
use crate::machinst::*;
|
use crate::{machinst::*, trace};
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ impl LoweredBlock {
|
|||||||
impl BlockLoweringOrder {
|
impl BlockLoweringOrder {
|
||||||
/// Compute and return a lowered block order for `f`.
|
/// Compute and return a lowered block order for `f`.
|
||||||
pub fn new(f: &Function) -> BlockLoweringOrder {
|
pub fn new(f: &Function) -> BlockLoweringOrder {
|
||||||
log::trace!("BlockLoweringOrder: function body {:?}", f);
|
trace!("BlockLoweringOrder: function body {:?}", f);
|
||||||
|
|
||||||
// Step 1: compute the in-edge and out-edge count of every block.
|
// Step 1: compute the in-edge and out-edge count of every block.
|
||||||
let mut block_in_count = SecondaryMap::with_default(0);
|
let mut block_in_count = SecondaryMap::with_default(0);
|
||||||
@@ -477,7 +477,7 @@ impl BlockLoweringOrder {
|
|||||||
orig_map,
|
orig_map,
|
||||||
cold_blocks,
|
cold_blocks,
|
||||||
};
|
};
|
||||||
log::trace!("BlockLoweringOrder: {:?}", result);
|
trace!("BlockLoweringOrder: {:?}", result);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ use crate::machinst::{
|
|||||||
BlockIndex, MachInstLabelUse, TextSectionBuilder, VCodeConstant, VCodeConstants, VCodeInst,
|
BlockIndex, MachInstLabelUse, TextSectionBuilder, VCodeConstant, VCodeConstants, VCodeInst,
|
||||||
};
|
};
|
||||||
use crate::timing;
|
use crate::timing;
|
||||||
|
use crate::trace;
|
||||||
use cranelift_entity::{entity_impl, SecondaryMap};
|
use cranelift_entity::{entity_impl, SecondaryMap};
|
||||||
use log::trace;
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::ir::Function;
|
|||||||
use crate::isa::TargetIsa;
|
use crate::isa::TargetIsa;
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
use crate::timing;
|
use crate::timing;
|
||||||
|
use crate::trace;
|
||||||
|
|
||||||
use regalloc2::RegallocOptions;
|
use regalloc2::RegallocOptions;
|
||||||
use regalloc2::{self, MachineEnv};
|
use regalloc2::{self, MachineEnv};
|
||||||
@@ -27,7 +28,7 @@ pub fn compile<B: LowerBackend + TargetIsa>(
|
|||||||
lower.lower(b)?
|
lower.lower(b)?
|
||||||
};
|
};
|
||||||
|
|
||||||
log::trace!("vcode from lowering: \n{:?}", vcode);
|
trace!("vcode from lowering: \n{:?}", vcode);
|
||||||
|
|
||||||
// Perform register allocation.
|
// Perform register allocation.
|
||||||
let regalloc_result = {
|
let regalloc_result = {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use crate::machinst::{
|
|||||||
LoweredBlock, MachLabel, Reg, VCode, VCodeBuilder, VCodeConstant, VCodeConstantData,
|
LoweredBlock, MachLabel, Reg, VCode, VCodeBuilder, VCodeConstant, VCodeConstantData,
|
||||||
VCodeConstants, VCodeInst, ValueRegs, Writable,
|
VCodeConstants, VCodeInst, ValueRegs, Writable,
|
||||||
};
|
};
|
||||||
use crate::CodegenResult;
|
use crate::{trace, CodegenResult};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
@@ -506,7 +506,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
if value_regs[param].is_invalid() {
|
if value_regs[param].is_invalid() {
|
||||||
let regs = alloc_vregs(ty, &mut next_vreg, &mut vcode)?;
|
let regs = alloc_vregs(ty, &mut next_vreg, &mut vcode)?;
|
||||||
value_regs[param] = regs;
|
value_regs[param] = regs;
|
||||||
log::trace!("bb {} param {}: regs {:?}", bb, param, regs);
|
trace!("bb {} param {}: regs {:?}", bb, param, regs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for inst in f.layout.block_insts(bb) {
|
for inst in f.layout.block_insts(bb) {
|
||||||
@@ -515,7 +515,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
if value_regs[result].is_invalid() {
|
if value_regs[result].is_invalid() {
|
||||||
let regs = alloc_vregs(ty, &mut next_vreg, &mut vcode)?;
|
let regs = alloc_vregs(ty, &mut next_vreg, &mut vcode)?;
|
||||||
value_regs[result] = regs;
|
value_regs[result] = regs;
|
||||||
log::trace!(
|
trace!(
|
||||||
"bb {} inst {} ({:?}): result {} regs {:?}",
|
"bb {} inst {} ({:?}): result {} regs {:?}",
|
||||||
bb,
|
bb,
|
||||||
inst,
|
inst,
|
||||||
@@ -543,7 +543,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
for ret in &vcode.abi().signature().returns.clone() {
|
for ret in &vcode.abi().signature().returns.clone() {
|
||||||
let regs = alloc_vregs(ret.value_type, &mut next_vreg, &mut vcode)?;
|
let regs = alloc_vregs(ret.value_type, &mut next_vreg, &mut vcode)?;
|
||||||
retval_regs.push(regs);
|
retval_regs.push(regs);
|
||||||
log::trace!("retval gets regs {:?}", regs);
|
trace!("retval gets regs {:?}", regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute instruction colors, find constant instructions, and find instructions with
|
// Compute instruction colors, find constant instructions, and find instructions with
|
||||||
@@ -557,16 +557,16 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
for inst in f.layout.block_insts(bb) {
|
for inst in f.layout.block_insts(bb) {
|
||||||
let side_effect = has_lowering_side_effect(f, inst);
|
let side_effect = has_lowering_side_effect(f, inst);
|
||||||
|
|
||||||
log::trace!("bb {} inst {} has color {}", bb, inst, cur_color);
|
trace!("bb {} inst {} has color {}", bb, inst, cur_color);
|
||||||
if side_effect {
|
if side_effect {
|
||||||
side_effect_inst_entry_colors.insert(inst, InstColor::new(cur_color));
|
side_effect_inst_entry_colors.insert(inst, InstColor::new(cur_color));
|
||||||
log::trace!(" -> side-effecting; incrementing color for next inst");
|
trace!(" -> side-effecting; incrementing color for next inst");
|
||||||
cur_color += 1;
|
cur_color += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if this is a constant; if so, add to the table.
|
// Determine if this is a constant; if so, add to the table.
|
||||||
if let Some(c) = is_constant_64bit(f, inst) {
|
if let Some(c) = is_constant_64bit(f, inst) {
|
||||||
log::trace!(" -> constant: {}", c);
|
trace!(" -> constant: {}", c);
|
||||||
inst_constants.insert(inst, c);
|
inst_constants.insert(inst, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,7 +627,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
|
|
||||||
// Push args for a given inst onto the DFS stack.
|
// Push args for a given inst onto the DFS stack.
|
||||||
let push_args_on_stack = |stack: &mut StackVec<'a>, value| {
|
let push_args_on_stack = |stack: &mut StackVec<'a>, value| {
|
||||||
log::trace!(" -> pushing args for {} onto stack", value);
|
trace!(" -> pushing args for {} onto stack", value);
|
||||||
if let ValueDef::Result(src_inst, _) = f.dfg.value_def(value) {
|
if let ValueDef::Result(src_inst, _) = f.dfg.value_def(value) {
|
||||||
stack.push(f.dfg.inst_args(src_inst).iter());
|
stack.push(f.dfg.inst_args(src_inst).iter());
|
||||||
}
|
}
|
||||||
@@ -640,7 +640,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
while let Some(iter) = stack.last_mut() {
|
while let Some(iter) = stack.last_mut() {
|
||||||
if let Some(&value) = iter.next() {
|
if let Some(&value) = iter.next() {
|
||||||
let value = f.dfg.resolve_aliases(value);
|
let value = f.dfg.resolve_aliases(value);
|
||||||
log::trace!(" -> DFS reaches {}", value);
|
trace!(" -> DFS reaches {}", value);
|
||||||
if value_ir_uses[value] == ValueUseState::Multiple {
|
if value_ir_uses[value] == ValueUseState::Multiple {
|
||||||
// Truncate DFS here: no need to go further,
|
// Truncate DFS here: no need to go further,
|
||||||
// as whole subtree must already be Multiple.
|
// as whole subtree must already be Multiple.
|
||||||
@@ -658,7 +658,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
value_ir_uses[value] = ValueUseState::Multiple;
|
value_ir_uses[value] = ValueUseState::Multiple;
|
||||||
log::trace!(" -> became Multiple");
|
trace!(" -> became Multiple");
|
||||||
push_args_on_stack(stack, value);
|
push_args_on_stack(stack, value);
|
||||||
} else {
|
} else {
|
||||||
// Empty iterator, discard.
|
// Empty iterator, discard.
|
||||||
@@ -683,7 +683,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
let arg = f.dfg.resolve_aliases(arg);
|
let arg = f.dfg.resolve_aliases(arg);
|
||||||
let old = value_ir_uses[arg];
|
let old = value_ir_uses[arg];
|
||||||
if force_multiple {
|
if force_multiple {
|
||||||
log::trace!(
|
trace!(
|
||||||
"forcing arg {} to Multiple because of multiple results of user inst",
|
"forcing arg {} to Multiple because of multiple results of user inst",
|
||||||
arg
|
arg
|
||||||
);
|
);
|
||||||
@@ -692,7 +692,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
value_ir_uses[arg].inc();
|
value_ir_uses[arg].inc();
|
||||||
}
|
}
|
||||||
let new = value_ir_uses[arg];
|
let new = value_ir_uses[arg];
|
||||||
log::trace!("arg {} used, old state {:?}, new {:?}", arg, old, new,);
|
trace!("arg {} used, old state {:?}, new {:?}", arg, old, new,);
|
||||||
// On transition to Multiple, do DFS.
|
// On transition to Multiple, do DFS.
|
||||||
if old != ValueUseState::Multiple && new == ValueUseState::Multiple {
|
if old != ValueUseState::Multiple && new == ValueUseState::Multiple {
|
||||||
push_args_on_stack(&mut stack, arg);
|
push_args_on_stack(&mut stack, arg);
|
||||||
@@ -706,7 +706,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
|
|
||||||
fn gen_arg_setup(&mut self) {
|
fn gen_arg_setup(&mut self) {
|
||||||
if let Some(entry_bb) = self.f.layout.entry_block() {
|
if let Some(entry_bb) = self.f.layout.entry_block() {
|
||||||
log::trace!(
|
trace!(
|
||||||
"gen_arg_setup: entry BB {} args are:\n{:?}",
|
"gen_arg_setup: entry BB {} args are:\n{:?}",
|
||||||
entry_bb,
|
entry_bb,
|
||||||
self.f.dfg.block_params(entry_bb)
|
self.f.dfg.block_params(entry_bb)
|
||||||
@@ -830,7 +830,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
}
|
}
|
||||||
// Are any outputs used at least once?
|
// Are any outputs used at least once?
|
||||||
let value_needed = self.is_any_inst_result_needed(inst);
|
let value_needed = self.is_any_inst_result_needed(inst);
|
||||||
log::trace!(
|
trace!(
|
||||||
"lower_clif_block: block {} inst {} ({:?}) is_branch {} side_effect {} value_needed {}",
|
"lower_clif_block: block {} inst {} ({:?}) is_branch {} side_effect {} value_needed {}",
|
||||||
block,
|
block,
|
||||||
inst,
|
inst,
|
||||||
@@ -860,7 +860,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
// Normal instruction: codegen if the instruction is side-effecting
|
// Normal instruction: codegen if the instruction is side-effecting
|
||||||
// or any of its outputs its used.
|
// or any of its outputs its used.
|
||||||
if has_side_effect || value_needed {
|
if has_side_effect || value_needed {
|
||||||
log::trace!("lowering: inst {}: {:?}", inst, self.f.dfg[inst]);
|
trace!("lowering: inst {}: {:?}", inst, self.f.dfg[inst]);
|
||||||
backend.lower(self, inst)?;
|
backend.lower(self, inst)?;
|
||||||
}
|
}
|
||||||
if data.opcode().is_return() {
|
if data.opcode().is_return() {
|
||||||
@@ -905,7 +905,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
|
|
||||||
fn get_value_labels<'a>(&'a self, val: Value, depth: usize) -> Option<&'a [ValueLabelStart]> {
|
fn get_value_labels<'a>(&'a self, val: Value, depth: usize) -> Option<&'a [ValueLabelStart]> {
|
||||||
if let Some(ref values_labels) = self.f.dfg.values_labels {
|
if let Some(ref values_labels) = self.f.dfg.values_labels {
|
||||||
log::trace!(
|
trace!(
|
||||||
"get_value_labels: val {} -> {} -> {:?}",
|
"get_value_labels: val {} -> {} -> {:?}",
|
||||||
val,
|
val,
|
||||||
self.f.dfg.resolve_aliases(val),
|
self.f.dfg.resolve_aliases(val),
|
||||||
@@ -937,7 +937,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
.map(|&ValueLabelStart { label, .. }| label)
|
.map(|&ValueLabelStart { label, .. }| label)
|
||||||
.collect::<FxHashSet<_>>();
|
.collect::<FxHashSet<_>>();
|
||||||
for label in labels {
|
for label in labels {
|
||||||
log::trace!(
|
trace!(
|
||||||
"value labeling: defines val {:?} -> reg {:?} -> label {:?}",
|
"value labeling: defines val {:?} -> reg {:?} -> label {:?}",
|
||||||
val,
|
val,
|
||||||
reg,
|
reg,
|
||||||
@@ -953,7 +953,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!(
|
trace!(
|
||||||
"value labeling: srcloc {}: inst {}",
|
"value labeling: srcloc {}: inst {}",
|
||||||
self.srcloc(inst),
|
self.srcloc(inst),
|
||||||
inst
|
inst
|
||||||
@@ -968,7 +968,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!("value labeling: block {}", block);
|
trace!("value labeling: block {}", block);
|
||||||
for &arg in self.f.dfg.block_params(block) {
|
for &arg in self.f.dfg.block_params(block) {
|
||||||
self.emit_value_label_marks_for_value(arg);
|
self.emit_value_label_marks_for_value(arg);
|
||||||
}
|
}
|
||||||
@@ -999,7 +999,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
branches: &SmallVec<[Inst; 2]>,
|
branches: &SmallVec<[Inst; 2]>,
|
||||||
targets: &SmallVec<[MachLabel; 2]>,
|
targets: &SmallVec<[MachLabel; 2]>,
|
||||||
) -> CodegenResult<()> {
|
) -> CodegenResult<()> {
|
||||||
log::trace!(
|
trace!(
|
||||||
"lower_clif_branches: block {} branches {:?} targets {:?}",
|
"lower_clif_branches: block {} branches {:?} targets {:?}",
|
||||||
block,
|
block,
|
||||||
branches,
|
branches,
|
||||||
@@ -1061,7 +1061,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
|
|
||||||
/// Lower the function.
|
/// Lower the function.
|
||||||
pub fn lower<B: LowerBackend<MInst = I>>(mut self, backend: &B) -> CodegenResult<VCode<I>> {
|
pub fn lower<B: LowerBackend<MInst = I>>(mut self, backend: &B) -> CodegenResult<VCode<I>> {
|
||||||
log::trace!("about to lower function: {:?}", self.f);
|
trace!("about to lower function: {:?}", self.f);
|
||||||
|
|
||||||
// Initialize the ABI object, giving it a temp if requested.
|
// Initialize the ABI object, giving it a temp if requested.
|
||||||
let maybe_tmp = if let Some(temp_ty) = self.vcode.abi().temp_needed() {
|
let maybe_tmp = if let Some(temp_ty) = self.vcode.abi().temp_needed() {
|
||||||
@@ -1152,7 +1152,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
// Now that we've emitted all instructions into the
|
// Now that we've emitted all instructions into the
|
||||||
// VCodeBuilder, let's build the VCode.
|
// VCodeBuilder, let's build the VCode.
|
||||||
let vcode = self.vcode.build();
|
let vcode = self.vcode.build();
|
||||||
log::trace!("built vcode: {:?}", vcode);
|
trace!("built vcode: {:?}", vcode);
|
||||||
|
|
||||||
Ok(vcode)
|
Ok(vcode)
|
||||||
}
|
}
|
||||||
@@ -1287,7 +1287,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_value_as_source_or_const(&self, val: Value) -> NonRegInput {
|
fn get_value_as_source_or_const(&self, val: Value) -> NonRegInput {
|
||||||
log::trace!(
|
trace!(
|
||||||
"get_input_for_val: val {} at cur_inst {:?} cur_scan_entry_color {:?}",
|
"get_input_for_val: val {} at cur_inst {:?} cur_scan_entry_color {:?}",
|
||||||
val,
|
val,
|
||||||
self.cur_inst,
|
self.cur_inst,
|
||||||
@@ -1317,8 +1317,8 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
// prior to the sunk instruction) to sink.
|
// prior to the sunk instruction) to sink.
|
||||||
ValueDef::Result(src_inst, result_idx) => {
|
ValueDef::Result(src_inst, result_idx) => {
|
||||||
let src_side_effect = has_lowering_side_effect(self.f, src_inst);
|
let src_side_effect = has_lowering_side_effect(self.f, src_inst);
|
||||||
log::trace!(" -> src inst {}", src_inst);
|
trace!(" -> src inst {}", src_inst);
|
||||||
log::trace!(" -> has lowering side effect: {}", src_side_effect);
|
trace!(" -> has lowering side effect: {}", src_side_effect);
|
||||||
if !src_side_effect {
|
if !src_side_effect {
|
||||||
// Pure instruction: always possible to
|
// Pure instruction: always possible to
|
||||||
// sink. Let's determine whether we are the only
|
// sink. Let's determine whether we are the only
|
||||||
@@ -1332,7 +1332,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
// Side-effect: test whether this is the only use of the
|
// Side-effect: test whether this is the only use of the
|
||||||
// only result of the instruction, and whether colors allow
|
// only result of the instruction, and whether colors allow
|
||||||
// the code-motion.
|
// the code-motion.
|
||||||
log::trace!(
|
trace!(
|
||||||
" -> side-effecting op {} for val {}: use state {:?}",
|
" -> side-effecting op {} for val {}: use state {:?}",
|
||||||
src_inst,
|
src_inst,
|
||||||
val,
|
val,
|
||||||
@@ -1369,7 +1369,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
|
|
||||||
fn put_value_in_regs(&mut self, val: Value) -> ValueRegs<Reg> {
|
fn put_value_in_regs(&mut self, val: Value) -> ValueRegs<Reg> {
|
||||||
let val = self.f.dfg.resolve_aliases(val);
|
let val = self.f.dfg.resolve_aliases(val);
|
||||||
log::trace!("put_value_in_regs: val {}", val);
|
trace!("put_value_in_regs: val {}", val);
|
||||||
|
|
||||||
// Assert that the value is not `iflags`/`fflags`-typed; these
|
// Assert that the value is not `iflags`/`fflags`-typed; these
|
||||||
// cannot be reified into normal registers. TODO(#3249)
|
// cannot be reified into normal registers. TODO(#3249)
|
||||||
@@ -1387,7 +1387,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
.and_then(|inst| self.get_constant(inst))
|
.and_then(|inst| self.get_constant(inst))
|
||||||
{
|
{
|
||||||
let regs = self.alloc_tmp(ty);
|
let regs = self.alloc_tmp(ty);
|
||||||
log::trace!(" -> regs {:?}", regs);
|
trace!(" -> regs {:?}", regs);
|
||||||
assert!(regs.is_valid());
|
assert!(regs.is_valid());
|
||||||
|
|
||||||
let insts = I::gen_constant(regs, c.into(), ty, |ty| {
|
let insts = I::gen_constant(regs, c.into(), ty, |ty| {
|
||||||
@@ -1400,7 +1400,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut regs = self.value_regs[val];
|
let mut regs = self.value_regs[val];
|
||||||
log::trace!(" -> regs {:?}", regs);
|
trace!(" -> regs {:?}", regs);
|
||||||
assert!(regs.is_valid());
|
assert!(regs.is_valid());
|
||||||
|
|
||||||
self.value_lowered_uses[val] += 1;
|
self.value_lowered_uses[val] += 1;
|
||||||
@@ -1431,7 +1431,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit(&mut self, mach_inst: I) {
|
fn emit(&mut self, mach_inst: I) {
|
||||||
log::trace!("emit: {:?}", mach_inst);
|
trace!("emit: {:?}", mach_inst);
|
||||||
self.ir_insts.push(mach_inst);
|
self.ir_insts.push(mach_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1492,7 +1492,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_vreg_alias(&mut self, from: Reg, to: Reg) {
|
fn set_vreg_alias(&mut self, from: Reg, to: Reg) {
|
||||||
log::trace!("set vreg alias: from {:?} to {:?}", from, to);
|
trace!("set vreg alias: from {:?} to {:?}", from, to);
|
||||||
self.vcode.set_vreg_alias(from, to);
|
self.vcode.set_vreg_alias(from, to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ use crate::ir::{
|
|||||||
};
|
};
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
use crate::timing;
|
use crate::timing;
|
||||||
|
use crate::trace;
|
||||||
use crate::ValueLocRange;
|
use crate::ValueLocRange;
|
||||||
use regalloc2::{
|
use regalloc2::{
|
||||||
Edit, Function as RegallocFunction, InstOrEdit, InstRange, Operand, OperandKind, PReg, PRegSet,
|
Edit, Function as RegallocFunction, InstOrEdit, InstRange, Operand, OperandKind, PReg, PRegSet,
|
||||||
@@ -587,7 +588,7 @@ impl<I: VCodeInst> VCodeBuilder<I> {
|
|||||||
// Translate blockparam args via the vreg aliases table as well.
|
// Translate blockparam args via the vreg aliases table as well.
|
||||||
for arg in &mut self.vcode.branch_block_args {
|
for arg in &mut self.vcode.branch_block_args {
|
||||||
let new_arg = Self::resolve_vreg_alias_impl(&self.vcode.vreg_aliases, *arg);
|
let new_arg = Self::resolve_vreg_alias_impl(&self.vcode.vreg_aliases, *arg);
|
||||||
log::trace!("operandcollector: block arg {:?} -> {:?}", arg, new_arg);
|
trace!("operandcollector: block arg {:?} -> {:?}", arg, new_arg);
|
||||||
*arg = new_arg;
|
*arg = new_arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -806,7 +807,7 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for block in final_order {
|
for block in final_order {
|
||||||
log::trace!("emitting block {:?}", block);
|
trace!("emitting block {:?}", block);
|
||||||
let new_offset = I::align_basic_block(buffer.cur_offset());
|
let new_offset = I::align_basic_block(buffer.cur_offset());
|
||||||
while new_offset > buffer.cur_offset() {
|
while new_offset > buffer.cur_offset() {
|
||||||
// Pad with NOPs up to the aligned block offset.
|
// Pad with NOPs up to the aligned block offset.
|
||||||
@@ -829,7 +830,7 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
|
|
||||||
// Is this the first block? Emit the prologue directly if so.
|
// Is this the first block? Emit the prologue directly if so.
|
||||||
if block == self.entry {
|
if block == self.entry {
|
||||||
log::trace!(" -> entry block");
|
trace!(" -> entry block");
|
||||||
buffer.start_srcloc(SourceLoc::default());
|
buffer.start_srcloc(SourceLoc::default());
|
||||||
state.pre_sourceloc(SourceLoc::default());
|
state.pre_sourceloc(SourceLoc::default());
|
||||||
for inst in &prologue_insts {
|
for inst in &prologue_insts {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
use crate::cursor::{Cursor, FuncCursor};
|
use crate::cursor::{Cursor, FuncCursor};
|
||||||
use crate::dominator_tree::DominatorTree;
|
use crate::dominator_tree::DominatorTree;
|
||||||
use crate::flowgraph::ControlFlowGraph;
|
use crate::flowgraph::ControlFlowGraph;
|
||||||
use crate::ir;
|
|
||||||
use crate::timing;
|
use crate::timing;
|
||||||
|
use crate::{ir, trace};
|
||||||
|
|
||||||
/// Eliminate unreachable code.
|
/// Eliminate unreachable code.
|
||||||
///
|
///
|
||||||
@@ -24,14 +24,14 @@ pub fn eliminate_unreachable_code(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::trace!("Eliminating unreachable {}", block);
|
trace!("Eliminating unreachable {}", block);
|
||||||
// Move the cursor out of the way and make sure the next lop iteration goes to the right
|
// Move the cursor out of the way and make sure the next lop iteration goes to the right
|
||||||
// block.
|
// block.
|
||||||
pos.prev_block();
|
pos.prev_block();
|
||||||
|
|
||||||
// Remove all instructions from `block`.
|
// Remove all instructions from `block`.
|
||||||
while let Some(inst) = pos.func.layout.first_inst(block) {
|
while let Some(inst) = pos.func.layout.first_inst(block) {
|
||||||
log::trace!(" - {}", pos.func.dfg.display_inst(inst));
|
trace!(" - {}", pos.func.dfg.display_inst(inst));
|
||||||
pos.func.layout.remove_inst(inst);
|
pos.func.layout.remove_inst(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user