Skip to content

Commit 7507ff6

Browse files
committed
Generalized mir::codegen_mir (and all subsequent functions)
1 parent ca3c42f commit 7507ff6

40 files changed

+1686
-1172
lines changed

src/librustc_codegen_llvm/abi.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ use mir::operand::OperandValue;
1717
use type_::Type;
1818
use type_of::{LayoutLlvmExt, PointerKind};
1919
use value::Value;
20+
use rustc_target::abi::call::ArgType;
2021

21-
use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods};
22+
use interfaces::*;
2223

2324
use rustc_target::abi::{LayoutOf, Size, TyLayout, Abi as LayoutAbi};
2425
use rustc::ty::{self, Ty};
@@ -279,6 +280,27 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
279280
}
280281
}
281282

283+
impl<'a, 'll: 'a, 'tcx: 'll> ArgTypeMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx, &'ll Value> {
284+
fn store_fn_arg(
285+
&self,
286+
ty: &ArgType<'tcx, Ty<'tcx>>,
287+
idx: &mut usize, dst: PlaceRef<'tcx, <Self::CodegenCx as Backend>::Value>
288+
) {
289+
ty.store_fn_arg(&self, idx, dst)
290+
}
291+
fn store_arg_ty(
292+
&self,
293+
ty: &ArgType<'tcx, Ty<'tcx>>,
294+
val: &'ll Value,
295+
dst: PlaceRef<'tcx, &'ll Value>
296+
) {
297+
ty.store(&self, val, dst)
298+
}
299+
fn memory_ty(&self, ty: &ArgType<'tcx, Ty<'tcx>>) -> &'ll Type {
300+
ty.memory_ty(self.cx())
301+
}
302+
}
303+
282304
pub trait FnTypeExt<'tcx> {
283305
fn of_instance(cx: &CodegenCx<'ll, 'tcx, &'ll Value>, instance: &ty::Instance<'tcx>) -> Self;
284306
fn new(cx: &CodegenCx<'ll, 'tcx, &'ll Value>,
@@ -781,3 +803,29 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
781803
}
782804
}
783805
}
806+
807+
impl AbiMethods<'tcx> for CodegenCx<'ll, 'tcx, &'ll Value> {
808+
fn new_fn_type(&self, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx, Ty<'tcx>> {
809+
FnType::new(&self, sig, extra_args)
810+
}
811+
fn new_vtable(
812+
&self,
813+
sig: ty::FnSig<'tcx>,
814+
extra_args: &[Ty<'tcx>]
815+
) -> FnType<'tcx, Ty<'tcx>> {
816+
FnType::new_vtable(&self, sig, extra_args)
817+
}
818+
fn fn_type_of_instance(&self, instance: &Instance<'tcx>) -> FnType<'tcx, Ty<'tcx>> {
819+
FnType::of_instance(&self, instance)
820+
}
821+
}
822+
823+
impl AbiBuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx, &'ll Value> {
824+
fn apply_attrs_callsite(
825+
&self,
826+
ty: &FnType<'tcx, Ty<'tcx>>,
827+
callsite: <Self::CodegenCx as Backend>::Value
828+
) {
829+
ty.apply_attrs_callsite(&self, callsite)
830+
}
831+
}

src/librustc_codegen_llvm/asm.rs

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,43 @@ use builder::Builder;
1515
use value::Value;
1616

1717
use rustc::hir;
18-
use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods};
18+
use interfaces::*;
1919

2020
use mir::place::PlaceRef;
2121
use mir::operand::OperandValue;
2222

2323
use std::ffi::CString;
2424
use libc::{c_uint, c_char};
2525

26-
// Take an inline assembly expression and splat it out via LLVM
27-
pub fn codegen_inline_asm(
28-
bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
29-
ia: &hir::InlineAsm,
30-
outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
31-
mut inputs: Vec<&'ll Value>
32-
) -> bool {
33-
let mut ext_constraints = vec![];
34-
let mut output_types = vec![];
35-
36-
// Prepare the output operands
37-
let mut indirect_outputs = vec![];
38-
for (i, (out, place)) in ia.outputs.iter().zip(&outputs).enumerate() {
39-
if out.is_rw {
40-
inputs.push(bx.load_ref(place).immediate());
41-
ext_constraints.push(i.to_string());
26+
27+
impl AsmBuilderMethods<'a, 'll, 'tcx> for Builder<'a, 'll, 'tcx, &'ll Value> {
28+
// Take an inline assembly expression and splat it out via LLVM
29+
fn codegen_inline_asm(
30+
&self,
31+
ia: &hir::InlineAsm,
32+
outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
33+
mut inputs: Vec<&'ll Value>
34+
) -> bool {
35+
let mut ext_constraints = vec![];
36+
let mut output_types = vec![];
37+
38+
// Prepare the output operands
39+
let mut indirect_outputs = vec![];
40+
for (i, (out, place)) in ia.outputs.iter().zip(&outputs).enumerate() {
41+
if out.is_rw {
42+
inputs.push(self.load_ref(place).immediate());
43+
ext_constraints.push(i.to_string());
44+
}
45+
if out.is_indirect {
46+
indirect_outputs.push(self.load_ref(place).immediate());
47+
} else {
48+
output_types.push(place.layout.llvm_type(self.cx()));
49+
}
4250
}
43-
if out.is_indirect {
44-
indirect_outputs.push(bx.load_ref(place).immediate());
45-
} else {
46-
output_types.push(place.layout.llvm_type(bx.cx()));
51+
if !indirect_outputs.is_empty() {
52+
indirect_outputs.extend_from_slice(&inputs);
53+
inputs = indirect_outputs;
4754
}
48-
}
49-
if !indirect_outputs.is_empty() {
50-
indirect_outputs.extend_from_slice(&inputs);
51-
inputs = indirect_outputs;
52-
}
5355

5456
let clobbers = ia.clobbers.iter()
5557
.map(|s| format!("~{{{}}}", &s));
@@ -103,26 +105,28 @@ pub fn codegen_inline_asm(
103105
OperandValue::Immediate(v).store(bx, place);
104106
}
105107

106-
// Store mark in a metadata node so we can map LLVM errors
107-
// back to source locations. See #17552.
108-
unsafe {
109-
let key = "srcloc";
110-
let kind = llvm::LLVMGetMDKindIDInContext(bx.cx().llcx,
111-
key.as_ptr() as *const c_char, key.len() as c_uint);
108+
// Store mark in a metadata node so we can map LLVM errors
109+
// back to source locations. See #17552.
110+
unsafe {
111+
let key = "srcloc";
112+
let kind = llvm::LLVMGetMDKindIDInContext(self.cx().llcx,
113+
key.as_ptr() as *const c_char, key.len() as c_uint);
112114

113-
let val: &'ll Value = bx.cx().const_i32(ia.ctxt.outer().as_u32() as i32);
115+
let val: &'ll Value = self.cx().const_i32(ia.ctxt.outer().as_u32() as i32);
114116

115-
llvm::LLVMSetMetadata(r, kind,
116-
llvm::LLVMMDNodeInContext(bx.cx().llcx, &val, 1));
117+
llvm::LLVMSetMetadata(r, kind,
118+
llvm::LLVMMDNodeInContext(self.cx().llcx, &val, 1));
119+
}
117120
}
118121

119122
return true;
120123
}
121124

122-
pub fn codegen_global_asm<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx, &'a Value>,
123-
ga: &hir::GlobalAsm) {
124-
let asm = CString::new(ga.asm.as_str().as_bytes()).unwrap();
125-
unsafe {
126-
llvm::LLVMRustAppendModuleInlineAsm(cx.llmod, asm.as_ptr());
125+
impl AsmMethods for CodegenCx<'ll, 'tcx, &'ll Value> {
126+
fn codegen_global_asm(&self, ga: &hir::GlobalAsm) {
127+
let asm = CString::new(ga.asm.as_str().as_bytes()).unwrap();
128+
unsafe {
129+
llvm::LLVMRustAppendModuleInlineAsm(self.llmod, asm.as_ptr());
130+
}
127131
}
128132
}

src/librustc_codegen_llvm/attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
1616
use rustc::session::Session;
1717
use rustc::session::config::Sanitizer;
1818
use rustc::ty::TyCtxt;
19-
use rustc::ty::layout::HasTyCtxt;
2019
use rustc::ty::query::Providers;
2120
use rustc_data_structures::sync::Lrc;
2221
use rustc_data_structures::fx::FxHashMap;
2322
use rustc_target::spec::PanicStrategy;
23+
use interfaces::*;
2424

2525
use attributes;
2626
use llvm::{self, Attribute};

src/librustc_codegen_llvm/base.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ use rustc_mir::monomorphize::item::DefPathBasedNames;
5858
use common::{self, IntPredicate, RealPredicate, TypeKind};
5959
use context::CodegenCx;
6060
use debuginfo;
61-
use declare;
6261
use meth;
6362
use mir;
6463
use monomorphize::Instance;
@@ -396,15 +395,18 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
396395
sess.target.target.options.is_like_msvc
397396
}
398397

399-
pub fn call_assume(bx: &Builder<'_, 'll, '_, &'ll Value>, val: &'ll Value) {
398+
pub fn call_assume<'a, 'll: 'a, 'tcx: 'll, Bx : BuilderMethods<'a, 'll ,'tcx>>(
399+
bx: &Bx,
400+
val: <Bx::CodegenCx as Backend>::Value
401+
) {
400402
let assume_intrinsic = bx.cx().get_intrinsic("llvm.assume");
401403
bx.call(assume_intrinsic, &[val], None);
402404
}
403405

404-
pub fn from_immediate<'a, 'll: 'a, 'tcx: 'll, Builder : BuilderMethods<'a, 'll ,'tcx>>(
405-
bx: &Builder,
406-
val: <Builder::CodegenCx as Backend>::Value
407-
) -> <Builder::CodegenCx as Backend>::Value {
406+
pub fn from_immediate<'a, 'll: 'a, 'tcx: 'll, Bx : BuilderMethods<'a, 'll ,'tcx>>(
407+
bx: &Bx,
408+
val: <Bx::CodegenCx as Backend>::Value
409+
) -> <Bx::CodegenCx as Backend>::Value {
408410
if bx.cx().val_ty(val) == bx.cx().type_i1() {
409411
bx.zext(val, bx.cx().type_i8())
410412
} else {
@@ -450,7 +452,7 @@ pub fn memcpy_ty<'a, 'll: 'a, 'tcx: 'll, Builder : BuilderMethods<'a, 'll, 'tcx>
450452
bx.call_memcpy(dst, src, bx.cx().const_usize(size), align, flags);
451453
}
452454

453-
pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx, &'a Value>, instance: Instance<'tcx>) {
455+
pub fn codegen_instance<'a, 'll: 'a, 'tcx: 'll>(cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>, instance: Instance<'tcx>) {
454456
let _s = if cx.sess().codegen_stats() {
455457
let mut instance_name = String::new();
456458
DefPathBasedNames::new(cx.tcx, true, true)
@@ -474,7 +476,7 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx, &'a Value>, instance:
474476
cx.stats.borrow_mut().n_closures += 1;
475477

476478
let mir = cx.tcx.instance_mir(instance.def);
477-
mir::codegen_mir(cx, lldecl, &mir, instance, sig);
479+
mir::codegen_mir::<'a, 'll, 'tcx, Builder<'a, 'll, 'tcx, &'ll Value>>(cx, lldecl, &mir, instance, sig);
478480
}
479481

480482
pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
@@ -535,15 +537,15 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx<'ll, '_, &'ll Value>) {
535537
&main_ret_ty.no_bound_vars().unwrap(),
536538
);
537539

538-
if declare::get_defined_value(cx, "main").is_some() {
540+
if cx.get_defined_value("main").is_some() {
539541
// FIXME: We should be smart and show a better diagnostic here.
540542
cx.sess().struct_span_err(sp, "entry symbol `main` defined multiple times")
541543
.help("did you use #[no_mangle] on `fn main`? Use #[start] instead")
542544
.emit();
543545
cx.sess().abort_if_errors();
544546
bug!();
545547
}
546-
let llfn = declare::declare_cfn(cx, "main", llfty);
548+
let llfn = cx.declare_cfn("main", llfty);
547549

548550
// `main` should respect same config for frame pointer elimination as rest of code
549551
attributes::set_frame_pointer_elimination(cx, llfn);

src/librustc_codegen_llvm/builder.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use value::Value;
1818
use libc::{c_uint, c_char};
1919
use rustc::ty::TyCtxt;
2020
use rustc::ty::layout::{self, Align, Size};
21-
use rustc::session::{config, Session};
21+
use rustc::session::config;
2222
use rustc_data_structures::small_c_str::SmallCStr;
2323
use interfaces::*;
2424
use syntax;
@@ -99,10 +99,6 @@ impl BuilderMethods<'a, 'll, 'tcx>
9999
Builder::new_block(self.cx, self.llfn(), name)
100100
}
101101

102-
fn sess(&self) -> &Session {
103-
self.cx.sess()
104-
}
105-
106102
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
107103
self.cx.tcx
108104
}
@@ -603,7 +599,7 @@ impl BuilderMethods<'a, 'll, 'tcx>
603599

604600

605601
fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
606-
if self.sess().target.target.arch == "amdgpu" {
602+
if self.cx().sess().target.target.arch == "amdgpu" {
607603
// amdgpu/LLVM does something weird and thinks a i64 value is
608604
// split into a v2i32, halving the bitwidth LLVM expects,
609605
// tripping an assertion. So, for now, just disable this
@@ -1378,7 +1374,7 @@ impl BuilderMethods<'a, 'll, 'tcx>
13781374
return;
13791375
}
13801376
let cx = &self.cx();
1381-
let ptr_width = &self.sess().target.target.target_pointer_width;
1377+
let ptr_width = &self.cx().sess().target.target.target_pointer_width;
13821378
let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
13831379
let memcpy = cx.get_intrinsic(&key);
13841380
let src_ptr = &self.pointercast(src, cx.type_i8p());
@@ -1397,7 +1393,7 @@ impl BuilderMethods<'a, 'll, 'tcx>
13971393
align: &'ll Value,
13981394
volatile: bool,
13991395
) -> &'ll Value {
1400-
let ptr_width = &self.sess().target.target.target_pointer_width;
1396+
let ptr_width = &self.cx().sess().target.target.target_pointer_width;
14011397
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
14021398
let llintrinsicfn = &self.cx().get_intrinsic(&intrinsic_key);
14031399
let volatile = &self.cx().const_bool(volatile);
@@ -1422,4 +1418,14 @@ impl BuilderMethods<'a, 'll, 'tcx>
14221418
fn cx(&self) -> &'a CodegenCx<'ll, 'tcx, &'ll Value> {
14231419
&self.cx
14241420
}
1421+
1422+
fn delete_basic_block(&self, bb: &'ll BasicBlock) {
1423+
unsafe {
1424+
llvm::LLVMDeleteBasicBlock(bb);
1425+
}
1426+
}
1427+
1428+
fn do_not_inline(&self, llret: &'ll Value) {
1429+
llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
1430+
}
14251431
}

src/librustc_codegen_llvm/callee.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@
1515
//! closure.
1616
1717
use attributes;
18-
use common::{self, CodegenCx};
19-
use consts;
20-
use declare;
18+
use common;
2119
use llvm;
2220
use monomorphize::Instance;
23-
use type_of::LayoutLlvmExt;
21+
use context::CodegenCx;
2422
use value::Value;
2523
use interfaces::*;
2624

@@ -40,16 +38,16 @@ pub fn get_fn(
4038
cx: &CodegenCx<'ll, 'tcx, &'ll Value>,
4139
instance: Instance<'tcx>,
4240
) -> &'ll Value {
43-
let tcx = cx.tcx;
41+
let tcx = cx.tcx();
4442

4543
debug!("get_fn(instance={:?})", instance);
4644

4745
assert!(!instance.substs.needs_infer());
4846
assert!(!instance.substs.has_escaping_bound_vars());
4947
assert!(!instance.substs.has_param_types());
5048

51-
let sig = instance.fn_sig(cx.tcx);
52-
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
49+
let sig = instance.fn_sig(cx.tcx());
50+
if let Some(&llfn) = cx.instances().borrow().get(&instance) {
5351
return llfn;
5452
}
5553

@@ -58,9 +56,9 @@ pub fn get_fn(
5856

5957
// Create a fn pointer with the substituted signature.
6058
let fn_ptr_ty = tcx.mk_fn_ptr(sig);
61-
let llptrty = cx.layout_of(fn_ptr_ty).llvm_type(cx);
59+
let llptrty = cx.backend_type(&cx.layout_of(fn_ptr_ty));
6260

63-
let llfn = if let Some(llfn) = declare::get_declared_value(cx, &sym) {
61+
let llfn = if let Some(llfn) = cx.get_declared_value(&sym) {
6462
// This is subtle and surprising, but sometimes we have to bitcast
6563
// the resulting fn pointer. The reason has to do with external
6664
// functions. If you have two crates that both bind the same C
@@ -86,17 +84,17 @@ pub fn get_fn(
8684
// other weird situations. Annoying.
8785
if cx.val_ty(llfn) != llptrty {
8886
debug!("get_fn: casting {:?} to {:?}", llfn, llptrty);
89-
consts::ptrcast(llfn, llptrty)
87+
cx.static_ptrcast(llfn, llptrty)
9088
} else {
9189
debug!("get_fn: not casting pointer!");
9290
llfn
9391
}
9492
} else {
9593
let llfn = declare::declare_fn(cx, &sym, sig);
96-
assert_eq!(common::val_ty(llfn), llptrty);
94+
assert_eq!(cx.val_ty(llfn), llptrty);
9795
debug!("get_fn: not casting pointer!");
9896

99-
if instance.def.is_inline(tcx) {
97+
if instance.def.is_inline(*tcx) {
10098
attributes::inline(cx, llfn, attributes::InlineAttr::Hint);
10199
}
102100
attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()));

0 commit comments

Comments
 (0)