Skip to content

Commit 2f3cc47

Browse files
authored
Replace internal reverse_postorder by a stable one (rust-lang#3064)
The `reverse_postorder` function used before is internal to the compiler and reflects the internal body representation. Besides that, I would like to introduce transformation on the top of SMIR body, which will break the 1:1 relationship between basic blocks from internal body and monomorphic body from StableMIR.
1 parent 45caad4 commit 2f3cc47

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

kani-compiler/src/codegen_cprover_gotoc/codegen/block.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

44
use crate::codegen_cprover_gotoc::GotocCtx;
5-
use stable_mir::mir::{BasicBlock, BasicBlockIdx};
5+
use stable_mir::mir::{BasicBlock, BasicBlockIdx, Body};
6+
use std::collections::HashSet;
67
use tracing::debug;
78

89
pub fn bb_label(bb: BasicBlockIdx) -> String {
@@ -72,3 +73,32 @@ impl<'tcx> GotocCtx<'tcx> {
7273
}
7374
}
7475
}
76+
77+
/// Iterate over the basic blocks in reverse post-order.
78+
///
79+
/// The `reverse_postorder` function used before was internal to the compiler and reflected the
80+
/// internal body representation.
81+
///
82+
/// As we introduce transformations on the top of SMIR body, there will be not guarantee of a
83+
/// 1:1 relationship between basic blocks from internal body and monomorphic body from StableMIR.
84+
pub fn reverse_postorder(body: &Body) -> impl Iterator<Item = BasicBlockIdx> {
85+
postorder(body, 0, &mut HashSet::with_capacity(body.blocks.len())).into_iter().rev()
86+
}
87+
88+
fn postorder(
89+
body: &Body,
90+
bb: BasicBlockIdx,
91+
visited: &mut HashSet<BasicBlockIdx>,
92+
) -> Vec<BasicBlockIdx> {
93+
if visited.contains(&bb) {
94+
return vec![];
95+
}
96+
visited.insert(bb);
97+
98+
let mut result = vec![];
99+
for succ in body.blocks[bb].terminator.successors() {
100+
result.append(&mut postorder(body, succ, visited));
101+
}
102+
result.push(bb);
103+
result
104+
}

kani-compiler/src/codegen_cprover_gotoc/codegen/function.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
//! This file contains functions related to codegenning MIR functions into gotoc
55
6+
use crate::codegen_cprover_gotoc::codegen::block::reverse_postorder;
67
use crate::codegen_cprover_gotoc::GotocCtx;
78
use cbmc::goto_program::{Expr, Stmt, Symbol};
89
use cbmc::InternString;
9-
use rustc_middle::mir::traversal::reverse_postorder;
1010
use stable_mir::mir::mono::Instance;
1111
use stable_mir::mir::{Body, Local};
1212
use stable_mir::ty::{RigidTy, TyKind};
@@ -67,9 +67,7 @@ impl<'tcx> GotocCtx<'tcx> {
6767
self.codegen_declare_variables(&body);
6868

6969
// Get the order from internal body for now.
70-
let internal_body = self.current_fn().body_internal();
71-
reverse_postorder(internal_body)
72-
.for_each(|(bb, _)| self.codegen_block(bb.index(), &body.blocks[bb.index()]));
70+
reverse_postorder(&body).for_each(|bb| self.codegen_block(bb, &body.blocks[bb]));
7371

7472
let loc = self.codegen_span_stable(instance.def.span());
7573
let stmts = self.current_fn_mut().extract_block();

kani-compiler/src/codegen_cprover_gotoc/context/current_fn.rs

-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use crate::codegen_cprover_gotoc::GotocCtx;
55
use cbmc::goto_program::Stmt;
66
use cbmc::InternedString;
7-
use rustc_middle::mir::Body as BodyInternal;
87
use rustc_middle::ty::Instance as InstanceInternal;
98
use rustc_smir::rustc_internal;
109
use stable_mir::mir::mono::Instance;
@@ -21,8 +20,6 @@ pub struct CurrentFnCtx<'tcx> {
2120
instance: Instance,
2221
/// The crate this function is from
2322
krate: String,
24-
/// The MIR for the current instance. This is using the internal representation.
25-
mir: &'tcx BodyInternal<'tcx>,
2623
/// The current instance. This is using the internal representation.
2724
instance_internal: InstanceInternal<'tcx>,
2825
/// A list of local declarations used to retrieve MIR component types.
@@ -53,7 +50,6 @@ impl<'tcx> CurrentFnCtx<'tcx> {
5350
Self {
5451
block: vec![],
5552
instance,
56-
mir: gcx.tcx.instance_mir(instance_internal.def),
5753
instance_internal,
5854
krate: instance.def.krate().name,
5955
locals,
@@ -94,11 +90,6 @@ impl<'tcx> CurrentFnCtx<'tcx> {
9490
self.instance
9591
}
9692

97-
/// The internal MIR for the function we are currently compiling using internal APIs.
98-
pub fn body_internal(&self) -> &'tcx BodyInternal<'tcx> {
99-
self.mir
100-
}
101-
10293
/// The name of the function we are currently compiling
10394
pub fn name(&self) -> String {
10495
self.name.clone()

0 commit comments

Comments
 (0)