Skip to content

Adding IR printing functionality to the PassManager #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 56 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a0b54f1
WIP: First draft of adding IR printing functionality of the PassManager
lima-limon-inc Apr 15, 2025
17c5065
Revert "WIP: First draft" (See commit message for more details).
lima-limon-inc Apr 16, 2025
e9220bf
Add PassExecutionState as a parameter to the run_after_pass funtion.
lima-limon-inc Apr 16, 2025
42ddc95
Revert "Add PassExecutionState as a parameter to the run_after_pass f…
lima-limon-inc Apr 16, 2025
76309ab
WIP: Move printing logic into PassInstrumentator.
lima-limon-inc Apr 16, 2025
1b36899
Cast the OperationRef into an EntityRef inside the InstrumentationPas…
lima-limon-inc Apr 21, 2025
c007ef7
Move operation printing to auxiliary print_ir function
lima-limon-inc Apr 21, 2025
511dac2
Add IRPrintConfig to the the enable_ir_print function.
lima-limon-inc Apr 21, 2025
d453707
Enable Print to only print ir after a specific pass has passed.
lima-limon-inc Apr 21, 2025
be814de
Add run_before_pass implementation for Print struct
lima-limon-inc Apr 21, 2025
129df1c
Add some initial documentation regarding PassFilters.
lima-limon-inc Apr 21, 2025
da00c03
Remove debug config from .vscode directory
lima-limon-inc Apr 22, 2025
3cd1f15
Clean code up: Add documentation, remove prints, slight refactors.
lima-limon-inc Apr 22, 2025
300ecbc
Make `run_on_operation` return a boolean indicating that the IR has b…
lima-limon-inc Apr 22, 2025
9dc31b9
Add changed parameter to run_after_pass function
lima-limon-inc Apr 22, 2025
ec456fc
Receive "only print when ir has been modified" as a CLI parameter onl…
lima-limon-inc Apr 23, 2025
56f6b6a
Introduce th IRAfterPass enum. Replace the usage of bool to indicate …
lima-limon-inc Apr 24, 2025
877da4a
Remove the Pass implementation of the Print pass. Functionality moved…
lima-limon-inc Apr 24, 2025
242d6db
Remove debug prints.
lima-limon-inc Apr 24, 2025
06464cf
Remove duplicate struct member from IRPrintConfig and clean up from O…
lima-limon-inc Apr 24, 2025
df7f506
Clean up should_print functionality in Print::run_after_pass function…
lima-limon-inc Apr 24, 2025
06527ec
Add an OperationRef to `PassInstrumentation::run_before_pipeline`
lima-limon-inc Apr 24, 2025
b758cb1
Print the name of the pass before the IR when executing run_*_pass
lima-limon-inc Apr 24, 2025
cfa6fb0
Created PassType enum. One variant for each pass.
lima-limon-inc Apr 24, 2025
5955094
Make the PassFilter store PassTypes instead of strings, use that for …
lima-limon-inc Apr 24, 2025
6a7e684
First draft of Print creation refactor.
lima-limon-inc Apr 25, 2025
fc5fe30
Make Print::new return an Option<Self>. This avoids creating a Box<Pr…
lima-limon-inc Apr 25, 2025
b5b5295
Changed with_all_symbols call to generic with_symbol_filter call
lima-limon-inc Apr 25, 2025
1c7b9b9
Remove todos
lima-limon-inc Apr 25, 2025
b84386c
Move `Print::run_before_pipeline` up
lima-limon-inc Apr 25, 2025
f51e6c1
Remove the Option from the pass filter.
lima-limon-inc Apr 25, 2025
591458b
Make the enable_ir_printing function consume and return the PassManager
lima-limon-inc Apr 25, 2025
8137b9e
Change log::error! for log::trace!
lima-limon-inc Apr 25, 2025
52a162a
If the user set the "print after modify" flag but didn't set any ir f…
lima-limon-inc Apr 28, 2025
ed579fb
Remove default macro from PassFilter enum. Removed in favor of more e…
lima-limon-inc Apr 28, 2025
56df599
Rename: PassType -> PassIdentifier; pass_type() -> pass_id()
lima-limon-inc Apr 28, 2025
00d617b
Rename: IRAfterPass -> PostPassStatus
lima-limon-inc Apr 28, 2025
bd560c0
Remove unused OpToOpPassAdaptor::pass_id()
lima-limon-inc Apr 28, 2025
e53b374
Remove outdated comment in From<bool> for PostPassStatus
lima-limon-inc Apr 28, 2025
4333d35
Changed From<String> for PassIdentifier to TryFrom for PassIdentifier
lima-limon-inc Apr 28, 2025
a1fc2ee
Simplify if let with a unwrap or return statement for "IRUnchanged"
lima-limon-inc Apr 28, 2025
a112434
Remove pub mod pass. Make pass private again.
lima-limon-inc Apr 28, 2025
d57c768
Refactor: Change match bool in favor of if ... else
lima-limon-inc Apr 28, 2025
768acb8
Move "with_*" functions inside the ::new() constructor. Also, made th…
lima-limon-inc Apr 28, 2025
3c951e7
Rename: enum PassFilter -> enum SelectedPasses
lima-limon-inc Apr 29, 2025
d497263
Add InstructionScheduler to the PassIdentifier enum, but commented out.
lima-limon-inc Apr 29, 2025
21aa490
Remove InstructionScheduler variant (and comment) from PassIdentifier…
lima-limon-inc May 5, 2025
09aa5af
Update Print struct member variable names.
lima-limon-inc May 5, 2025
e0669e8
Error if conflicting options are passed.
lima-limon-inc May 5, 2025
3838fb6
Add documentation for the Print struct
lima-limon-inc May 5, 2025
6522bae
Change Print struct documentation
lima-limon-inc May 5, 2025
1249baa
Move selected_passes up to reflect the flow better
lima-limon-inc May 5, 2025
ee46940
Re-write Print struct documentation
lima-limon-inc May 5, 2025
f841e70
Move PostPassStatus to PassExecutionState
lima-limon-inc May 9, 2025
14f4fc2
rename: IRChanged -> Changed; IRUnchanged -> Unchanged
lima-limon-inc May 9, 2025
6f83279
Remove PassIdentifier enum and use SmallVec instead of Vec.
lima-limon-inc May 9, 2025
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
16 changes: 14 additions & 2 deletions dialects/hir/src/transforms/spill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use alloc::rc::Rc;
use midenc_hir::{
adt::SmallDenseMap,
dialects::builtin::{Function, FunctionRef, LocalVariable},
pass::{Pass, PassExecutionState},
pass::{Pass, PassExecutionState, PostPassStatus},
BlockRef, BuilderExt, EntityMut, Op, OpBuilder, OperationName, OperationRef, Report, Rewriter,
SourceSpan, Spanned, Symbol, ValueRef,
};
Expand Down Expand Up @@ -38,6 +38,7 @@ impl Pass for TransformSpills {
if function.is_declaration() {
log::debug!(target: "insert-spills", "function has no body, no spills needed!");
state.preserved_analyses_mut().preserve_all();
state.set_post_pass_status(PostPassStatus::Unchanged);
return Ok(());
}
let mut analysis =
Expand All @@ -46,6 +47,7 @@ impl Pass for TransformSpills {
if !analysis.has_spills() {
log::debug!(target: "insert-spills", "no spills needed!");
state.preserved_analyses_mut().preserve_all();
state.set_post_pass_status(PostPassStatus::Unchanged);
return Ok(());
}

Expand All @@ -62,7 +64,17 @@ impl Pass for TransformSpills {

let op = function.as_operation_ref();
drop(function);
transforms::transform_spills(op, analysis, &mut interface, state.analysis_manager().clone())

let transform_result = transforms::transform_spills(
op,
analysis,
&mut interface,
state.analysis_manager().clone(),
)?;

state.set_post_pass_status(transform_result);

return Ok(());
}
}

Expand Down
5 changes: 4 additions & 1 deletion dialects/scf/src/transforms/cfg_to_scf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use midenc_hir::{
diagnostics::Severity,
dialects::builtin,
dominance::DominanceInfo,
pass::{Pass, PassExecutionState},
pass::{Pass, PassExecutionState, PostPassStatus},
Builder, EntityMut, Forward, Op, Operation, OperationName, OperationRef, RawWalk, Report,
SmallVec, Spanned, Type, ValueRange, ValueRef, WalkResult,
};
Expand Down Expand Up @@ -130,6 +130,7 @@ impl Pass for LiftControlFlowToSCF {
});

if result.was_interrupted() {
state.set_post_pass_status(PostPassStatus::Unchanged);
return result.into_result();
}

Expand All @@ -141,6 +142,8 @@ impl Pass for LiftControlFlowToSCF {
state.preserved_analyses_mut().preserve_all();
}

state.set_post_pass_status(changed.into());

Ok(())
}
}
Expand Down
23 changes: 15 additions & 8 deletions hir-transform/src/canonicalization.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::{boxed::Box, format, rc::Rc};

use midenc_hir::{
pass::{OperationPass, Pass, PassExecutionState},
pass::{OperationPass, Pass, PassExecutionState, PostPassStatus},
patterns::{self, FrozenRewritePatternSet, GreedyRewriteConfig, RewritePatternSet},
Context, EntityMut, Operation, OperationName, Report, Spanned,
};
Expand Down Expand Up @@ -96,6 +96,7 @@ impl Pass for Canonicalizer {
) -> Result<(), Report> {
let Some(rewrites) = self.rewrites.as_ref() else {
log::debug!("skipping canonicalization as there are no rewrite patterns to apply");
state.set_post_pass_status(PostPassStatus::Unchanged);
return Ok(());
};
let op = {
Expand Down Expand Up @@ -129,15 +130,21 @@ impl Pass for Canonicalizer {
}

let op = op.borrow();
match converged {
let changed = match converged {
Ok(changed) => {
log::debug!("canonicalization converged for '{}', changed={changed}", op.name())
log::debug!("canonicalization converged for '{}', changed={changed}", op.name());
changed
}
Err(changed) => log::warn!(
"canonicalization failed to converge for '{}', changed={changed}",
op.name()
),
}
Err(changed) => {
log::warn!(
"canonicalization failed to converge for '{}', changed={changed}",
op.name()
);
changed
}
};
let ir_changed = changed.into();
state.set_post_pass_status(ir_changed);

Ok(())
}
Expand Down
13 changes: 9 additions & 4 deletions hir-transform/src/sccp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl SparseConditionalConstantPropagation {
fn rewrite(
&mut self,
op: &mut Operation,
_state: &mut PassExecutionState,
state: &mut PassExecutionState,
solver: &DataFlowSolver,
) -> Result<(), Report> {
let mut worklist = SmallVec::<[BlockRef; 8]>::default();
Expand All @@ -76,6 +76,7 @@ impl SparseConditionalConstantPropagation {

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

let mut replaced_any = false;
while let Some(mut block) = worklist.pop() {
let mut block = block.borrow_mut();
let body = block.body_mut();
Expand All @@ -91,8 +92,10 @@ impl SparseConditionalConstantPropagation {
let mut replaced_all = num_results != 0;
for index in 0..num_results {
let result = { op.borrow().get_result(index).borrow().as_value_ref() };
replaced_all &=
replace_with_constant(solver, &mut builder, &mut folder, result);
let replaced = replace_with_constant(solver, &mut builder, &mut folder, result);

replaced_any |= replaced;
replaced_all &= replaced;
}

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

for arg in block.arguments() {
replace_with_constant(
replaced_any |= replace_with_constant(
solver,
&mut builder,
&mut folder,
Expand All @@ -121,6 +124,8 @@ impl SparseConditionalConstantPropagation {
}
}

state.set_post_pass_status(replaced_any.into());

Ok(())
}
}
Expand Down
19 changes: 14 additions & 5 deletions hir-transform/src/sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use midenc_hir::{
adt::SmallDenseMap,
dominance::DominanceInfo,
matchers::{self, Matcher},
pass::{Pass, PassExecutionState},
pass::{Pass, PassExecutionState, PostPassStatus},
traits::{ConstantLike, Terminator},
Backward, Builder, EntityMut, Forward, FxHashSet, OpBuilder, Operation, OperationName,
OperationRef, ProgramPoint, RawWalk, Region, RegionBranchOpInterface,
Expand Down Expand Up @@ -105,6 +105,7 @@ impl Pass for ControlFlowSink {

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

let mut sunk = PostPassStatus::Unchanged;
operation.raw_prewalk_all::<Forward, _>(|op: OperationRef| {
let regions_to_sink = {
let op = op.borrow();
Expand All @@ -118,7 +119,7 @@ impl Pass for ControlFlowSink {
};

// Sink side-effect free operations.
control_flow_sink(
sunk = control_flow_sink(
&regions_to_sink,
&dominfo,
|op: &Operation, _region: &Region| op.is_memory_effect_free(),
Expand All @@ -132,6 +133,8 @@ impl Pass for ControlFlowSink {
);
});

state.set_post_pass_status(sunk);

Ok(())
}
}
Expand Down Expand Up @@ -171,7 +174,7 @@ impl Pass for SinkOperandDefs {
fn run_on_operation(
&mut self,
op: EntityMut<'_, Self::Target>,
_state: &mut PassExecutionState,
state: &mut PassExecutionState,
) -> Result<(), Report> {
let operation = op.as_operation_ref();
drop(op);
Expand All @@ -184,6 +187,7 @@ impl Pass for SinkOperandDefs {
// then process the worklist, moving everything into position.
let mut worklist = alloc::collections::VecDeque::default();

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

changed = PostPassStatus::Changed;
// If no other uses of this value remain, then remove the original
// operation, as it is now dead.
if !operand_value.borrow().is_used() {
Expand Down Expand Up @@ -354,6 +359,7 @@ impl Pass for SinkOperandDefs {
log::trace!(target: "sink-operand-defs", " rewriting operand {operand_value} as {replacement}");
sink_state.replacements.insert(operand_value, replacement);
operand.borrow_mut().set(replacement);
changed = PostPassStatus::Changed;
} else {
log::trace!(target: "sink-operand-defs", " defining op is a constant with no other uses, moving into place");
// The original op can be moved
Expand Down Expand Up @@ -397,6 +403,7 @@ impl Pass for SinkOperandDefs {
}
}

state.set_post_pass_status(changed);
Ok(())
}
}
Expand Down Expand Up @@ -548,12 +555,14 @@ pub fn control_flow_sink<P, F>(
dominfo: &DominanceInfo,
should_move_into_region: P,
move_into_region: F,
) where
) -> PostPassStatus
where
P: Fn(&Operation, &Region) -> bool,
F: Fn(OperationRef, RegionRef),
{
let sinker = Sinker::new(dominfo, should_move_into_region, move_into_region);
sinker.sink_regions(regions);
let sunk_regions = sinker.sink_regions(regions);
(sunk_regions > 0).into()
}

/// Populates `regions` with regions of the provided region branch op that are executed at most once
Expand Down
6 changes: 3 additions & 3 deletions hir-transform/src/spill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use midenc_hir::{
adt::{SmallDenseMap, SmallSet},
cfg::Graph,
dominance::{DomTreeNode, DominanceFrontier, DominanceInfo},
pass::AnalysisManager,
pass::{AnalysisManager, PostPassStatus},
traits::SingleRegion,
BlockRef, Builder, Context, FxHashMap, OpBuilder, OpOperand, Operation, OperationRef,
ProgramPoint, Region, RegionBranchOpInterface, RegionBranchPoint, RegionRef, Report, Rewriter,
Expand Down Expand Up @@ -113,7 +113,7 @@ pub fn transform_spills(
analysis: &mut SpillAnalysis,
interface: &mut dyn TransformSpillsInterface,
analysis_manager: AnalysisManager,
) -> Result<(), Report> {
) -> Result<PostPassStatus, Report> {
assert!(
op.borrow().implements::<dyn SingleRegion>(),
"the spills transformation is not supported when the root op is multi-region"
Expand Down Expand Up @@ -252,7 +252,7 @@ pub fn transform_spills(
)?;
}

Ok(())
Ok(PostPassStatus::Changed)
}

fn rewrite_single_block_spills(
Expand Down
1 change: 1 addition & 0 deletions hir/src/ir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
AttributeValue, EntityWithId, SuccessorOperands, Value,
};

#[derive(Debug)]
pub struct OpPrintingFlags {
pub print_entry_block_headers: bool,
pub print_intrinsic_attributes: bool,
Expand Down
Loading