Skip to content

Commit 504c853

Browse files
committed
Review feedback: add back sequence points and enforce tags only on sequence points or calls.
1 parent 9409a84 commit 504c853

File tree

34 files changed

+208
-69
lines changed

34 files changed

+208
-69
lines changed

cranelift/codegen/meta/src/shared/instructions.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3902,4 +3902,20 @@ pub(crate) fn define(
39023902
Operand::new("a", &TxN.dynamic_to_vector()).with_doc("New fixed vector"),
39033903
]),
39043904
);
3905+
3906+
ig.push(
3907+
Inst::new(
3908+
"sequence_point",
3909+
r#"
3910+
A compiler barrier that acts as an immovable marker from IR input to machine-code output.
3911+
3912+
This "sequence point" can have debug tags attached to it, and these tags will be
3913+
noted in the output `MachBuffer`.
3914+
3915+
It prevents motion of any other side-effects across this boundary.
3916+
"#,
3917+
&formats.nullary,
3918+
)
3919+
.other_side_effects(),
3920+
);
39053921
}

cranelift/codegen/src/cursor.rs

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
//!
33
//! This module defines cursor data types that can be used for inserting instructions.
44
5-
use crate::{
6-
inst_predicates::has_lowering_side_effect,
7-
ir::{self},
8-
};
9-
use alloc::vec::Vec;
5+
use crate::ir;
106

117
/// The possible positions of a cursor.
128
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -38,9 +34,6 @@ pub trait Cursor {
3834
/// Set the source location that should be assigned to new instructions.
3935
fn set_srcloc(&mut self, srcloc: ir::SourceLoc);
4036

41-
/// Set the debug tags that should be assigned to new side-effecting instructions.
42-
fn set_debug_tags(&mut self, tags: Vec<ir::DebugTag>);
43-
4437
/// Borrow a reference to the function layout that this cursor is navigating.
4538
fn layout(&self) -> &ir::Layout;
4639

@@ -68,30 +61,6 @@ pub trait Cursor {
6861
self
6962
}
7063

71-
/// Exchange this cursor for one with a set debug tag list.
72-
///
73-
/// These tags will be attached to all newly inserted
74-
/// side-effecting instructions.
75-
///
76-
/// This is intended to be used as a builder method:
77-
///
78-
/// ```
79-
/// # use cranelift_codegen::ir::{Function, Block, DebugTag};
80-
/// # use cranelift_codegen::cursor::{Cursor, FuncCursor};
81-
/// fn edit_func(func: &mut Function, tags: Vec<DebugTag>) {
82-
/// let mut pos = FuncCursor::new(func).with_debug_tags(tags);
83-
///
84-
/// // Use `pos`...
85-
/// }
86-
/// ```
87-
fn with_debug_tags(mut self, tags: Vec<ir::DebugTag>) -> Self
88-
where
89-
Self: Sized,
90-
{
91-
self.set_debug_tags(tags);
92-
self
93-
}
94-
9564
/// Rebuild this cursor positioned at `pos`.
9665
fn at_position(mut self, pos: CursorPosition) -> Self
9766
where
@@ -648,7 +617,6 @@ pub trait Cursor {
648617
pub struct FuncCursor<'f> {
649618
pos: CursorPosition,
650619
srcloc: ir::SourceLoc,
651-
debug_tags: Vec<ir::DebugTag>,
652620

653621
/// The referenced function.
654622
pub func: &'f mut ir::Function,
@@ -660,7 +628,6 @@ impl<'f> FuncCursor<'f> {
660628
Self {
661629
pos: CursorPosition::Nowhere,
662630
srcloc: Default::default(),
663-
debug_tags: vec![],
664631
func,
665632
}
666633
}
@@ -694,10 +661,6 @@ impl<'f> Cursor for FuncCursor<'f> {
694661
self.srcloc = srcloc;
695662
}
696663

697-
fn set_debug_tags(&mut self, tags: Vec<ir::DebugTag>) {
698-
self.debug_tags = tags;
699-
}
700-
701664
fn layout(&self) -> &ir::Layout {
702665
&self.func.layout
703666
}
@@ -721,9 +684,6 @@ impl<'c, 'f> ir::InstInserterBase<'c> for &'c mut FuncCursor<'f> {
721684
if !self.srcloc.is_default() {
722685
self.func.set_srcloc(inst, self.srcloc);
723686
}
724-
if has_lowering_side_effect(self.func, inst) && !self.debug_tags.is_empty() {
725-
self.func.debug_tags.set(inst, self.debug_tags.clone());
726-
}
727687
&mut self.func.dfg
728688
}
729689
}

cranelift/codegen/src/inline.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,11 @@ fn inline_one(
367367
let mut last_inlined_block = inline_block_layout(func, call_block, callee, &entity_map);
368368

369369
// Get a copy of debug tags on the call instruction; these are
370-
// prepended to debug tags on inlined instructions.
370+
// prepended to debug tags on inlined instructions. Remove them
371+
// from the call itself as it will be rewritten to a jump (which
372+
// cannot have tags).
371373
let call_debug_tags = func.debug_tags.get(call_inst).to_vec();
374+
func.debug_tags.set(call_inst, []);
372375

373376
// Translate each instruction from the callee into the caller,
374377
// appending them to their associated block in the caller.

cranelift/codegen/src/inst_predicates.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ pub fn has_memory_fence_semantics(op: Opcode) -> bool {
147147
| Opcode::AtomicLoad
148148
| Opcode::AtomicStore
149149
| Opcode::Fence
150-
| Opcode::Debugtrap => true,
150+
| Opcode::Debugtrap
151+
| Opcode::SequencePoint => true,
151152
Opcode::Call | Opcode::CallIndirect | Opcode::TryCall | Opcode::TryCallIndirect => true,
152153
op if op.can_trap() => true,
153154
_ => false,

cranelift/codegen/src/ir/debug_tags.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ pub enum DebugTag {
7171

7272
impl DebugTags {
7373
/// Set the tags on an instruction, overwriting existing tag list.
74+
///
75+
/// Tags can only be set on call instructions (those for which
76+
/// [`crate::Opcode::is_call()`] returns `true`) and on
77+
/// `sequence_point` instructions. This property is checked by the
78+
/// CLIF verifier.
7479
pub fn set(&mut self, inst: Inst, tags: impl IntoIterator<Item = DebugTag>) {
7580
let start = u32::try_from(self.tags.len()).unwrap();
7681
self.tags.extend(tags);
@@ -93,13 +98,22 @@ impl DebugTags {
9398
}
9499
}
95100

101+
/// Does the given instruction have any tags?
102+
pub fn has(&self, inst: Inst) -> bool {
103+
// We rely on the invariant that an entry in the map is
104+
// present only if the list range is non-empty.
105+
self.insts.contains_key(&inst)
106+
}
107+
96108
/// Clone the tags from one instruction to another.
97109
///
98110
/// This clone is cheap (references the same underlying storage)
99111
/// because the tag lists are immutable.
100112
pub fn clone_tags(&mut self, from: Inst, to: Inst) {
101113
if let Some(range) = self.insts.get(&from).cloned() {
102114
self.insts.insert(to, range);
115+
} else {
116+
self.insts.remove(&to);
103117
}
104118
}
105119

cranelift/codegen/src/ir/function.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,20 @@ pub struct FunctionStencil {
191191
/// interpreted by Cranelift, only preserved.
192192
pub srclocs: SourceLocs,
193193

194-
/// Opaque debug-info tags on instructions.
194+
/// Opaque debug-info tags on sequence-point and call
195+
/// instructions.
195196
///
196197
/// These tags are not interpreted by Cranelift, and are passed
197198
/// through to compilation-result metadata. The only semantic
198199
/// structure that Cranelift imposes is that when inlining, it
199200
/// prepends the callsite call instruction's tags to the tags on
200201
/// inlined instructions.
202+
///
203+
/// In order to ensure clarity around guaranteed compiler
204+
/// behavior, tags are only permitted on instructions whose
205+
/// presence and sequence will remain the same in the compiled
206+
/// output: namely, `sequence_point` instructions and ordinary
207+
/// call instructions.
201208
pub debug_tags: DebugTags,
202209

203210
/// An optional global value which represents an expression evaluating to

cranelift/codegen/src/ir/layout.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ mod tests {
756756
use super::*;
757757
use crate::cursor::{Cursor, CursorPosition};
758758
use crate::entity::EntityRef;
759-
use crate::ir::{Block, DebugTag, Inst, SourceLoc};
759+
use crate::ir::{Block, Inst, SourceLoc};
760760
use alloc::vec::Vec;
761761
use core::cmp::Ordering;
762762

@@ -795,10 +795,6 @@ mod tests {
795795
unimplemented!()
796796
}
797797

798-
fn set_debug_tags(&mut self, _tags: Vec<DebugTag>) {
799-
unimplemented!()
800-
}
801-
802798
fn layout(&self) -> &Layout {
803799
self.layout
804800
}

cranelift/codegen/src/isa/aarch64/inst.isle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,9 @@
997997
(LabelAddress (dst WritableReg)
998998
(label MachLabel))
999999

1000+
;; A pseudoinstruction that serves as a sequence point.
1001+
(SequencePoint)
1002+
10001003
;; Emits an inline stack probe loop.
10011004
;;
10021005
;; Note that this is emitted post-regalloc so `start` and `end` can be
@@ -5203,3 +5206,8 @@
52035206
(let ((dst WritableReg (temp_writable_reg $I64))
52045207
(_ Unit (emit (MInst.LabelAddress dst label))))
52055208
dst))
5209+
5210+
;; Helper for creating a `SequencePoint` instruction.
5211+
(decl a64_sequence_point () SideEffectNoResult)
5212+
(rule (a64_sequence_point)
5213+
(SideEffectNoResult.Inst (MInst.SequencePoint)))

cranelift/codegen/src/isa/aarch64/inst/emit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3547,6 +3547,10 @@ impl MachInstEmit for Inst {
35473547
sink.use_label_at_offset(offset, label, LabelUse::Adr21);
35483548
}
35493549

3550+
&Inst::SequencePoint { .. } => {
3551+
// Nothing.
3552+
}
3553+
35503554
&Inst::StackProbeLoop { start, end, step } => {
35513555
assert!(emit_info.0.enable_probestack());
35523556

cranelift/codegen/src/isa/aarch64/inst/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ fn aarch64_get_operands(inst: &mut Inst, collector: &mut impl OperandVisitor) {
919919
Inst::LabelAddress { dst, .. } => {
920920
collector.reg_def(dst);
921921
}
922+
Inst::SequencePoint { .. } => {}
922923
Inst::StackProbeLoop { start, end, .. } => {
923924
collector.reg_early_def(start);
924925
collector.reg_use(end);
@@ -2893,6 +2894,9 @@ impl Inst {
28932894
let dst = pretty_print_reg(dst.to_reg());
28942895
format!("label_address {dst}, {label:?}")
28952896
}
2897+
&Inst::SequencePoint {} => {
2898+
format!("sequence_point")
2899+
}
28962900
&Inst::StackProbeLoop { start, end, step } => {
28972901
let start = pretty_print_reg(start.to_reg());
28982902
let end = pretty_print_reg(end);

0 commit comments

Comments
 (0)