1use rustc_attr_ir::UnrollAttr;
4use rustc_data_structures::thin_vec::ThinVec;
5use rustc_middle::mir::*;
6use rustc_middle::ty::TyCtxt;
7use tracing::debug;
8
9use crate::builder::CFG;
10
11impl<'tcx> CFG<'tcx> {
12 pub(crate) fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
13 &self.basic_blocks[blk]
14 }
15
16 pub(crate) fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
17 &mut self.basic_blocks[blk]
18 }
19
20 #[inline(never)]
23 pub(crate) fn start_new_block(&mut self) -> BasicBlock {
24 self.basic_blocks.push(BasicBlockData::new(None, false))
25 }
26
27 pub(crate) fn start_new_cleanup_block(&mut self) -> BasicBlock {
28 let bb = self.start_new_block();
29 self.block_data_mut(bb).is_cleanup = true;
30 bb
31 }
32
33 pub(crate) fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
34 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/92ffebeceaa0a071066f233873c2438e73d70fe7/compiler/rustc_mir_build/src/builder/cfg.rs:34",
"rustc_mir_build::builder::cfg", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/92ffebeceaa0a071066f233873c2438e73d70fe7/compiler/rustc_mir_build/src/builder/cfg.rs"),
::tracing_core::__macro_support::Option::Some(34u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::cfg"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("push({0:?}, {1:?})",
block, statement) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("push({:?}, {:?})", block, statement);
35 self.block_data_mut(block).statements.push(statement);
36 }
37
38 pub(crate) fn push_assign(
39 &mut self,
40 block: BasicBlock,
41 source_info: SourceInfo,
42 place: Place<'tcx>,
43 rvalue: Rvalue<'tcx>,
44 ) {
45 self.push(
46 block,
47 Statement::new(source_info, StatementKind::Assign(Box::new((place, rvalue)))),
48 );
49 }
50
51 pub(crate) fn push_assign_constant(
52 &mut self,
53 block: BasicBlock,
54 source_info: SourceInfo,
55 temp: Place<'tcx>,
56 constant: ConstOperand<'tcx>,
57 ) {
58 self.push_assign(
59 block,
60 source_info,
61 temp,
62 Rvalue::Use(Operand::Constant(Box::new(constant)), WithRetag::Yes),
63 );
64 }
65
66 pub(crate) fn push_assign_unit(
67 &mut self,
68 block: BasicBlock,
69 source_info: SourceInfo,
70 place: Place<'tcx>,
71 tcx: TyCtxt<'tcx>,
72 ) {
73 self.push_assign(
74 block,
75 source_info,
76 place,
77 Rvalue::Use(
78 Operand::Constant(Box::new(ConstOperand {
79 span: source_info.span,
80 user_ty: None,
81 const_: Const::zero_sized(tcx.types.unit),
82 })),
83 WithRetag::Yes,
84 ),
85 );
86 }
87
88 pub(crate) fn push_fake_read(
89 &mut self,
90 block: BasicBlock,
91 source_info: SourceInfo,
92 cause: FakeReadCause,
93 place: Place<'tcx>,
94 ) {
95 let kind = StatementKind::FakeRead(Box::new((cause, place)));
96 let stmt = Statement::new(source_info, kind);
97 self.push(block, stmt);
98 }
99
100 pub(crate) fn push_place_mention(
101 &mut self,
102 block: BasicBlock,
103 source_info: SourceInfo,
104 place: Place<'tcx>,
105 ) {
106 let kind = StatementKind::PlaceMention(Box::new(place));
107 let stmt = Statement::new(source_info, kind);
108 self.push(block, stmt);
109 }
110
111 pub(crate) fn terminate(
112 &mut self,
113 block: BasicBlock,
114 source_info: SourceInfo,
115 kind: TerminatorKind<'tcx>,
116 ) -> &mut Terminator<'tcx> {
117 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/92ffebeceaa0a071066f233873c2438e73d70fe7/compiler/rustc_mir_build/src/builder/cfg.rs:117",
"rustc_mir_build::builder::cfg", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/92ffebeceaa0a071066f233873c2438e73d70fe7/compiler/rustc_mir_build/src/builder/cfg.rs"),
::tracing_core::__macro_support::Option::Some(117u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::builder::cfg"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("terminating block {0:?} <- {1:?}",
block, kind) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("terminating block {:?} <- {:?}", block, kind);
118 if true {
if !self.block_data(block).terminator.is_none() {
{
::core::panicking::panic_fmt(format_args!("terminate: block {0:?}={1:?} already has a terminator set",
block, self.block_data(block)));
}
};
};debug_assert!(
119 self.block_data(block).terminator.is_none(),
120 "terminate: block {:?}={:?} already has a terminator set",
121 block,
122 self.block_data(block)
123 );
124 self.block_data_mut(block).terminator = Some(Terminator { source_info, kind });
125 self.block_data_mut(block).terminator.as_mut().unwrap()
126 }
127
128 pub(crate) fn goto(
130 &mut self,
131 origin: BasicBlock,
132 source_info: SourceInfo,
133 target: BasicBlock,
134 ) -> &mut Terminator<'tcx> {
135 self.goto_with_hints(origin, source_info, target, ThinVec::new())
136 }
137
138 #[inline(always)]
139 pub(crate) fn goto_with_hints(
140 &mut self,
141 origin: BasicBlock,
142 source_info: SourceInfo,
143 target: BasicBlock,
144 loop_hint_attrs: ThinVec<UnrollAttr>,
145 ) -> &mut Terminator<'tcx> {
146 self.terminate(origin, source_info, TerminatorKind::Goto { target, loop_hint_attrs })
147 }
148}