Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor unwind generation in Cranelift. #1466

Merged
merged 5 commits into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 0 additions & 30 deletions cranelift/codegen/src/binemit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,36 +173,6 @@ pub trait CodeSink {
}
}

/// Type of the frame unwind information.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FrameUnwindKind {
/// Windows fastcall unwinding (as in .pdata).
Fastcall,
/// FDE entry for libunwind (similar to .eh_frame format).
Libunwind,
}

/// Offset in frame unwind information buffer.
pub type FrameUnwindOffset = usize;

/// Sink for frame unwind information.
pub trait FrameUnwindSink {
/// Get the current position.
fn len(&self) -> FrameUnwindOffset;

/// Add bytes to the code section.
fn bytes(&mut self, _: &[u8]);

/// Reserves bytes in the buffer.
fn reserve(&mut self, _len: usize) {}

/// Add a relocation entry.
fn reloc(&mut self, _: Reloc, _: FrameUnwindOffset);

/// Specified offset to main structure.
fn set_entry_offset(&mut self, _: FrameUnwindOffset);
}

/// Report a bad encoding error.
#[cold]
pub fn bad_encoding(func: &Function, inst: Inst) -> ! {
Expand Down
20 changes: 8 additions & 12 deletions cranelift/codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
//! single ISA instance.

use crate::binemit::{
relax_branches, shrink_instructions, CodeInfo, FrameUnwindKind, FrameUnwindSink,
MemoryCodeSink, RelocSink, StackmapSink, TrapSink,
relax_branches, shrink_instructions, CodeInfo, MemoryCodeSink, RelocSink, StackmapSink,
TrapSink,
};
use crate::dce::do_dce;
use crate::dominator_tree::DominatorTree;
Expand Down Expand Up @@ -231,19 +231,15 @@ impl Context {
sink.info
}

/// Emit unwind information.
/// Creates unwind information for the function.
///
/// Requires that the function layout be calculated (see `relax_branches`).
///
/// Only some calling conventions (e.g. Windows fastcall) will have unwind information.
/// This is a no-op if the function has no unwind information.
pub fn emit_unwind_info(
/// Returns `None` if the function has no unwind information.
#[cfg(feature = "unwind")]
pub fn create_unwind_info(
&self,
isa: &dyn TargetIsa,
kind: FrameUnwindKind,
sink: &mut dyn FrameUnwindSink,
) -> CodegenResult<()> {
isa.emit_unwind_info(&self.func, kind, sink)
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
isa.create_unwind_info(&self.func)
}

/// Run the verifier on the function.
Expand Down
74 changes: 0 additions & 74 deletions cranelift/codegen/src/ir/framelayout.rs

This file was deleted.

23 changes: 8 additions & 15 deletions cranelift/codegen/src/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ use crate::ir::{
Block, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap, HeapData, Inst, JumpTable,
JumpTableData, Opcode, SigRef, StackSlot, StackSlotData, Table, TableData,
};
use crate::ir::{BlockOffsets, FrameLayout, InstEncodings, SourceLocs, StackSlots, ValueLocations};
use crate::ir::{BlockOffsets, InstEncodings, SourceLocs, StackSlots, ValueLocations};
use crate::ir::{DataFlowGraph, ExternalName, Layout, Signature};
use crate::ir::{JumpTableOffsets, JumpTables};
use crate::isa::{CallConv, EncInfo, Encoding, Legalize, TargetIsa};
use crate::regalloc::{EntryRegDiversions, RegDiversions};
use crate::value_label::ValueLabelsRanges;
use crate::write::write_function;
use alloc::vec::Vec;
use core::fmt;

/// A function.
Expand Down Expand Up @@ -87,15 +88,13 @@ pub struct Function {

/// Instruction that marks the end (inclusive) of the function's prologue.
///
/// This is used for some calling conventions to track the end of unwind information.
/// This is used for some ABIs to generate unwind information.
pub prologue_end: Option<Inst>,

/// Frame layout for the instructions.
/// The instructions that mark the start (inclusive) of an epilogue in the function.
///
/// The stack unwinding requires to have information about which registers and where they
/// are saved in the frame. This information is created during the prologue and epilogue
/// passes.
pub frame_layout: Option<FrameLayout>,
/// This is used for some ABIs to generate unwind information.
pub epilogues_start: Vec<Inst>,
}

impl Function {
Expand All @@ -119,7 +118,7 @@ impl Function {
jt_offsets: SecondaryMap::new(),
srclocs: SecondaryMap::new(),
prologue_end: None,
frame_layout: None,
epilogues_start: Vec::new(),
}
}

Expand All @@ -140,7 +139,7 @@ impl Function {
self.jt_offsets.clear();
self.srclocs.clear();
self.prologue_end = None;
self.frame_layout = None;
self.epilogues_start.clear();
}

/// Create a new empty, anonymous function with a Fast calling convention.
Expand Down Expand Up @@ -258,12 +257,6 @@ impl Function {
/// Starts collection of debug information.
pub fn collect_debug_info(&mut self) {
self.dfg.collect_debug_info();
self.collect_frame_layout_info();
}

/// Starts collection of frame layout information.
pub fn collect_frame_layout_info(&mut self) {
self.frame_layout = Some(FrameLayout::new());
}

/// Changes the destination of a jump or branch instruction.
Expand Down
2 changes: 0 additions & 2 deletions cranelift/codegen/src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub mod dfg;
pub mod entities;
mod extfunc;
mod extname;
mod framelayout;
pub mod function;
mod globalvalue;
mod heap;
Expand Down Expand Up @@ -40,7 +39,6 @@ pub use crate::ir::extfunc::{
AbiParam, ArgumentExtension, ArgumentPurpose, ExtFuncData, Signature,
};
pub use crate::ir::extname::ExternalName;
pub use crate::ir::framelayout::{FrameLayout, FrameLayoutChange, FrameLayoutChanges};
pub use crate::ir::function::{DisplayFunctionAnnotations, Function};
pub use crate::ir::globalvalue::GlobalValueData;
pub use crate::ir::heap::{HeapData, HeapStyle};
Expand Down
14 changes: 0 additions & 14 deletions cranelift/codegen/src/isa/fde.rs

This file was deleted.

32 changes: 20 additions & 12 deletions cranelift/codegen/src/isa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ pub use crate::isa::stack::{StackBase, StackBaseMask, StackRef};
use crate::binemit;
use crate::flowgraph;
use crate::ir;
use crate::isa::fde::RegisterMappingError;
#[cfg(feature = "unwind")]
use crate::isa::unwind::systemv::RegisterMappingError;
use crate::machinst::MachBackend;
use crate::regalloc;
use crate::result::CodegenResult;
Expand All @@ -77,15 +77,15 @@ mod riscv;
#[cfg(feature = "x86")]
mod x86;

#[cfg(feature = "unwind")]
pub mod fde;

#[cfg(feature = "arm32")]
mod arm32;

#[cfg(feature = "arm64")]
mod aarch64;

#[cfg(feature = "unwind")]
pub mod unwind;

mod call_conv;
mod constraints;
mod enc_tables;
Expand Down Expand Up @@ -394,17 +394,25 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
/// IntCC condition for Unsigned Subtraction Overflow (Borrow/Carry).
fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC;

/// Emit unwind information for the given function.
/// Creates unwind information for the function.
///
/// Only some calling conventions (e.g. Windows fastcall) will have unwind information.
fn emit_unwind_info(
/// Returns `None` if there is no unwind information for the function.
#[cfg(feature = "unwind")]
fn create_unwind_info(
&self,
_func: &ir::Function,
_kind: binemit::FrameUnwindKind,
_sink: &mut dyn binemit::FrameUnwindSink,
) -> CodegenResult<()> {
// No-op by default
Ok(())
) -> CodegenResult<Option<unwind::UnwindInfo>> {
// By default, an ISA has no unwind information
Ok(None)
}

/// Creates a new System V Common Information Entry for the ISA.
///
/// Returns `None` if the ISA does not support System V unwind information.
#[cfg(feature = "unwind")]
fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {
// By default, an ISA cannot create a System V CIE
None
}

/// Get the new-style MachBackend, if this is an adapter around one.
Expand Down
16 changes: 16 additions & 0 deletions cranelift/codegen/src/isa/unwind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Represents information relating to function unwinding.
#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};

pub mod systemv;
pub mod winx64;

/// Represents unwind information for a single function.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub enum UnwindInfo {
/// Windows x64 ABI unwind information.
WindowsX64(winx64::UnwindInfo),
/// System V ABI unwind information.
SystemV(systemv::UnwindInfo),
}
Loading