Fix all dead-code warnings in cranelift-codegen

This commit is contained in:
bjorn3
2021-06-21 13:11:28 +02:00
parent 3e4167ba95
commit 9e5201d88f
7 changed files with 2 additions and 948 deletions

View File

@@ -3,11 +3,10 @@
//! This module contains types and functions for working with the encoding tables generated by
//! `cranelift-codegen/meta/src/gen_encodings.rs`.
use crate::constant_hash::{probe, Table};
use crate::constant_hash::Table;
use crate::ir::{Function, InstructionData, Opcode, Type};
use crate::isa::{Encoding, Legalize};
use crate::settings::PredicateView;
use core::ops::Range;
/// A recipe predicate.
///
@@ -49,14 +48,6 @@ pub struct Level1Entry<OffT: Into<u32> + Copy> {
pub offset: OffT,
}
impl<OffT: Into<u32> + Copy> Level1Entry<OffT> {
/// Get the level 2 table range indicated by this entry.
fn range(&self) -> Range<usize> {
let b = self.offset.into() as usize;
b..b + (1 << self.log2len)
}
}
impl<OffT: Into<u32> + Copy> Table<Type> for [Level1Entry<OffT>] {
fn len(&self) -> usize {
self.len()
@@ -97,68 +88,6 @@ impl<OffT: Into<u32> + Copy> Table<Opcode> for [Level2Entry<OffT>] {
}
}
/// Two-level hash table lookup and iterator construction.
///
/// Given the controlling type variable and instruction opcode, find the corresponding encoding
/// list.
///
/// Returns an iterator that produces legal encodings for `inst`.
pub fn lookup_enclist<'a, OffT1, OffT2>(
ctrl_typevar: Type,
inst: &'a InstructionData,
func: &'a Function,
level1_table: &'static [Level1Entry<OffT1>],
level2_table: &'static [Level2Entry<OffT2>],
enclist: &'static [EncListEntry],
legalize_actions: &'static [Legalize],
recipe_preds: &'static [RecipePredicate],
inst_preds: &'static [InstPredicate],
isa_preds: PredicateView<'a>,
) -> Encodings<'a>
where
OffT1: Into<u32> + Copy,
OffT2: Into<u32> + Copy,
{
let (offset, legalize) = match probe(level1_table, ctrl_typevar, ctrl_typevar.index()) {
Err(l1idx) => {
// No level 1 entry found for the type.
// We have a sentinel entry with the default legalization code.
(!0, level1_table[l1idx].legalize)
}
Ok(l1idx) => {
// We have a valid level 1 entry for this type.
let l1ent = &level1_table[l1idx];
let offset = match level2_table.get(l1ent.range()) {
Some(l2tab) => {
let opcode = inst.opcode();
match probe(l2tab, opcode, opcode as usize) {
Ok(l2idx) => l2tab[l2idx].offset.into() as usize,
Err(_) => !0,
}
}
// The l1ent range is invalid. This means that we just have a customized
// legalization code for this type. The level 2 table is empty.
None => !0,
};
(offset, l1ent.legalize)
}
};
// Now we have an offset into `enclist` that is `!0` when no encoding list could be found.
// The default legalization code is always valid.
Encodings::new(
offset,
legalize,
inst,
func,
enclist,
legalize_actions,
recipe_preds,
inst_preds,
isa_preds,
)
}
/// Encoding list entry.
///
/// Encoding lists are represented as sequences of u16 words.

View File

@@ -24,77 +24,6 @@ pub enum UnwindInfo {
SystemV(systemv::UnwindInfo),
}
/// Intermediate representation for the unwind information
/// generated by a backend.
pub mod input {
use crate::binemit::CodeOffset;
use alloc::vec::Vec;
#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};
/// Elementary operation in the unwind operations.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub enum UnwindCode<Reg> {
/// Defines that a register is saved at the specified offset.
SaveRegister {
/// The saved register.
reg: Reg,
/// The specified offset relative to the stack pointer.
stack_offset: u32,
},
/// Defines that a register is as defined before call.
RestoreRegister {
/// The restored register.
reg: Reg,
},
/// The stack pointer was adjusted to allocate the stack.
StackAlloc {
/// Size to allocate.
size: u32,
},
/// The stack pointer was adjusted to free the stack.
StackDealloc {
/// Size to deallocate.
size: u32,
},
/// The alternative register was assigned as frame pointer base.
SetFramePointer {
/// The specified register.
reg: Reg,
},
/// Restores a frame pointer base to default register.
RestoreFramePointer,
/// Saves the state.
RememberState,
/// Restores the state.
RestoreState,
/// On aarch64 ARMv8.3+ devices, enables or disables pointer authentication.
Aarch64SetPointerAuth {
/// Whether return addresses (hold in LR) contain a pointer-authentication code.
return_addresses: bool,
},
}
/// Unwind information as generated by a backend.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct UnwindInfo<Reg> {
/// Size of the prologue.
pub prologue_size: CodeOffset,
/// Unwind codes for prologue.
pub prologue_unwind_codes: Vec<(CodeOffset, UnwindCode<Reg>)>,
/// Unwind codes for epilogues.
pub epilogues_unwind_codes: Vec<Vec<(CodeOffset, UnwindCode<Reg>)>>,
/// Entire function size.
pub function_size: CodeOffset,
/// Platform word size in bytes.
pub word_size: u8,
/// Initial stack pointer offset.
pub initial_sp_offset: u8,
}
}
/// Unwind pseudoinstruction used in VCode backends: represents that
/// at the present location, an action has just been taken.
///

View File

@@ -1,7 +1,6 @@
//! System V ABI unwind information.
use crate::binemit::CodeOffset;
use crate::isa::unwind::input;
use crate::isa::unwind::UnwindInst;
use crate::result::{CodegenError, CodegenResult};
use alloc::vec::Vec;
@@ -259,66 +258,6 @@ pub(crate) fn create_unwind_info_from_insts<MR: RegisterMapper<regalloc::Reg>>(
}
impl UnwindInfo {
// TODO: remove `build()` below when old backend is removed. The new backend uses a simpler
// approach in `create_unwind_info_from_insts()` above.
pub(crate) fn build<'b, Reg: PartialEq + Copy>(
unwind: input::UnwindInfo<Reg>,
map_reg: &'b dyn RegisterMapper<Reg>,
) -> CodegenResult<Self> {
use input::UnwindCode;
let mut builder = InstructionBuilder::new(unwind.initial_sp_offset, map_reg);
for (offset, c) in unwind.prologue_unwind_codes.iter().chain(
unwind
.epilogues_unwind_codes
.iter()
.map(|c| c.iter())
.flatten(),
) {
match c {
UnwindCode::SaveRegister { reg, stack_offset } => {
builder
.save_reg(*offset, *reg, *stack_offset)
.map_err(CodegenError::RegisterMappingError)?;
}
UnwindCode::StackAlloc { size } => {
builder.adjust_sp_down_imm(*offset, *size as i64);
}
UnwindCode::StackDealloc { size } => {
builder.adjust_sp_up_imm(*offset, *size as i64);
}
UnwindCode::RestoreRegister { reg } => {
builder
.restore_reg(*offset, *reg)
.map_err(CodegenError::RegisterMappingError)?;
}
UnwindCode::SetFramePointer { reg } => {
builder
.set_cfa_reg(*offset, *reg)
.map_err(CodegenError::RegisterMappingError)?;
}
UnwindCode::RestoreFramePointer => {
builder.restore_cfa(*offset);
}
UnwindCode::RememberState => {
builder.remember_state(*offset);
}
UnwindCode::RestoreState => {
builder.restore_state(*offset);
}
UnwindCode::Aarch64SetPointerAuth { return_addresses } => {
builder.set_aarch64_pauth(*offset, *return_addresses);
}
}
}
let instructions = builder.instructions;
let len = unwind.function_size;
Ok(Self { instructions, len })
}
/// Converts the unwind information into a `FrameDescriptionEntry`.
pub fn to_fde(&self, address: Address) -> gimli::write::FrameDescriptionEntry {
let mut fde = FrameDescriptionEntry::new(address, self.len);
@@ -330,145 +269,3 @@ impl UnwindInfo {
fde
}
}
// TODO: delete the builder below when the old backend is removed.
struct InstructionBuilder<'a, Reg: PartialEq + Copy> {
sp_offset: i32,
frame_register: Option<Reg>,
saved_state: Option<(i32, Option<Reg>)>,
map_reg: &'a dyn RegisterMapper<Reg>,
instructions: Vec<(u32, CallFrameInstruction)>,
}
impl<'a, Reg: PartialEq + Copy> InstructionBuilder<'a, Reg> {
fn new(sp_offset: u8, map_reg: &'a (dyn RegisterMapper<Reg> + 'a)) -> Self {
Self {
sp_offset: sp_offset as i32, // CFA offset starts at the specified offset to account for the return address on stack
saved_state: None,
frame_register: None,
map_reg,
instructions: Vec::new(),
}
}
fn save_reg(
&mut self,
offset: u32,
reg: Reg,
stack_offset: u32,
) -> Result<(), RegisterMappingError> {
// Pushes in the prologue are register saves, so record an offset of the save
self.instructions.push((
offset,
CallFrameInstruction::Offset(
self.map_reg.map(reg)?,
stack_offset as i32 - self.sp_offset,
),
));
Ok(())
}
fn adjust_sp_down_imm(&mut self, offset: u32, imm: i64) {
assert!(imm <= core::u32::MAX as i64);
self.sp_offset += imm as i32;
// Don't adjust the CFA if we're using a frame pointer
if self.frame_register.is_some() {
return;
}
self.instructions
.push((offset, CallFrameInstruction::CfaOffset(self.sp_offset)));
}
fn adjust_sp_up_imm(&mut self, offset: u32, imm: i64) {
assert!(imm <= core::u32::MAX as i64);
self.sp_offset -= imm as i32;
// Don't adjust the CFA if we're using a frame pointer
if self.frame_register.is_some() {
return;
}
let cfa_inst_ofs = {
// Scan to find and merge with CFA instruction with the same offset.
let mut it = self.instructions.iter_mut();
loop {
match it.next_back() {
Some((i_offset, i)) if *i_offset == offset => {
if let CallFrameInstruction::Cfa(_, o) = i {
break Some(o);
}
}
_ => {
break None;
}
}
}
};
if let Some(o) = cfa_inst_ofs {
// Update previous CFA instruction.
*o = self.sp_offset;
} else {
// Add just CFA offset instruction.
self.instructions
.push((offset, CallFrameInstruction::CfaOffset(self.sp_offset)));
}
}
fn set_cfa_reg(&mut self, offset: u32, reg: Reg) -> Result<(), RegisterMappingError> {
self.instructions.push((
offset,
CallFrameInstruction::CfaRegister(self.map_reg.map(reg)?),
));
self.frame_register = Some(reg);
Ok(())
}
fn restore_cfa(&mut self, offset: u32) {
// Restore SP and its offset.
self.instructions.push((
offset,
CallFrameInstruction::Cfa(self.map_reg.sp(), self.sp_offset),
));
self.frame_register = None;
}
fn restore_reg(&mut self, offset: u32, reg: Reg) -> Result<(), RegisterMappingError> {
// Pops in the epilogue are register restores, so record a "same value" for the register
self.instructions.push((
offset,
CallFrameInstruction::SameValue(self.map_reg.map(reg)?),
));
Ok(())
}
fn remember_state(&mut self, offset: u32) {
self.saved_state = Some((self.sp_offset, self.frame_register));
self.instructions
.push((offset, CallFrameInstruction::RememberState));
}
fn restore_state(&mut self, offset: u32) {
let (sp_offset, frame_register) = self.saved_state.take().unwrap();
self.sp_offset = sp_offset;
self.frame_register = frame_register;
self.instructions
.push((offset, CallFrameInstruction::RestoreState));
}
fn set_aarch64_pauth(&mut self, offset: u32, return_addresses: bool) {
self.instructions.push((
offset,
CallFrameInstruction::Aarch64SetPointerAuth { return_addresses },
));
}
}

View File

@@ -1,6 +1,5 @@
//! Windows x64 ABI unwind information.
use crate::isa::unwind::input;
use crate::result::{CodegenError, CodegenResult};
use alloc::vec::Vec;
use log::warn;
@@ -259,76 +258,6 @@ impl UnwindInfo {
.iter()
.fold(0, |nodes, c| nodes + c.node_count())
}
// TODO: remove `build()` below when old backend is removed. The new backend uses
// a simpler approach in `create_unwind_info_from_insts()` below.
pub(crate) fn build<Reg: PartialEq + Copy + std::fmt::Debug, MR: RegisterMapper<Reg>>(
unwind: input::UnwindInfo<Reg>,
) -> CodegenResult<Self> {
use crate::isa::unwind::input::UnwindCode as InputUnwindCode;
let word_size: u32 = unwind.word_size.into();
let mut unwind_codes = Vec::new();
for (offset, c) in unwind.prologue_unwind_codes.iter() {
match c {
InputUnwindCode::SaveRegister { reg, stack_offset } => {
let reg = MR::map(*reg);
let offset = ensure_unwind_offset(*offset)?;
match reg {
MappedRegister::Int(reg) => {
// Attempt to convert sequence of the `InputUnwindCode`:
// `StackAlloc { size = word_size }`, `SaveRegister { stack_offset: 0 }`
// to the shorter `UnwindCode::PushRegister`.
let push_reg_sequence = if let Some(UnwindCode::StackAlloc {
instruction_offset: alloc_offset,
size,
}) = unwind_codes.last()
{
*size == word_size && offset == *alloc_offset && *stack_offset == 0
} else {
false
};
if push_reg_sequence {
*unwind_codes.last_mut().unwrap() = UnwindCode::PushRegister {
instruction_offset: offset,
reg,
};
} else {
unwind_codes.push(UnwindCode::SaveReg {
instruction_offset: offset,
reg,
stack_offset: *stack_offset,
});
}
}
MappedRegister::Xmm(reg) => {
unwind_codes.push(UnwindCode::SaveXmm {
instruction_offset: offset,
reg,
stack_offset: *stack_offset,
});
}
}
}
InputUnwindCode::StackAlloc { size } => {
unwind_codes.push(UnwindCode::StackAlloc {
instruction_offset: ensure_unwind_offset(*offset)?,
size: *size,
});
}
_ => {}
}
}
Ok(Self {
flags: 0, // this assumes cranelift functions have no SEH handlers
prologue_size: ensure_unwind_offset(unwind.prologue_size)?,
frame_register: None,
frame_register_offset: 0,
unwind_codes,
})
}
}
const UNWIND_RBP_REG: u8 = 5;