Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 30de2a0

Browse files
committedDec 1, 2019
Don't force static refs to const memory
1 parent 95aad5d commit 30de2a0

File tree

1 file changed

+65
-34
lines changed

1 file changed

+65
-34
lines changed
 

‎src/constant.rs

+65-34
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_mir::interpret::{
99
StackPopInfo,
1010
};
1111

12+
use cranelift::codegen::ir::GlobalValue;
1213
use cranelift_module::*;
1314

1415
use crate::prelude::*;
@@ -94,41 +95,65 @@ pub fn trans_const_value<'tcx>(
9495
) -> CValue<'tcx> {
9596
let ty = fx.monomorphize(&const_.ty);
9697
let layout = fx.layout_of(ty);
97-
match ty.kind {
98-
ty::Bool | ty::Uint(_) => {
99-
let bits = const_.val.try_to_bits(layout.size).unwrap();
100-
CValue::const_val(fx, ty, bits)
101-
}
102-
ty::Int(_) => {
103-
let bits = const_.val.try_to_bits(layout.size).unwrap();
104-
CValue::const_val(
105-
fx,
106-
ty,
107-
rustc::mir::interpret::sign_extend(bits, layout.size),
108-
)
109-
}
110-
ty::Float(fty) => {
111-
let bits = const_.val.try_to_bits(layout.size).unwrap();
112-
let val = match fty {
113-
FloatTy::F32 => fx
114-
.bcx
115-
.ins()
116-
.f32const(Ieee32::with_bits(u32::try_from(bits).unwrap())),
117-
FloatTy::F64 => fx
118-
.bcx
119-
.ins()
120-
.f64const(Ieee64::with_bits(u64::try_from(bits).unwrap())),
121-
};
122-
CValue::by_val(val, layout)
123-
}
124-
ty::FnDef(_def_id, _substs) => CValue::by_ref(
98+
99+
if layout.is_zst() {
100+
return CValue::by_ref(
125101
fx.bcx
126102
.ins()
127-
.iconst(fx.pointer_type, fx.pointer_type.bytes() as i64),
103+
.iconst(fx.pointer_type, i64::try_from(layout.align.pref.bytes()).unwrap()),
128104
layout,
129-
),
130-
_ => trans_const_place(fx, const_).to_cvalue(fx),
105+
);
131106
}
107+
108+
if let Some(_) = fx.clif_type(layout.ty) {
109+
let val = match const_.val {
110+
ConstKind::Value(val) => val,
111+
_ => bug!("encountered bad ConstKind in codegen"),
112+
};
113+
match val {
114+
ConstValue::Scalar(x) => {
115+
match x {
116+
Scalar::Raw { data, size } => {
117+
assert_eq!(u64::from(size), layout.size.bytes());
118+
return CValue::const_val(fx, layout.ty, data);
119+
}
120+
Scalar::Ptr(ptr) => {
121+
let alloc_kind = fx.tcx.alloc_map.lock().get(ptr.alloc_id);
122+
let base_addr = match alloc_kind {
123+
Some(GlobalAlloc::Memory(alloc)) => {
124+
fx.constants_cx.todo.insert(TodoItem::Alloc(ptr.alloc_id));
125+
let data_id = data_id_for_alloc_id(fx.module, ptr.alloc_id, alloc.align);
126+
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
127+
#[cfg(debug_assertions)]
128+
fx.add_entity_comment(local_data_id, format!("{:?}", ptr.alloc_id));
129+
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
130+
}
131+
Some(GlobalAlloc::Function(instance)) => {
132+
let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
133+
let local_func_id = fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
134+
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
135+
}
136+
Some(GlobalAlloc::Static(def_id)) => {
137+
assert!(fx.tcx.is_static(def_id));
138+
let linkage = crate::linkage::get_static_ref_linkage(fx.tcx, def_id);
139+
let data_id = data_id_for_static(fx.tcx, fx.module, def_id, linkage);
140+
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
141+
#[cfg(debug_assertions)]
142+
fx.add_entity_comment(local_data_id, format!("{:?}", def_id));
143+
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
144+
}
145+
None => bug!("missing allocation {:?}", ptr.alloc_id),
146+
};
147+
let val = fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap());
148+
return CValue::by_val(val, layout);
149+
}
150+
}
151+
}
152+
_ => {}
153+
}
154+
}
155+
156+
trans_const_place(fx, const_).to_cvalue(fx)
132157
}
133158

134159
fn trans_const_place<'tcx>(
@@ -172,7 +197,10 @@ fn trans_const_place<'tcx>(
172197
let alloc_id = fx.tcx.alloc_map.lock().create_memory_alloc(alloc);
173198
fx.constants_cx.todo.insert(TodoItem::Alloc(alloc_id));
174199
let data_id = data_id_for_alloc_id(fx.module, alloc_id, alloc.align);
175-
cplace_for_dataid(fx, const_.ty, data_id)
200+
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
201+
#[cfg(debug_assertions)]
202+
fx.add_entity_comment(local_data_id, format!("{:?}", alloc_id));
203+
cplace_for_dataid(fx, const_.ty, local_data_id)
176204
}
177205

178206
fn data_id_for_alloc_id<B: Backend>(
@@ -185,6 +213,7 @@ fn data_id_for_alloc_id<B: Backend>(
185213
&format!("__alloc_{}", alloc_id.0),
186214
Linkage::Local,
187215
false,
216+
false,
188217
Some(align.bytes() as u8),
189218
)
190219
.unwrap()
@@ -211,11 +240,14 @@ fn data_id_for_static(
211240
.pref
212241
.bytes();
213242

243+
let attrs = tcx.codegen_fn_attrs(def_id);
244+
214245
let data_id = module
215246
.declare_data(
216247
&*symbol_name,
217248
linkage,
218249
is_mutable,
250+
attrs.flags.contains(rustc::hir::CodegenFnAttrFlags::THREAD_LOCAL),
219251
Some(align.try_into().unwrap()),
220252
)
221253
.unwrap();
@@ -249,9 +281,8 @@ fn data_id_for_static(
249281
fn cplace_for_dataid<'tcx>(
250282
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
251283
ty: Ty<'tcx>,
252-
data_id: DataId,
284+
local_data_id: GlobalValue,
253285
) -> CPlace<'tcx> {
254-
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
255286
let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id);
256287
let layout = fx.layout_of(fx.monomorphize(&ty));
257288
assert!(!layout.is_unsized(), "unsized statics aren't supported");

0 commit comments

Comments
 (0)
Please sign in to comment.