Store Results in Formatter.

Instead of `ResultsCursor`.

This partly undoes the second commit from #132346; possible because
`Results::as_result_cursor` (which doesn't consume the `Results`) is now
available. Delaying the `ResultsCursor` construction will facilitate the
next couple of commits.
This commit is contained in:
Nicholas Nethercote
2025-04-21 10:05:41 +10:00
parent b8c54d6358
commit 85f6025f45

View File

@@ -201,11 +201,12 @@ struct Formatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
body: &'mir Body<'tcx>,
// The `RefCell` is used because `<Formatter as Labeller>::node_label`
// takes `&self`, but it needs to modify the cursor. This is also the
// takes `&self`, but it needs to modify the results. This is also the
// reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
// the operations that involve the mutation, i.e. within the `borrow_mut`.
cursor: RefCell<ResultsCursor<'mir, 'tcx, A>>,
results: RefCell<&'mir mut Results<'tcx, A>>,
style: OutputStyle,
reachable: DenseBitSet<BasicBlock>,
}
@@ -220,11 +221,7 @@ where
style: OutputStyle,
) -> Self {
let reachable = traversal::reachable_as_bitset(body);
Formatter { cursor: results.as_results_cursor(body).into(), style, reachable }
}
fn body(&self) -> &'mir Body<'tcx> {
self.cursor.borrow().body()
Formatter { body, results: results.into(), style, reachable }
}
}
@@ -253,7 +250,7 @@ where
type Edge = CfgEdge;
fn graph_id(&self) -> dot::Id<'_> {
let name = graphviz_safe_def_name(self.body().source.def_id());
let name = graphviz_safe_def_name(self.body.source.def_id());
dot::Id::new(format!("graph_for_def_id_{name}")).unwrap()
}
@@ -262,9 +259,12 @@ where
}
fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
let mut cursor = self.cursor.borrow_mut();
let mut fmt =
BlockFormatter { cursor: &mut cursor, style: self.style, bg: Background::Light };
let mut results = self.results.borrow_mut();
let mut fmt = BlockFormatter {
cursor: results.as_results_cursor(self.body),
style: self.style,
bg: Background::Light,
};
let label = fmt.write_node_label(*block).unwrap();
dot::LabelText::html(String::from_utf8(label).unwrap())
@@ -275,7 +275,7 @@ where
}
fn edge_label(&self, e: &Self::Edge) -> dot::LabelText<'_> {
let label = &self.body()[e.source].terminator().kind.fmt_successor_labels()[e.index];
let label = &self.body[e.source].terminator().kind.fmt_successor_labels()[e.index];
dot::LabelText::label(label.clone())
}
}
@@ -288,7 +288,7 @@ where
type Edge = CfgEdge;
fn nodes(&self) -> dot::Nodes<'_, Self::Node> {
self.body()
self.body
.basic_blocks
.indices()
.filter(|&idx| self.reachable.contains(idx))
@@ -297,10 +297,10 @@ where
}
fn edges(&self) -> dot::Edges<'_, Self::Edge> {
let body = self.body();
body.basic_blocks
self.body
.basic_blocks
.indices()
.flat_map(|bb| dataflow_successors(body, bb))
.flat_map(|bb| dataflow_successors(self.body, bb))
.collect::<Vec<_>>()
.into()
}
@@ -310,20 +310,20 @@ where
}
fn target(&self, edge: &Self::Edge) -> Self::Node {
self.body()[edge.source].terminator().successors().nth(edge.index).unwrap()
self.body[edge.source].terminator().successors().nth(edge.index).unwrap()
}
}
struct BlockFormatter<'a, 'mir, 'tcx, A>
struct BlockFormatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
cursor: &'a mut ResultsCursor<'mir, 'tcx, A>,
cursor: ResultsCursor<'mir, 'tcx, A>,
bg: Background,
style: OutputStyle,
}
impl<'tcx, A> BlockFormatter<'_, '_, 'tcx, A>
impl<'tcx, A> BlockFormatter<'_, 'tcx, A>
where
A: Analysis<'tcx>,
A::Domain: DebugWithContext<A>,