Skip to content

Commit 000eb60

Browse files
Make run_on_operation return a boolean indicating that the IR has been changed.
Signed-off-by: Tomas Fabrizio Orsi <[email protected]>
1 parent 11425dd commit 000eb60

File tree

9 files changed

+57
-42
lines changed

9 files changed

+57
-42
lines changed

dialects/hir/src/transforms/spill.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,22 @@ impl Pass for TransformSpills {
3131
&mut self,
3232
op: EntityMut<'_, Self::Target>,
3333
state: &mut PassExecutionState,
34-
) -> Result<(), Report> {
34+
) -> Result<bool, Report> {
3535
let function = op.into_entity_ref();
3636
log::debug!(target: "insert-spills", "computing and inserting spills for {}", function.as_operation());
3737

3838
if function.is_declaration() {
3939
log::debug!(target: "insert-spills", "function has no body, no spills needed!");
4040
state.preserved_analyses_mut().preserve_all();
41-
return Ok(());
41+
return Ok(false);
4242
}
4343
let mut analysis =
4444
state.analysis_manager().get_analysis_for::<SpillAnalysis, Function>()?;
4545

4646
if !analysis.has_spills() {
4747
log::debug!(target: "insert-spills", "no spills needed!");
4848
state.preserved_analyses_mut().preserve_all();
49-
return Ok(());
49+
return Ok(false);
5050
}
5151

5252
// 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: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl Pass for LiftControlFlowToSCF {
5151
&mut self,
5252
op: EntityMut<'_, Self::Target>,
5353
state: &mut PassExecutionState,
54-
) -> Result<(), Report> {
54+
) -> Result<bool, Report> {
5555
let mut transformation = ControlFlowToSCFTransformation;
5656
let mut changed = false;
5757

@@ -130,7 +130,8 @@ impl Pass for LiftControlFlowToSCF {
130130
});
131131

132132
if result.was_interrupted() {
133-
return result.into_result();
133+
// TODO: Maybe Change into_result implementation
134+
return result.into_result().map(|_| false);
134135
}
135136

136137
log::debug!(
@@ -141,7 +142,7 @@ impl Pass for LiftControlFlowToSCF {
141142
state.preserved_analyses_mut().preserve_all();
142143
}
143144

144-
Ok(())
145+
Ok(changed)
145146
}
146147
}
147148

hir-transform/src/canonicalization.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ impl Pass for Canonicalizer {
9393
&mut self,
9494
op: EntityMut<'_, Self::Target>,
9595
state: &mut PassExecutionState,
96-
) -> Result<(), Report> {
96+
) -> Result<bool, Report> {
9797
let Some(rewrites) = self.rewrites.as_ref() else {
9898
log::debug!("skipping canonicalization as there are no rewrite patterns to apply");
99-
return Ok(());
99+
return Ok(false);
100100
};
101101
let op = {
102102
let ptr = op.as_operation_ref();
@@ -129,16 +129,20 @@ impl Pass for Canonicalizer {
129129
}
130130

131131
let op = op.borrow();
132-
match converged {
132+
let changed = match converged {
133133
Ok(changed) => {
134-
log::debug!("canonicalization converged for '{}', changed={changed}", op.name())
134+
log::debug!("canonicalization converged for '{}', changed={changed}", op.name());
135+
changed
135136
}
136-
Err(changed) => log::warn!(
137-
"canonicalization failed to converge for '{}', changed={changed}",
138-
op.name()
139-
),
140-
}
137+
Err(changed) => {
138+
log::warn!(
139+
"canonicalization failed to converge for '{}', changed={changed}",
140+
op.name()
141+
);
142+
changed
143+
}
144+
};
141145

142-
Ok(())
146+
Ok(changed)
143147
}
144148
}

hir-transform/src/sccp.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Pass for SparseConditionalConstantPropagation {
3838
&mut self,
3939
mut op: EntityMut<'_, Self::Target>,
4040
state: &mut PassExecutionState,
41-
) -> Result<(), Report> {
41+
) -> Result<bool, Report> {
4242
// Run sparse constant propagation + dead code analysis
4343
let mut solver = DataFlowSolver::default();
4444
solver.load::<DeadCodeAnalysis>();
@@ -58,7 +58,7 @@ impl SparseConditionalConstantPropagation {
5858
op: &mut Operation,
5959
_state: &mut PassExecutionState,
6060
solver: &DataFlowSolver,
61-
) -> Result<(), Report> {
61+
) -> Result<bool, Report> {
6262
let mut worklist = SmallVec::<[BlockRef; 8]>::default();
6363

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

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

79+
let mut replaced_any = false;
7980
while let Some(mut block) = worklist.pop() {
8081
let mut block = block.borrow_mut();
8182
let body = block.body_mut();
@@ -91,8 +92,10 @@ impl SparseConditionalConstantPropagation {
9192
let mut replaced_all = num_results != 0;
9293
for index in 0..num_results {
9394
let result = { op.borrow().get_result(index).borrow().as_value_ref() };
94-
replaced_all &=
95-
replace_with_constant(solver, &mut builder, &mut folder, result);
95+
let replaced = replace_with_constant(solver, &mut builder, &mut folder, result);
96+
97+
replaced_any |= replaced;
98+
replaced_all &= replaced;
9699
}
97100

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

114117
for arg in block.arguments() {
115-
replace_with_constant(
118+
replaced_any |= replace_with_constant(
116119
solver,
117120
&mut builder,
118121
&mut folder,
@@ -121,7 +124,7 @@ impl SparseConditionalConstantPropagation {
121124
}
122125
}
123126

124-
Ok(())
127+
Ok(replaced_any)
125128
}
126129
}
127130

hir-transform/src/sink.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl Pass for ControlFlowSink {
9696
&mut self,
9797
op: EntityMut<'_, Self::Target>,
9898
state: &mut PassExecutionState,
99-
) -> Result<(), Report> {
99+
) -> Result<bool, Report> {
100100
let op = op.into_entity_ref();
101101
log::debug!(target: "control-flow-sink", "sinking operations in {op}");
102102

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

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

108+
let mut sunk = false;
108109
operation.raw_prewalk_all::<Forward, _>(|op: OperationRef| {
109110
let regions_to_sink = {
110111
let op = op.borrow();
@@ -118,7 +119,7 @@ impl Pass for ControlFlowSink {
118119
};
119120

120121
// Sink side-effect free operations.
121-
control_flow_sink(
122+
sunk = control_flow_sink(
122123
&regions_to_sink,
123124
&dominfo,
124125
|op: &Operation, _region: &Region| op.is_memory_effect_free(),
@@ -132,7 +133,7 @@ impl Pass for ControlFlowSink {
132133
);
133134
});
134135

135-
Ok(())
136+
Ok(sunk)
136137
}
137138
}
138139

@@ -172,7 +173,7 @@ impl Pass for SinkOperandDefs {
172173
&mut self,
173174
op: EntityMut<'_, Self::Target>,
174175
_state: &mut PassExecutionState,
175-
) -> Result<(), Report> {
176+
) -> Result<bool, Report> {
176177
let operation = op.as_operation_ref();
177178
drop(op);
178179

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

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

313+
changed = true;
311314
// If no other uses of this value remain, then remove the original
312315
// operation, as it is now dead.
313316
if !operand_value.borrow().is_used() {
@@ -354,6 +357,7 @@ impl Pass for SinkOperandDefs {
354357
log::trace!(target: "sink-operand-defs", " rewriting operand {operand_value} as {replacement}");
355358
sink_state.replacements.insert(operand_value, replacement);
356359
operand.borrow_mut().set(replacement);
360+
changed = true;
357361
} else {
358362
log::trace!(target: "sink-operand-defs", " defining op is a constant with no other uses, moving into place");
359363
// The original op can be moved
@@ -397,7 +401,7 @@ impl Pass for SinkOperandDefs {
397401
}
398402
}
399403

400-
Ok(())
404+
Ok(changed)
401405
}
402406
}
403407

@@ -548,12 +552,14 @@ pub fn control_flow_sink<P, F>(
548552
dominfo: &DominanceInfo,
549553
should_move_into_region: P,
550554
move_into_region: F,
551-
) where
555+
) -> bool
556+
where
552557
P: Fn(&Operation, &Region) -> bool,
553558
F: Fn(OperationRef, RegionRef),
554559
{
555560
let sinker = Sinker::new(dominfo, should_move_into_region, move_into_region);
556-
sinker.sink_regions(regions);
561+
let sunk_regions = sinker.sink_regions(regions);
562+
sunk_regions > 0
557563
}
558564

559565
/// 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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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<bool, 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,8 @@ pub fn transform_spills(
252252
)?;
253253
}
254254

255-
Ok(())
255+
// QUESTION: If the code has reached this point, then, in theory, it must've gotten changed. Right? Requires double check.
256+
Ok(true)
256257
}
257258

258259
fn rewrite_single_block_spills(

hir/src/pass.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ impl Pass for Print {
157157
&mut self,
158158
op: crate::EntityMut<'_, Self::Target>,
159159
_state: &mut PassExecutionState,
160-
) -> Result<(), crate::Report> {
160+
) -> Result<bool, crate::Report> {
161161
let op = op.into_entity_ref();
162162
self.print_ir(op);
163-
Ok(())
163+
Ok(false)
164164
}
165165
}
166166

hir/src/pass/manager.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -956,9 +956,9 @@ impl OpToOpPassAdaptor {
956956

957957
let mut result =
958958
if let Some(adaptor) = pass.as_any_mut().downcast_mut::<OpToOpPassAdaptor>() {
959-
adaptor.run_on_operation(op, &mut execution_state, verify)
959+
adaptor.run_on_operation(op, &mut execution_state, verify).map(|_| ())
960960
} else {
961-
pass.run_on_operation(op, &mut execution_state)
961+
pass.run_on_operation(op, &mut execution_state).map(|_| ())
962962
};
963963

964964
// Invalidate any non-preserved analyses
@@ -1006,7 +1006,7 @@ impl OpToOpPassAdaptor {
10061006
op: OperationRef,
10071007
state: &mut PassExecutionState,
10081008
verify: bool,
1009-
) -> Result<(), Report> {
1009+
) -> Result<bool, Report> {
10101010
let analysis_manager = state.analysis_manager();
10111011
let instrumentor = analysis_manager.pass_instrumentor();
10121012
let parent_info = PipelineParentInfo {
@@ -1041,7 +1041,7 @@ impl OpToOpPassAdaptor {
10411041
}
10421042
}
10431043

1044-
Ok(())
1044+
Ok(false)
10451045
}
10461046
}
10471047

@@ -1078,7 +1078,7 @@ impl Pass for OpToOpPassAdaptor {
10781078
&mut self,
10791079
_op: EntityMut<'_, Operation>,
10801080
_state: &mut PassExecutionState,
1081-
) -> Result<(), Report> {
1081+
) -> Result<bool, Report> {
10821082
unreachable!("unexpected call to `Pass::run_on_operation` for OpToOpPassAdaptor")
10831083
}
10841084
}

hir/src/pass/pass.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub trait OperationPass {
4444
&mut self,
4545
op: OperationRef,
4646
state: &mut PassExecutionState,
47-
) -> Result<(), Report>;
47+
) -> Result<bool, Report>;
4848
fn run_pipeline(
4949
&mut self,
5050
pipeline: &mut OpPassManager,
@@ -121,7 +121,7 @@ where
121121
&mut self,
122122
mut op: OperationRef,
123123
state: &mut PassExecutionState,
124-
) -> Result<(), Report> {
124+
) -> Result<bool, Report> {
125125
let op = <<P as Pass>::Target as PassTarget>::into_target_mut(&mut op);
126126
<P as Pass>::run_on_operation(self, op, state)
127127
}
@@ -231,7 +231,7 @@ pub trait Pass: Sized + Any {
231231
&mut self,
232232
op: EntityMut<'_, Self::Target>,
233233
state: &mut PassExecutionState,
234-
) -> Result<(), Report>;
234+
) -> Result<bool, Report>;
235235
/// Schedule an arbitrary pass pipeline on the provided operation.
236236
///
237237
/// This can be invoke any time in a pass to dynamic schedule more passes. The provided
@@ -330,7 +330,7 @@ where
330330
&mut self,
331331
op: EntityMut<'_, Self::Target>,
332332
state: &mut PassExecutionState,
333-
) -> Result<(), Report> {
333+
) -> Result<bool, Report> {
334334
(**self).run_on_operation(op, state)
335335
}
336336

0 commit comments

Comments
 (0)