Skip to content

Commit 8c51c14

Browse files
Add IR printing functionality to the PassManager
Signed-off-by: Tomas Fabrizio Orsi <[email protected]>
1 parent f633c53 commit 8c51c14

File tree

14 files changed

+407
-116
lines changed

14 files changed

+407
-116
lines changed

dialects/hir/src/transforms/spill.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use alloc::rc::Rc;
33
use midenc_hir::{
44
adt::SmallDenseMap,
55
dialects::builtin::{Function, FunctionRef, LocalVariable},
6-
pass::{Pass, PassExecutionState},
6+
pass::{Pass, PassExecutionState, PassIdentifier, PostPassStatus},
77
BlockRef, BuilderExt, EntityMut, Op, OpBuilder, OperationName, OperationRef, Report, Rewriter,
88
SourceSpan, Spanned, Symbol, ValueRef,
99
};
@@ -19,6 +19,10 @@ impl Pass for TransformSpills {
1919
"transform-spills"
2020
}
2121

22+
fn pass_id(&self) -> Option<PassIdentifier> {
23+
Some(PassIdentifier::TransformSpills)
24+
}
25+
2226
fn argument(&self) -> &'static str {
2327
"transform-spills"
2428
}
@@ -31,22 +35,22 @@ impl Pass for TransformSpills {
3135
&mut self,
3236
op: EntityMut<'_, Self::Target>,
3337
state: &mut PassExecutionState,
34-
) -> Result<(), Report> {
38+
) -> Result<PostPassStatus, Report> {
3539
let function = op.into_entity_ref();
3640
log::debug!(target: "insert-spills", "computing and inserting spills for {}", function.as_operation());
3741

3842
if function.is_declaration() {
3943
log::debug!(target: "insert-spills", "function has no body, no spills needed!");
4044
state.preserved_analyses_mut().preserve_all();
41-
return Ok(());
45+
return Ok(PostPassStatus::IRUnchanged);
4246
}
4347
let mut analysis =
4448
state.analysis_manager().get_analysis_for::<SpillAnalysis, Function>()?;
4549

4650
if !analysis.has_spills() {
4751
log::debug!(target: "insert-spills", "no spills needed!");
4852
state.preserved_analyses_mut().preserve_all();
49-
return Ok(());
53+
return Ok(PostPassStatus::IRUnchanged);
5054
}
5155

5256
// Take ownership of the spills analysis so that we can mutate the analysis state during

dialects/scf/src/transforms/cfg_to_scf.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use midenc_hir::{
77
diagnostics::Severity,
88
dialects::builtin,
99
dominance::DominanceInfo,
10-
pass::{Pass, PassExecutionState},
10+
pass::{Pass, PassExecutionState, PassIdentifier, PostPassStatus},
1111
Builder, EntityMut, Forward, Op, Operation, OperationName, OperationRef, RawWalk, Report,
1212
SmallVec, Spanned, Type, ValueRange, ValueRef, WalkResult,
1313
};
@@ -35,6 +35,10 @@ impl Pass for LiftControlFlowToSCF {
3535
"lift-control-flow"
3636
}
3737

38+
fn pass_id(&self) -> Option<PassIdentifier> {
39+
Some(PassIdentifier::LiftControlFlowToSCF)
40+
}
41+
3842
fn argument(&self) -> &'static str {
3943
"lift-control-flow"
4044
}
@@ -51,7 +55,7 @@ impl Pass for LiftControlFlowToSCF {
5155
&mut self,
5256
op: EntityMut<'_, Self::Target>,
5357
state: &mut PassExecutionState,
54-
) -> Result<(), Report> {
58+
) -> Result<PostPassStatus, Report> {
5559
let mut transformation = ControlFlowToSCFTransformation;
5660
let mut changed = false;
5761

@@ -130,7 +134,7 @@ impl Pass for LiftControlFlowToSCF {
130134
});
131135

132136
if result.was_interrupted() {
133-
return result.into_result();
137+
return result.into_result().map(|_| PostPassStatus::IRUnchanged);
134138
}
135139

136140
log::debug!(
@@ -141,7 +145,7 @@ impl Pass for LiftControlFlowToSCF {
141145
state.preserved_analyses_mut().preserve_all();
142146
}
143147

144-
Ok(())
148+
Ok(changed.into())
145149
}
146150
}
147151

hir-transform/src/canonicalization.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use alloc::{boxed::Box, format, rc::Rc};
22

33
use midenc_hir::{
4-
pass::{OperationPass, Pass, PassExecutionState},
4+
pass::{OperationPass, Pass, PassExecutionState, PassIdentifier, PostPassStatus},
55
patterns::{self, FrozenRewritePatternSet, GreedyRewriteConfig, RewritePatternSet},
66
Context, EntityMut, Operation, OperationName, Report, Spanned,
77
};
@@ -62,6 +62,10 @@ impl Pass for Canonicalizer {
6262
"canonicalizer"
6363
}
6464

65+
fn pass_id(&self) -> Option<PassIdentifier> {
66+
Some(PassIdentifier::Canonicalizer)
67+
}
68+
6569
fn argument(&self) -> &'static str {
6670
"canonicalizer"
6771
}
@@ -93,10 +97,10 @@ impl Pass for Canonicalizer {
9397
&mut self,
9498
op: EntityMut<'_, Self::Target>,
9599
state: &mut PassExecutionState,
96-
) -> Result<(), Report> {
100+
) -> Result<PostPassStatus, Report> {
97101
let Some(rewrites) = self.rewrites.as_ref() else {
98102
log::debug!("skipping canonicalization as there are no rewrite patterns to apply");
99-
return Ok(());
103+
return Ok(PostPassStatus::IRUnchanged);
100104
};
101105
let op = {
102106
let ptr = op.as_operation_ref();
@@ -129,16 +133,20 @@ impl Pass for Canonicalizer {
129133
}
130134

131135
let op = op.borrow();
132-
match converged {
136+
let changed = match converged {
133137
Ok(changed) => {
134-
log::debug!("canonicalization converged for '{}', changed={changed}", op.name())
138+
log::debug!("canonicalization converged for '{}', changed={changed}", op.name());
139+
changed
135140
}
136-
Err(changed) => log::warn!(
137-
"canonicalization failed to converge for '{}', changed={changed}",
138-
op.name()
139-
),
140-
}
141+
Err(changed) => {
142+
log::warn!(
143+
"canonicalization failed to converge for '{}', changed={changed}",
144+
op.name()
145+
);
146+
changed
147+
}
148+
};
141149

142-
Ok(())
150+
Ok(changed.into())
143151
}
144152
}

hir-transform/src/sccp.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use midenc_hir::{
2-
pass::{Pass, PassExecutionState},
2+
pass::{Pass, PassExecutionState, PassIdentifier, PostPassStatus},
33
patterns::NoopRewriterListener,
44
BlockRef, Builder, EntityMut, OpBuilder, Operation, OperationFolder, OperationName, RegionList,
55
Report, SmallVec, ValueRef,
@@ -26,6 +26,10 @@ impl Pass for SparseConditionalConstantPropagation {
2626
"sparse-conditional-constant-propagation"
2727
}
2828

29+
fn pass_id(&self) -> Option<PassIdentifier> {
30+
Some(PassIdentifier::SparseConditionalConstantPropagation)
31+
}
32+
2933
fn argument(&self) -> &'static str {
3034
"sparse-conditional-constant-propagation"
3135
}
@@ -38,7 +42,7 @@ impl Pass for SparseConditionalConstantPropagation {
3842
&mut self,
3943
mut op: EntityMut<'_, Self::Target>,
4044
state: &mut PassExecutionState,
41-
) -> Result<(), Report> {
45+
) -> Result<PostPassStatus, Report> {
4246
// Run sparse constant propagation + dead code analysis
4347
let mut solver = DataFlowSolver::default();
4448
solver.load::<DeadCodeAnalysis>();
@@ -58,7 +62,7 @@ impl SparseConditionalConstantPropagation {
5862
op: &mut Operation,
5963
_state: &mut PassExecutionState,
6064
solver: &DataFlowSolver,
61-
) -> Result<(), Report> {
65+
) -> Result<PostPassStatus, Report> {
6266
let mut worklist = SmallVec::<[BlockRef; 8]>::default();
6367

6468
let add_to_worklist = |regions: &RegionList, worklist: &mut SmallVec<[BlockRef; 8]>| {
@@ -76,6 +80,7 @@ impl SparseConditionalConstantPropagation {
7680

7781
add_to_worklist(op.regions(), &mut worklist);
7882

83+
let mut replaced_any = false;
7984
while let Some(mut block) = worklist.pop() {
8085
let mut block = block.borrow_mut();
8186
let body = block.body_mut();
@@ -91,8 +96,10 @@ impl SparseConditionalConstantPropagation {
9196
let mut replaced_all = num_results != 0;
9297
for index in 0..num_results {
9398
let result = { op.borrow().get_result(index).borrow().as_value_ref() };
94-
replaced_all &=
95-
replace_with_constant(solver, &mut builder, &mut folder, result);
99+
let replaced = replace_with_constant(solver, &mut builder, &mut folder, result);
100+
101+
replaced_any |= replaced;
102+
replaced_all &= replaced;
96103
}
97104

98105
// If all of the results of the operation were replaced, try to erase the operation
@@ -112,7 +119,7 @@ impl SparseConditionalConstantPropagation {
112119
builder.set_insertion_point_to_start(block.as_block_ref());
113120

114121
for arg in block.arguments() {
115-
replace_with_constant(
122+
replaced_any |= replace_with_constant(
116123
solver,
117124
&mut builder,
118125
&mut folder,
@@ -121,7 +128,7 @@ impl SparseConditionalConstantPropagation {
121128
}
122129
}
123130

124-
Ok(())
131+
Ok(replaced_any.into())
125132
}
126133
}
127134

hir-transform/src/sink.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use midenc_hir::{
44
adt::SmallDenseMap,
55
dominance::DominanceInfo,
66
matchers::{self, Matcher},
7-
pass::{Pass, PassExecutionState},
7+
pass::{Pass, PassExecutionState, PassIdentifier, PostPassStatus},
88
traits::{ConstantLike, Terminator},
99
Backward, Builder, EntityMut, Forward, FxHashSet, OpBuilder, Operation, OperationName,
1010
OperationRef, ProgramPoint, RawWalk, Region, RegionBranchOpInterface,
@@ -84,6 +84,10 @@ impl Pass for ControlFlowSink {
8484
"control-flow-sink"
8585
}
8686

87+
fn pass_id(&self) -> Option<PassIdentifier> {
88+
Some(PassIdentifier::ControlFlowSink)
89+
}
90+
8791
fn argument(&self) -> &'static str {
8892
"control-flow-sink"
8993
}
@@ -96,7 +100,7 @@ impl Pass for ControlFlowSink {
96100
&mut self,
97101
op: EntityMut<'_, Self::Target>,
98102
state: &mut PassExecutionState,
99-
) -> Result<(), Report> {
103+
) -> Result<PostPassStatus, Report> {
100104
let op = op.into_entity_ref();
101105
log::debug!(target: "control-flow-sink", "sinking operations in {op}");
102106

@@ -105,6 +109,7 @@ impl Pass for ControlFlowSink {
105109

106110
let dominfo = state.analysis_manager().get_analysis::<DominanceInfo>()?;
107111

112+
let mut sunk = PostPassStatus::IRUnchanged;
108113
operation.raw_prewalk_all::<Forward, _>(|op: OperationRef| {
109114
let regions_to_sink = {
110115
let op = op.borrow();
@@ -118,7 +123,7 @@ impl Pass for ControlFlowSink {
118123
};
119124

120125
// Sink side-effect free operations.
121-
control_flow_sink(
126+
sunk = control_flow_sink(
122127
&regions_to_sink,
123128
&dominfo,
124129
|op: &Operation, _region: &Region| op.is_memory_effect_free(),
@@ -132,7 +137,7 @@ impl Pass for ControlFlowSink {
132137
);
133138
});
134139

135-
Ok(())
140+
Ok(sunk)
136141
}
137142
}
138143

@@ -160,6 +165,10 @@ impl Pass for SinkOperandDefs {
160165
"sink-operand-defs"
161166
}
162167

168+
fn pass_id(&self) -> Option<PassIdentifier> {
169+
Some(PassIdentifier::SinkOperandDefs)
170+
}
171+
163172
fn argument(&self) -> &'static str {
164173
"sink-operand-defs"
165174
}
@@ -172,7 +181,7 @@ impl Pass for SinkOperandDefs {
172181
&mut self,
173182
op: EntityMut<'_, Self::Target>,
174183
_state: &mut PassExecutionState,
175-
) -> Result<(), Report> {
184+
) -> Result<PostPassStatus, Report> {
176185
let operation = op.as_operation_ref();
177186
drop(op);
178187

@@ -184,6 +193,7 @@ impl Pass for SinkOperandDefs {
184193
// then process the worklist, moving everything into position.
185194
let mut worklist = alloc::collections::VecDeque::default();
186195

196+
let mut changed = PostPassStatus::IRUnchanged;
187197
// Visit ops in "true" post-order (i.e. block bodies are visited bottom-up).
188198
operation.raw_postwalk_all::<Backward, _>(|operation: OperationRef| {
189199
// Determine if any of this operation's operands represent one of the following:
@@ -308,6 +318,7 @@ impl Pass for SinkOperandDefs {
308318
log::trace!(target: "sink-operand-defs", " rewriting operand {operand_value} as {replacement}");
309319
operand.borrow_mut().set(replacement);
310320

321+
changed = PostPassStatus::IRChanged;
311322
// If no other uses of this value remain, then remove the original
312323
// operation, as it is now dead.
313324
if !operand_value.borrow().is_used() {
@@ -354,6 +365,7 @@ impl Pass for SinkOperandDefs {
354365
log::trace!(target: "sink-operand-defs", " rewriting operand {operand_value} as {replacement}");
355366
sink_state.replacements.insert(operand_value, replacement);
356367
operand.borrow_mut().set(replacement);
368+
changed = PostPassStatus::IRChanged;
357369
} else {
358370
log::trace!(target: "sink-operand-defs", " defining op is a constant with no other uses, moving into place");
359371
// The original op can be moved
@@ -397,7 +409,7 @@ impl Pass for SinkOperandDefs {
397409
}
398410
}
399411

400-
Ok(())
412+
Ok(changed)
401413
}
402414
}
403415

@@ -548,12 +560,14 @@ pub fn control_flow_sink<P, F>(
548560
dominfo: &DominanceInfo,
549561
should_move_into_region: P,
550562
move_into_region: F,
551-
) where
563+
) -> PostPassStatus
564+
where
552565
P: Fn(&Operation, &Region) -> bool,
553566
F: Fn(OperationRef, RegionRef),
554567
{
555568
let sinker = Sinker::new(dominfo, should_move_into_region, move_into_region);
556-
sinker.sink_regions(regions);
569+
let sunk_regions = sinker.sink_regions(regions);
570+
(sunk_regions > 0).into()
557571
}
558572

559573
/// Populates `regions` with regions of the provided region branch op that are executed at most once

hir-transform/src/spill.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use midenc_hir::{
44
adt::{SmallDenseMap, SmallSet},
55
cfg::Graph,
66
dominance::{DomTreeNode, DominanceFrontier, DominanceInfo},
7-
pass::AnalysisManager,
7+
pass::{AnalysisManager, PostPassStatus},
88
traits::SingleRegion,
99
BlockRef, Builder, Context, FxHashMap, OpBuilder, OpOperand, Operation, OperationRef,
1010
ProgramPoint, Region, RegionBranchOpInterface, RegionBranchPoint, RegionRef, Report, Rewriter,
@@ -113,7 +113,7 @@ pub fn transform_spills(
113113
analysis: &mut SpillAnalysis,
114114
interface: &mut dyn TransformSpillsInterface,
115115
analysis_manager: AnalysisManager,
116-
) -> Result<(), Report> {
116+
) -> Result<PostPassStatus, Report> {
117117
assert!(
118118
op.borrow().implements::<dyn SingleRegion>(),
119119
"the spills transformation is not supported when the root op is multi-region"
@@ -252,7 +252,7 @@ pub fn transform_spills(
252252
)?;
253253
}
254254

255-
Ok(())
255+
Ok(PostPassStatus::IRChanged)
256256
}
257257

258258
fn rewrite_single_block_spills(

hir/src/ir/print.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::{
99
AttributeValue, EntityWithId, SuccessorOperands, Value,
1010
};
1111

12+
#[derive(Debug)]
1213
pub struct OpPrintingFlags {
1314
pub print_entry_block_headers: bool,
1415
pub print_intrinsic_attributes: bool,

0 commit comments

Comments
 (0)