Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Track frame layout changes. #679

Closed
Closed
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
73 changes: 73 additions & 0 deletions cranelift-codegen/src/ir/framelayout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! Frame layout item changes.

use crate::ir::entities::Inst;
use crate::isa::RegUnit;
use std::boxed::Box;

#[cfg(not(feature = "std"))]
use crate::HashMap;
#[cfg(feature = "std")]
use std::collections::HashMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we don't need to guard against the std feature here and we can just use crate::HashMap;, right?


/// Change in the frame layout information.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum FrameLayoutChange {
/// Base CFA pointer moved to different register/offset.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it's obvious from context here, would be nice to explicit CFA in this file at least once.

CallFrameAddressAt {
/// CFA register.
reg: RegUnit,
/// CFA offset.
offset: isize,
},
/// Register saved at.
RegAt {
/// Saved register.
reg: RegUnit,
/// Offset in the frame (offset from CFA).
cfa_offset: isize,
},
/// Return address saved at.
ReturnAddressAt {
/// Offset in the frame (offset from CFA).
cfa_offset: isize,
},
/// The entire frame layout must be preserved somewhere to be restored at a corresponding
/// `Restore` change.
///
/// This likely maps to the DWARF call frame instruction `.cfa_remember_state`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you end this sentence with a dot please? (ditto below for restore)

Preserve,
/// Restore the entire frame layout from a corresponding prior `Preserve` frame change.
///
/// This likely maps to the DWARF call frame instruction `.cfa_restore_state`
Restore,
}

/// Set of frame layout changes.
pub type FrameLayoutChanges = Box<[FrameLayoutChange]>;

/// Frame items layout for (prologue/epilogue) instructions.
#[derive(Debug, Clone)]
pub struct FrameLayout {
/// Initial frame layout.
pub initial: FrameLayoutChanges,

/// Instruction frame layout (changes). Because the map will not be dense,
/// a HashMap is used instead of a SecondaryMap.
pub instructions: HashMap<Inst, FrameLayoutChanges>,
yurydelendik marked this conversation as resolved.
Show resolved Hide resolved
}

impl FrameLayout {
/// Creates instance of FrameLayout.
pub fn new() -> Self {
FrameLayout {
initial: vec![].into_boxed_slice(),
instructions: HashMap::new(),
}
}

/// Clear the structure.
pub fn clear(&mut self) {
self.initial = vec![].into_boxed_slice();
self.instructions.clear();
}
}
12 changes: 11 additions & 1 deletion cranelift-codegen/src/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::ir::{
Ebb, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap, HeapData, Inst, JumpTable,
JumpTableData, SigRef, StackSlot, StackSlotData, Table, TableData,
};
use crate::ir::{EbbOffsets, InstEncodings, SourceLocs, StackSlots, ValueLocations};
use crate::ir::{EbbOffsets, FrameLayout, InstEncodings, SourceLocs, StackSlots, ValueLocations};
use crate::ir::{JumpTableOffsets, JumpTables};
use crate::isa::{CallConv, EncInfo, Encoding, Legalize, TargetIsa};
use crate::regalloc::{EntryRegDiversions, RegDiversions};
Expand Down Expand Up @@ -83,6 +83,13 @@ pub struct Function {
/// Track the original source location for each instruction. The source locations are not
/// interpreted by Cranelift, only preserved.
pub srclocs: SourceLocs,

/// Frame layout for the instructions.
///
/// 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>,
}

impl Function {
Expand All @@ -104,6 +111,7 @@ impl Function {
offsets: SecondaryMap::new(),
jt_offsets: SecondaryMap::new(),
srclocs: SecondaryMap::new(),
frame_layout: None,
}
}

Expand All @@ -123,6 +131,7 @@ impl Function {
self.offsets.clear();
self.jt_offsets.clear();
self.srclocs.clear();
self.frame_layout = None;
}

/// Create a new empty, anonymous function with a Fast calling convention.
Expand Down Expand Up @@ -232,6 +241,7 @@ impl Function {
/// Starts collection of debug information.
pub fn collect_debug_info(&mut self) {
self.dfg.collect_debug_info();
self.frame_layout = Some(FrameLayout::new());
}

/// Changes the destination of a jump or branch instruction.
Expand Down
2 changes: 2 additions & 0 deletions cranelift-codegen/src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod dfg;
pub mod entities;
mod extfunc;
mod extname;
mod framelayout;
pub mod function;
mod globalvalue;
mod heap;
Expand Down Expand Up @@ -39,6 +40,7 @@ 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
Loading