Skip to content

Commit 48af59f

Browse files
committed
Generalized mono_item.rs and base.rs:codegen_instance
1 parent 88a5dea commit 48af59f

File tree

6 files changed

+139
-93
lines changed

6 files changed

+139
-93
lines changed

src/librustc_codegen_llvm/base.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,28 +89,33 @@ use value::Value;
8989
use mir::operand::OperandValue;
9090

9191
use rustc_codegen_utils::check_for_rustc_errors_attr;
92+
use std::marker::PhantomData;
9293

93-
pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> {
94-
cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>,
94+
pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll, Cx: 'a + CodegenMethods<'ll, 'tcx>> {
95+
cx: &'a Cx,
9596
name: Option<String>,
9697
istart: usize,
98+
phantom: PhantomData<(&'ll (), &'tcx ())>
9799
}
98100

99-
impl StatRecorder<'a, 'll, 'tcx> {
100-
pub fn new(cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>, name: String) -> Self {
101-
let istart = cx.stats.borrow().n_llvm_insns;
101+
impl<'a, 'll: 'a, 'tcx: 'll, Cx: 'a + CodegenMethods<'ll, 'tcx>> StatRecorder<'a, 'll, 'tcx, Cx> {
102+
pub fn new(cx: &'a Cx, name: String) -> Self {
103+
let istart = cx.stats().borrow().n_llvm_insns;
102104
StatRecorder {
103105
cx,
104106
name: Some(name),
105107
istart,
108+
phantom: PhantomData
106109
}
107110
}
108111
}
109112

110-
impl Drop for StatRecorder<'a, 'll, 'tcx> {
113+
impl<'a, 'll: 'a, 'tcx: 'll, Cx: 'a + CodegenMethods<'ll, 'tcx>> Drop for
114+
StatRecorder<'a, 'll, 'tcx, Cx>
115+
{
111116
fn drop(&mut self) {
112117
if self.cx.sess().codegen_stats() {
113-
let mut stats = self.cx.stats.borrow_mut();
118+
let mut stats = self.cx.stats().borrow_mut();
114119
let iend = stats.n_llvm_insns;
115120
stats.fn_stats.push((self.name.take().unwrap(), iend - self.istart));
116121
stats.n_fns += 1;
@@ -451,13 +456,13 @@ pub fn memcpy_ty<'a, 'll: 'a, 'tcx: 'll, Builder : BuilderMethods<'a, 'll, 'tcx>
451456
bx.call_memcpy(dst, src, bx.cx().const_usize(size), align, flags);
452457
}
453458

454-
pub fn codegen_instance<'a, 'll: 'a, 'tcx: 'll>(
455-
cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>,
459+
pub fn codegen_instance<'a, 'll: 'a, 'tcx: 'll, Bx: BuilderMethods<'a, 'll, 'tcx>>(
460+
cx: &'a Bx::CodegenCx,
456461
instance: Instance<'tcx>
457-
) {
462+
) where &'a Bx::CodegenCx : LayoutOf<Ty = Ty<'tcx>, TyLayout=TyLayout<'tcx>> + HasTyCtxt<'tcx> {
458463
let _s = if cx.sess().codegen_stats() {
459464
let mut instance_name = String::new();
460-
DefPathBasedNames::new(cx.tcx, true, true)
465+
DefPathBasedNames::new(*cx.tcx(), true, true)
461466
.push_def_path(instance.def_id(), &mut instance_name);
462467
Some(StatRecorder::new(cx, instance_name))
463468
} else {
@@ -469,17 +474,17 @@ pub fn codegen_instance<'a, 'll: 'a, 'tcx: 'll>(
469474
// release builds.
470475
info!("codegen_instance({})", instance);
471476

472-
let fn_ty = instance.ty(cx.tcx);
477+
let fn_ty = instance.ty(*cx.tcx());
473478
let sig = common::ty_fn_sig(cx, fn_ty);
474-
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
479+
let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
475480

476-
let lldecl = cx.instances.borrow().get(&instance).cloned().unwrap_or_else(||
481+
let lldecl = cx.instances().borrow().get(&instance).cloned().unwrap_or_else(||
477482
bug!("Instance `{:?}` not already declared", instance));
478483

479-
cx.stats.borrow_mut().n_closures += 1;
484+
cx.stats().borrow_mut().n_closures += 1;
480485

481-
let mir = cx.tcx.instance_mir(instance.def);
482-
mir::codegen_mir::<'a, 'll, 'tcx, Builder<'a, 'll, 'tcx, &'ll Value>>(
486+
let mir = cx.tcx().instance_mir(instance.def);
487+
mir::codegen_mir::<'a, 'll, 'tcx, Bx>(
483488
cx, lldecl, &mir, instance, sig
484489
);
485490
}

src/librustc_codegen_llvm/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,14 @@ impl MiscMethods<'ll, 'tcx> for CodegenCx<'ll, 'tcx, &'ll Value> {
418418
fn check_overflow(&self) -> bool {
419419
self.check_overflow
420420
}
421+
422+
fn stats(&self) -> &RefCell<Stats> {
423+
&self.stats
424+
}
425+
426+
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>> {
427+
&self.codegen_unit
428+
}
421429
}
422430

423431
impl<'ll, 'tcx: 'll> CodegenMethods<'ll, 'tcx> for CodegenCx<'ll, 'tcx, &'ll Value> {}

src/librustc_codegen_llvm/interfaces/declare.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111
use rustc::ty::Ty;
1212
use super::backend::Backend;
13+
use rustc::hir::def_id::DefId;
14+
use rustc::mir::mono::{Linkage, Visibility};
15+
use monomorphize::Instance;
1316

1417
pub trait DeclareMethods<'ll, 'tcx: 'll> : Backend<'ll> {
1518
fn declare_global(
@@ -45,3 +48,20 @@ pub trait DeclareMethods<'ll, 'tcx: 'll> : Backend<'ll> {
4548
fn get_declared_value(&self, name: &str) -> Option<Self::Value>;
4649
fn get_defined_value(&self, name: &str) -> Option<Self::Value>;
4750
}
51+
52+
pub trait PreDefineMethods<'ll, 'tcx: 'll> : Backend<'ll> {
53+
fn predefine_static(
54+
&self,
55+
def_id: DefId,
56+
linkage: Linkage,
57+
visibility: Visibility,
58+
symbol_name: &str
59+
);
60+
fn predefine_fn(
61+
&self,
62+
instance: Instance<'tcx>,
63+
linkage: Linkage,
64+
visibility: Visibility,
65+
symbol_name: &str
66+
);
67+
}

src/librustc_codegen_llvm/interfaces/misc.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ use rustc::ty::{Ty, self, Instance};
1414
use super::backend::Backend;
1515
use rustc::session::Session;
1616
use libc::c_uint;
17+
use rustc::mir::mono::Stats;
18+
use std::sync::Arc;
19+
use monomorphize::partitioning::CodegenUnit;
1720

1821
pub trait MiscMethods<'ll, 'tcx: 'll> : Backend<'ll> {
1922
fn vtables(&self) -> &RefCell<FxHashMap<(Ty<'tcx>,
@@ -25,4 +28,6 @@ pub trait MiscMethods<'ll, 'tcx: 'll> : Backend<'ll> {
2528
fn eh_personality(&self) -> Self::Value;
2629
fn eh_unwind_resume(&self) -> Self::Value;
2730
fn sess(&self) -> &Session;
31+
fn stats(&self) -> &RefCell<Stats>;
32+
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
2833
}

src/librustc_codegen_llvm/interfaces/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ pub use self::statics::StaticMethods;
3030
pub use self::misc::MiscMethods;
3131
pub use self::debuginfo::{DebugInfoMethods, DebugInfoBuilderMethods};
3232
pub use self::abi::{AbiMethods, AbiBuilderMethods};
33-
pub use self::declare::DeclareMethods;
33+
pub use self::declare::{DeclareMethods, PreDefineMethods};
3434
pub use self::asm::{AsmMethods, AsmBuilderMethods};
3535

3636
use std::fmt;
3737

3838
pub trait CodegenMethods<'ll, 'tcx: 'll> :
3939
Backend<'ll> + TypeMethods<'ll, 'tcx> + MiscMethods<'ll, 'tcx> + ConstMethods<'ll, 'tcx> +
4040
StaticMethods<'ll> + DebugInfoMethods<'ll, 'tcx> + AbiMethods<'tcx> +
41-
IntrinsicDeclarationMethods<'ll> + DeclareMethods<'ll, 'tcx> + AsmMethods {}
41+
IntrinsicDeclarationMethods<'ll> + DeclareMethods<'ll, 'tcx> + AsmMethods +
42+
PreDefineMethods<'ll, 'tcx> {}
4243

4344
pub trait CodegenObject : Copy + PartialEq + fmt::Debug {}

src/librustc_codegen_llvm/mono_item.rs

Lines changed: 81 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,30 @@ use rustc::hir;
2424
use rustc::hir::def::Def;
2525
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
2626
use rustc::mir::mono::{Linkage, Visibility};
27-
use rustc::ty::TypeFoldable;
28-
use rustc::ty::layout::LayoutOf;
27+
use rustc::ty::{TypeFoldable, Ty};
28+
use rustc::ty::layout::{LayoutOf, HasTyCtxt, TyLayout};
2929
use std::fmt;
3030
use value::Value;
31+
use builder::Builder;
3132
use interfaces::*;
3233

3334
pub use rustc::mir::mono::MonoItem;
3435

3536
pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt;
3637

37-
pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
38-
fn define(&self, cx: &CodegenCx<'a, 'tcx, &'a Value>) {
38+
pub trait MonoItemExt<'a, 'll: 'a, 'tcx: 'll, Bx: BuilderMethods<'a, 'll, 'tcx>> :
39+
fmt::Debug + BaseMonoItemExt<'ll, 'tcx> where
40+
&'a Bx::CodegenCx : LayoutOf<Ty = Ty<'tcx>, TyLayout=TyLayout<'tcx>> + HasTyCtxt<'tcx>
41+
{
42+
fn define(&self, cx: &'a Bx::CodegenCx) {
3943
debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}",
40-
self.to_string(cx.tcx),
44+
self.to_string(*cx.tcx()),
4145
self.to_raw_string(),
42-
cx.codegen_unit.name());
46+
cx.codegen_unit().name());
4347

4448
match *self.as_mono_item() {
4549
MonoItem::Static(def_id) => {
46-
let tcx = cx.tcx;
50+
let tcx = *cx.tcx();
4751
let is_mutable = match tcx.describe_def(def_id) {
4852
Some(Def::Static(_, is_mutable)) => is_mutable,
4953
Some(other) => {
@@ -56,51 +60,51 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
5660
cx.codegen_static(def_id, is_mutable);
5761
}
5862
MonoItem::GlobalAsm(node_id) => {
59-
let item = cx.tcx.hir.expect_item(node_id);
63+
let item = cx.tcx().hir.expect_item(node_id);
6064
if let hir::ItemKind::GlobalAsm(ref ga) = item.node {
6165
cx.codegen_global_asm(ga);
6266
} else {
6367
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
6468
}
6569
}
6670
MonoItem::Fn(instance) => {
67-
base::codegen_instance(&cx, instance);
71+
base::codegen_instance::<'a, 'll, 'tcx, Bx>(&cx, instance);
6872
}
6973
}
7074

7175
debug!("END IMPLEMENTING '{} ({})' in cgu {}",
72-
self.to_string(cx.tcx),
76+
self.to_string(*cx.tcx()),
7377
self.to_raw_string(),
74-
cx.codegen_unit.name());
78+
cx.codegen_unit().name());
7579
}
7680

7781
fn predefine(&self,
78-
cx: &CodegenCx<'a, 'tcx, &'a Value>,
82+
cx: &'a Bx::CodegenCx,
7983
linkage: Linkage,
8084
visibility: Visibility) {
8185
debug!("BEGIN PREDEFINING '{} ({})' in cgu {}",
82-
self.to_string(cx.tcx),
86+
self.to_string(*cx.tcx()),
8387
self.to_raw_string(),
84-
cx.codegen_unit.name());
88+
cx.codegen_unit().name());
8589

86-
let symbol_name = self.symbol_name(cx.tcx).as_str();
90+
let symbol_name = self.symbol_name(*cx.tcx()).as_str();
8791

8892
debug!("symbol {}", &symbol_name);
8993

9094
match *self.as_mono_item() {
9195
MonoItem::Static(def_id) => {
92-
predefine_static(cx, def_id, linkage, visibility, &symbol_name);
96+
cx.predefine_static(def_id, linkage, visibility, &symbol_name);
9397
}
9498
MonoItem::Fn(instance) => {
95-
predefine_fn(cx, instance, linkage, visibility, &symbol_name);
99+
cx.predefine_fn(instance, linkage, visibility, &symbol_name);
96100
}
97101
MonoItem::GlobalAsm(..) => {}
98102
}
99103

100104
debug!("END PREDEFINING '{} ({})' in cgu {}",
101-
self.to_string(cx.tcx),
105+
self.to_string(*cx.tcx()),
102106
self.to_raw_string(),
103-
cx.codegen_unit.name());
107+
cx.codegen_unit().name());
104108
}
105109

106110
fn to_raw_string(&self) -> String {
@@ -120,68 +124,71 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
120124
}
121125
}
122126

123-
impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {}
127+
impl<'a, 'll:'a, 'tcx: 'll> MonoItemExt<'a, 'll, 'tcx, Builder<'a, 'll, 'tcx, &'ll Value>>
128+
for MonoItem<'tcx> {}
124129

125-
fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx, &'a Value>,
126-
def_id: DefId,
127-
linkage: Linkage,
128-
visibility: Visibility,
129-
symbol_name: &str) {
130-
let instance = Instance::mono(cx.tcx, def_id);
131-
let ty = instance.ty(cx.tcx);
132-
let llty = cx.layout_of(ty).llvm_type(cx);
133-
134-
let g = cx.define_global(symbol_name, llty).unwrap_or_else(|| {
135-
cx.sess().span_fatal(cx.tcx.def_span(def_id),
136-
&format!("symbol `{}` is already defined", symbol_name))
137-
});
138-
139-
unsafe {
140-
llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage));
141-
llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility));
142-
}
130+
impl<'ll, 'tcx: 'll> PreDefineMethods<'ll, 'tcx> for CodegenCx<'ll, 'tcx, &'ll Value> {
131+
fn predefine_static(&self,
132+
def_id: DefId,
133+
linkage: Linkage,
134+
visibility: Visibility,
135+
symbol_name: &str) {
136+
let instance = Instance::mono(self.tcx, def_id);
137+
let ty = instance.ty(self.tcx);
138+
let llty = self.layout_of(ty).llvm_type(self);
143139

144-
cx.instances.borrow_mut().insert(instance, g);
145-
}
140+
let g = self.define_global(symbol_name, llty).unwrap_or_else(|| {
141+
self.sess().span_fatal(self.tcx.def_span(def_id),
142+
&format!("symbol `{}` is already defined", symbol_name))
143+
});
146144

147-
fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx, &'a Value>,
148-
instance: Instance<'tcx>,
149-
linkage: Linkage,
150-
visibility: Visibility,
151-
symbol_name: &str) {
152-
assert!(!instance.substs.needs_infer() &&
153-
!instance.substs.has_param_types());
154-
155-
let mono_ty = instance.ty(cx.tcx);
156-
let attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
157-
let lldecl = cx.declare_fn(symbol_name, mono_ty);
158-
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
159-
base::set_link_section(lldecl, &attrs);
160-
if linkage == Linkage::LinkOnceODR ||
161-
linkage == Linkage::WeakODR {
162-
llvm::SetUniqueComdat(cx.llmod, lldecl);
145+
unsafe {
146+
llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage));
147+
llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility));
148+
}
149+
150+
self.instances.borrow_mut().insert(instance, g);
163151
}
164152

165-
// If we're compiling the compiler-builtins crate, e.g. the equivalent of
166-
// compiler-rt, then we want to implicitly compile everything with hidden
167-
// visibility as we're going to link this object all over the place but
168-
// don't want the symbols to get exported.
169-
if linkage != Linkage::Internal && linkage != Linkage::Private &&
170-
cx.tcx.is_compiler_builtins(LOCAL_CRATE) {
171-
unsafe {
172-
llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden);
153+
fn predefine_fn(&self,
154+
instance: Instance<'tcx>,
155+
linkage: Linkage,
156+
visibility: Visibility,
157+
symbol_name: &str) {
158+
assert!(!instance.substs.needs_infer() &&
159+
!instance.substs.has_param_types());
160+
161+
let mono_ty = instance.ty(self.tcx);
162+
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
163+
let lldecl = self.declare_fn(symbol_name, mono_ty);
164+
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
165+
base::set_link_section(lldecl, &attrs);
166+
if linkage == Linkage::LinkOnceODR ||
167+
linkage == Linkage::WeakODR {
168+
llvm::SetUniqueComdat(self.llmod, lldecl);
173169
}
174-
} else {
175-
unsafe {
176-
llvm::LLVMRustSetVisibility(lldecl, base::visibility_to_llvm(visibility));
170+
171+
// If we're compiling the compiler-builtins crate, e.g. the equivalent of
172+
// compiler-rt, then we want to implicitly compile everything with hidden
173+
// visibility as we're going to link this object all over the place but
174+
// don't want the symbols to get exported.
175+
if linkage != Linkage::Internal && linkage != Linkage::Private &&
176+
self.tcx.is_compiler_builtins(LOCAL_CRATE) {
177+
unsafe {
178+
llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden);
179+
}
180+
} else {
181+
unsafe {
182+
llvm::LLVMRustSetVisibility(lldecl, base::visibility_to_llvm(visibility));
183+
}
177184
}
178-
}
179185

180-
debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
181-
if instance.def.is_inline(cx.tcx) {
182-
attributes::inline(cx, lldecl, attributes::InlineAttr::Hint);
183-
}
184-
attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id()));
186+
debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
187+
if instance.def.is_inline(self.tcx) {
188+
attributes::inline(self, lldecl, attributes::InlineAttr::Hint);
189+
}
190+
attributes::from_fn_attrs(self, lldecl, Some(instance.def.def_id()));
185191

186-
cx.instances.borrow_mut().insert(instance, lldecl);
192+
self.instances.borrow_mut().insert(instance, lldecl);
193+
}
187194
}

0 commit comments

Comments
 (0)