Skip to content

Commit e885228

Browse files
committed
add sonatina ir comments to stackify trace output
1 parent 3149619 commit e885228

File tree

3 files changed

+1858
-8
lines changed

3 files changed

+1858
-8
lines changed

crates/codegen/src/stackalloc/stackify/trace.rs

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use std::{collections::BTreeMap, fmt::Write};
22

3-
use sonatina_ir::{BlockId, Function, InstId, ValueId};
3+
use sonatina_ir::{
4+
BlockId, Function, InstId, ValueId,
5+
ir_writer::{FuncWriteCtx, InstStatement, IrWrite},
6+
module::FuncRef,
7+
};
48

59
use crate::bitset::BitSet;
610

@@ -92,13 +96,19 @@ impl StackifyObserver for NullObserver {
9296
pub(super) struct StackifyTrace {
9397
out: String,
9498
action_chunks: Vec<ActionChunk>,
99+
inst_chunks: Vec<InstChunk>,
95100
}
96101

97102
struct ActionChunk {
98103
placeholder: String,
99104
actions: crate::stackalloc::Actions,
100105
}
101106

107+
struct InstChunk {
108+
placeholder: String,
109+
inst: InstId,
110+
}
111+
102112
impl StackifyTrace {
103113
pub(super) fn render(self, func: &Function, alloc: &StackifyAlloc) -> String {
104114
if func.layout.iter_block().next().is_none() {
@@ -152,6 +162,10 @@ impl StackifyTrace {
152162
let formatted = fmt_actions(&chunk.actions);
153163
trace = trace.replace(&chunk.placeholder, &formatted);
154164
}
165+
for chunk in self.inst_chunks {
166+
let comment = fmt_inst_comment(func, chunk.inst);
167+
trace = trace.replace(&chunk.placeholder, &comment);
168+
}
155169
out.push_str(&trace);
156170
out
157171
}
@@ -167,19 +181,34 @@ impl StackifyTrace {
167181
});
168182
placeholder
169183
}
184+
185+
fn push_inst_placeholder(&mut self, inst: InstId) -> String {
186+
let idx = self.inst_chunks.len();
187+
let placeholder = format!("@@INST:{idx}@@");
188+
self.inst_chunks.push(InstChunk {
189+
placeholder: placeholder.clone(),
190+
inst,
191+
});
192+
placeholder
193+
}
170194
}
171195

172196
impl StackifyObserver for StackifyTrace {
173-
type Checkpoint = (usize, usize);
197+
type Checkpoint = (usize, usize, usize);
174198

175199
fn checkpoint(&mut self) -> Self::Checkpoint {
176-
(self.out.len(), self.action_chunks.len())
200+
(
201+
self.out.len(),
202+
self.action_chunks.len(),
203+
self.inst_chunks.len(),
204+
)
177205
}
178206

179207
fn rollback(&mut self, checkpoint: Self::Checkpoint) {
180-
let (out_len, chunk_len) = checkpoint;
208+
let (out_len, action_chunk_len, inst_chunk_len) = checkpoint;
181209
self.out.truncate(out_len);
182-
self.action_chunks.truncate(chunk_len);
210+
self.action_chunks.truncate(action_chunk_len);
211+
self.inst_chunks.truncate(inst_chunk_len);
183212
}
184213

185214
fn on_block_header(&mut self, func: &Function, block: BlockId, template: &BlockTemplate) {
@@ -218,12 +247,14 @@ impl StackifyObserver for StackifyTrace {
218247
fn on_inst_start(
219248
&mut self,
220249
func: &Function,
221-
_inst: InstId,
250+
inst: InstId,
222251
stack: &SymStack,
223252
live_future: &BitSet<ValueId>,
224253
live_out: &BitSet<ValueId>,
225254
last_use: &BitSet<ValueId>,
226255
) {
256+
let comment = self.push_inst_placeholder(inst);
257+
let _ = writeln!(&mut self.out, " // {comment}");
227258
let stack_start = fmt_stack(func, stack, live_future, live_out);
228259
let last_use_list: Vec<ValueId> = last_use.iter().collect();
229260
if last_use_list.is_empty() {
@@ -298,6 +329,32 @@ impl StackifyObserver for StackifyTrace {
298329
}
299330
}
300331

332+
fn fmt_inst_comment(func: &Function, inst: InstId) -> String {
333+
let Some(func_ref) = fallback_func_ref(func) else {
334+
return fmt_inst_comment_fallback(func, inst);
335+
};
336+
let ctx = FuncWriteCtx::new(func, func_ref);
337+
let mut bytes = Vec::new();
338+
if InstStatement(inst).write(&mut bytes, &ctx).is_ok()
339+
&& let Ok(comment) = String::from_utf8(bytes)
340+
{
341+
return comment;
342+
}
343+
fmt_inst_comment_fallback(func, inst)
344+
}
345+
346+
fn fallback_func_ref(func: &Function) -> Option<FuncRef> {
347+
func.ctx()
348+
.declared_funcs
349+
.iter()
350+
.next()
351+
.map(|entry| *entry.key())
352+
}
353+
354+
fn fmt_inst_comment_fallback(func: &Function, inst: InstId) -> String {
355+
format!("{};", func.dfg.inst(inst).as_text())
356+
}
357+
301358
fn fmt_immediate(imm: sonatina_ir::Immediate) -> String {
302359
use sonatina_ir::Immediate::*;
303360
match imm {

0 commit comments

Comments
 (0)