Skip to content

Commit aa11613

Browse files
committed
inline const monomorphization/evaluation
getting rid of FunctionCx
1 parent 5c40c5f commit aa11613

File tree

2 files changed

+70
-80
lines changed

2 files changed

+70
-80
lines changed

compiler/rustc_codegen_ssa/src/mir/mod.rs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -173,28 +173,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
173173
debug!("fn_abi: {:?}", fn_abi);
174174

175175
if cx.tcx().codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
176-
let cached_llbbs = IndexVec::new();
177-
178-
let fx: FunctionCx<'_, '_, Bx> = FunctionCx {
179-
instance,
180-
mir,
181-
llfn,
182-
fn_abi,
183-
cx,
184-
personality_slot: None,
185-
cached_llbbs,
186-
unreachable_block: None,
187-
terminate_block: None,
188-
cleanup_kinds: None,
189-
landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
190-
funclets: IndexVec::from_fn_n(|_| None, mir.basic_blocks.len()),
191-
locals: locals::Locals::empty(),
192-
debug_context: None,
193-
per_local_var_debug_info: None,
194-
caller_location: None,
195-
};
196-
197-
fx.codegen_naked_asm(instance);
176+
crate::mir::naked_asm::codegen_naked_asm::<Bx>(cx, &mir, instance);
198177
return;
199178
}
200179

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 69 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,85 @@
11
use crate::common;
2-
use crate::mir::FunctionCx;
32
use crate::traits::{AsmMethods, BuilderMethods, GlobalAsmOperandRef, MiscMethods};
43
use rustc_attr::InstructionSetAttr;
54
use rustc_middle::bug;
65
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
6+
use rustc_middle::mir::Body;
77
use rustc_middle::mir::InlineAsmOperand;
88
use rustc_middle::ty;
99
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
1010
use rustc_middle::ty::{Instance, TyCtxt};
1111
use rustc_target::asm::InlineAsmArch;
1212

13-
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14-
pub fn codegen_naked_asm(&self, instance: Instance<'tcx>) {
15-
let cx = &self.cx;
16-
17-
let rustc_middle::mir::TerminatorKind::InlineAsm {
18-
template,
19-
ref operands,
20-
options,
21-
line_spans,
22-
targets: _,
23-
unwind: _,
24-
} = self.mir.basic_blocks.iter().next().unwrap().terminator().kind
25-
else {
26-
bug!("#[naked] functions should always terminate with an asm! block")
27-
};
28-
29-
let operands: Vec<_> =
30-
operands.iter().map(|op| self.inline_to_global_operand(op)).collect();
31-
32-
let item_data = cx.codegen_unit().items().get(&MonoItem::Fn(instance)).unwrap();
33-
let (begin, end) = crate::mir::naked_asm::prefix_and_suffix(cx.tcx(), instance, item_data);
34-
35-
let mut template_vec = Vec::new();
36-
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(begin));
37-
template_vec.extend(template.iter().cloned());
38-
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(end));
39-
40-
cx.codegen_global_asm(&template_vec, &operands, options, line_spans);
41-
}
13+
pub fn codegen_naked_asm<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
14+
cx: &'a Bx::CodegenCx,
15+
mir: &Body<'tcx>,
16+
instance: Instance<'tcx>,
17+
) {
18+
let rustc_middle::mir::TerminatorKind::InlineAsm {
19+
template,
20+
ref operands,
21+
options,
22+
line_spans,
23+
targets: _,
24+
unwind: _,
25+
} = mir.basic_blocks.iter().next().unwrap().terminator().kind
26+
else {
27+
bug!("#[naked] functions should always terminate with an asm! block")
28+
};
4229

43-
fn inline_to_global_operand(&self, op: &InlineAsmOperand<'tcx>) -> GlobalAsmOperandRef<'tcx> {
44-
match op {
45-
InlineAsmOperand::Const { value } => {
46-
let const_value = self.eval_mir_constant(value);
47-
let string = common::asm_const_to_str(
48-
self.cx.tcx(),
49-
value.span,
50-
const_value,
51-
self.cx.layout_of(value.ty()),
52-
);
53-
GlobalAsmOperandRef::Const { string }
54-
}
55-
InlineAsmOperand::SymFn { value } => {
56-
let instance = match value.ty().kind() {
57-
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
58-
_ => bug!("asm sym is not a function"),
59-
};
30+
let operands: Vec<_> =
31+
operands.iter().map(|op| inline_to_global_operand::<Bx>(cx, instance, op)).collect();
6032

61-
GlobalAsmOperandRef::SymFn { instance }
62-
}
63-
InlineAsmOperand::SymStatic { def_id } => {
64-
GlobalAsmOperandRef::SymStatic { def_id: *def_id }
65-
}
66-
InlineAsmOperand::In { .. }
67-
| InlineAsmOperand::Out { .. }
68-
| InlineAsmOperand::InOut { .. }
69-
| InlineAsmOperand::Label { .. } => {
70-
bug!("invalid operand type for naked_asm!")
71-
}
33+
let item_data = cx.codegen_unit().items().get(&MonoItem::Fn(instance)).unwrap();
34+
let (begin, end) = crate::mir::naked_asm::prefix_and_suffix(cx.tcx(), instance, item_data);
35+
36+
let mut template_vec = Vec::new();
37+
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(begin));
38+
template_vec.extend(template.iter().cloned());
39+
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(end));
40+
41+
cx.codegen_global_asm(&template_vec, &operands, options, line_spans);
42+
}
43+
44+
fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
45+
cx: &'a Bx::CodegenCx,
46+
instance: Instance<'tcx>,
47+
op: &InlineAsmOperand<'tcx>,
48+
) -> GlobalAsmOperandRef<'tcx> {
49+
match op {
50+
InlineAsmOperand::Const { value } => {
51+
let const_value = instance
52+
.instantiate_mir_and_normalize_erasing_regions(
53+
cx.tcx(),
54+
ty::ParamEnv::reveal_all(),
55+
ty::EarlyBinder::bind(value.const_),
56+
)
57+
.eval(cx.tcx(), ty::ParamEnv::reveal_all(), value.span)
58+
.expect("erroneous constant missed by mono item collection");
59+
let string = common::asm_const_to_str(
60+
cx.tcx(),
61+
value.span,
62+
const_value,
63+
cx.layout_of(value.ty()),
64+
);
65+
GlobalAsmOperandRef::Const { string }
66+
}
67+
InlineAsmOperand::SymFn { value } => {
68+
let instance = match value.ty().kind() {
69+
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
70+
_ => bug!("asm sym is not a function"),
71+
};
72+
73+
GlobalAsmOperandRef::SymFn { instance }
74+
}
75+
InlineAsmOperand::SymStatic { def_id } => {
76+
GlobalAsmOperandRef::SymStatic { def_id: *def_id }
77+
}
78+
InlineAsmOperand::In { .. }
79+
| InlineAsmOperand::Out { .. }
80+
| InlineAsmOperand::InOut { .. }
81+
| InlineAsmOperand::Label { .. } => {
82+
bug!("invalid operand type for naked_asm!")
7283
}
7384
}
7485
}

0 commit comments

Comments
 (0)