Skip to content

Commit ef8a1a7

Browse files
authored
Add logging support for debugging ISLE rules (#12233)
* Add logging support for debugging ISLE rules * remove unnecessary feature guard * use Debug print for escaping slashes
1 parent 50431b4 commit ef8a1a7

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

cranelift/codegen/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ fn run_compilation(compilation: &IsleCompilation) -> Result<(), Errors> {
211211
// https://github.com/rust-lang/rust/issues/47995.)
212212
options.exclude_global_allow_pragmas = true;
213213

214+
// When `cranelift-codegen` is built with detailed tracing enabled, also
215+
// ask the ISLE compiler to emit `log::{debug,trace}!` invocations in
216+
// the generated code to help debug rule matching.
217+
options.emit_logging = std::env::var("CARGO_FEATURE_TRACE_LOG").is_ok();
218+
214219
if let Ok(out_dir) = std::env::var("OUT_DIR") {
215220
options.prefixes.push(isle::codegen::Prefix {
216221
prefix: out_dir,

cranelift/isle/isle/src/codegen.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ pub struct CodegenOptions {
2121
/// Prefixes to remove when printing file names in generaed files. This
2222
/// helps keep codegen deterministic.
2323
pub prefixes: Vec<Prefix>,
24+
25+
/// Emit `log::debug!` and `log::trace!` invocations in the generated code to help
26+
/// debug rule matching and execution.
27+
///
28+
/// In Cranelift this is typically controlled by a cargo feature on the
29+
/// crate that includes the generated code (e.g. `cranelift-codegen`).
30+
pub emit_logging: bool,
2431
}
2532

2633
/// A path prefix which should be replaced when printing file names.
@@ -63,16 +70,20 @@ struct BodyContext<'a, W> {
6370
indent: String,
6471
is_ref: StableSet<BindingId>,
6572
is_bound: StableSet<BindingId>,
73+
term_name: &'a str,
74+
emit_logging: bool,
6675
}
6776

6877
impl<'a, W: Write> BodyContext<'a, W> {
69-
fn new(out: &'a mut W, ruleset: &'a RuleSet) -> Self {
78+
fn new(out: &'a mut W, ruleset: &'a RuleSet, term_name: &'a str, emit_logging: bool) -> Self {
7079
Self {
7180
out,
7281
ruleset,
7382
indent: Default::default(),
7483
is_ref: Default::default(),
7584
is_bound: Default::default(),
85+
term_name,
86+
emit_logging,
7687
}
7788
}
7889

@@ -130,7 +141,8 @@ impl<'a> Codegen<'a> {
130141
self.generate_header(&mut code, options);
131142
self.generate_ctx_trait(&mut code);
132143
self.generate_internal_types(&mut code);
133-
self.generate_internal_term_constructors(&mut code).unwrap();
144+
self.generate_internal_term_constructors(&mut code, options)
145+
.unwrap();
134146

135147
code
136148
}
@@ -404,13 +416,17 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
404416
}
405417
}
406418

407-
fn generate_internal_term_constructors(&self, code: &mut String) -> std::fmt::Result {
419+
fn generate_internal_term_constructors(
420+
&self,
421+
code: &mut String,
422+
options: &CodegenOptions,
423+
) -> std::fmt::Result {
408424
for &(termid, ref ruleset) in self.terms.iter() {
409425
let root = crate::serialize::serialize(ruleset);
410-
let mut ctx = BodyContext::new(code, ruleset);
411426

412427
let termdata = &self.termenv.terms[termid.index()];
413428
let term_name = &self.typeenv.syms[termdata.name.index()];
429+
let mut ctx = BodyContext::new(code, ruleset, term_name, options.emit_logging);
414430
writeln!(ctx.out)?;
415431
writeln!(
416432
ctx.out,
@@ -664,6 +680,15 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
664680
&ctx.indent,
665681
pos.pretty_print_line(&self.files)
666682
)?;
683+
if ctx.emit_logging {
684+
// Produce a valid Rust string literal with escapes.
685+
let pp = pos.pretty_print_line(&self.files);
686+
writeln!(
687+
ctx.out,
688+
"{}log::debug!(\"ISLE {{}} {{}}\", {:?}, {:?});",
689+
&ctx.indent, ctx.term_name, pp
690+
)?;
691+
}
667692
write!(ctx.out, "{}", &ctx.indent)?;
668693
match ret_kind {
669694
ReturnKind::Plain | ReturnKind::Option => {

0 commit comments

Comments
 (0)