Skip to content

Commit c0a428e

Browse files
denismerigouxeddyb
authored andcommitted
Great separation of librustc_codegen_llvm: librustc_codegen_ssa compiles
1 parent 915382f commit c0a428e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1634
-1470
lines changed

src/librustc_codegen_llvm/base.rs

Lines changed: 9 additions & 915 deletions
Large diffs are not rendered by default.

src/librustc_codegen_llvm/builder.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,6 @@ fn noname() -> *const c_char {
5353
&CNULL
5454
}
5555

56-
bitflags! {
57-
pub struct MemFlags: u8 {
58-
const VOLATILE = 1 << 0;
59-
const NONTEMPORAL = 1 << 1;
60-
const UNALIGNED = 1 << 2;
61-
}
62-
}
63-
6456
impl BackendTypes for Builder<'_, 'll, 'tcx> {
6557
type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
6658
type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;

src/librustc_codegen_llvm/callee.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -202,35 +202,3 @@ pub fn get_fn(
202202

203203
llfn
204204
}
205-
206-
pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>(
207-
cx: &Cx,
208-
def_id: DefId,
209-
substs: &'tcx Substs<'tcx>,
210-
) -> Cx::Value {
211-
cx.get_fn(
212-
ty::Instance::resolve(
213-
cx.tcx(),
214-
ty::ParamEnv::reveal_all(),
215-
def_id,
216-
substs
217-
).unwrap()
218-
)
219-
}
220-
221-
pub fn resolve_and_get_fn_for_vtable<'tcx,
222-
Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
223-
>(
224-
cx: &Cx,
225-
def_id: DefId,
226-
substs: &'tcx Substs<'tcx>,
227-
) -> Cx::Value {
228-
cx.get_fn(
229-
ty::Instance::resolve_for_vtable(
230-
cx.tcx(),
231-
ty::ParamEnv::reveal_all(),
232-
def_id,
233-
substs
234-
).unwrap()
235-
)
236-
}

src/librustc_codegen_llvm/common.rs

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -405,88 +405,3 @@ pub fn struct_in_context(
405405
fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 {
406406
((hi as u128) << 64) | (lo as u128)
407407
}
408-
409-
pub fn langcall(tcx: TyCtxt,
410-
span: Option<Span>,
411-
msg: &str,
412-
li: LangItem)
413-
-> DefId {
414-
tcx.lang_items().require(li).unwrap_or_else(|s| {
415-
let msg = format!("{} {}", msg, s);
416-
match span {
417-
Some(span) => tcx.sess.span_fatal(span, &msg[..]),
418-
None => tcx.sess.fatal(&msg[..]),
419-
}
420-
})
421-
}
422-
423-
// To avoid UB from LLVM, these two functions mask RHS with an
424-
// appropriate mask unconditionally (i.e. the fallback behavior for
425-
// all shifts). For 32- and 64-bit types, this matches the semantics
426-
// of Java. (See related discussion on #1877 and #10183.)
427-
428-
pub fn build_unchecked_lshift<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
429-
bx: &Bx,
430-
lhs: Bx::Value,
431-
rhs: Bx::Value
432-
) -> Bx::Value {
433-
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shl, lhs, rhs);
434-
// #1877, #10183: Ensure that input is always valid
435-
let rhs = shift_mask_rhs(bx, rhs);
436-
bx.shl(lhs, rhs)
437-
}
438-
439-
pub fn build_unchecked_rshift<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
440-
bx: &Bx,
441-
lhs_t: Ty<'tcx>,
442-
lhs: Bx::Value,
443-
rhs: Bx::Value
444-
) -> Bx::Value {
445-
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
446-
// #1877, #10183: Ensure that input is always valid
447-
let rhs = shift_mask_rhs(bx, rhs);
448-
let is_signed = lhs_t.is_signed();
449-
if is_signed {
450-
bx.ashr(lhs, rhs)
451-
} else {
452-
bx.lshr(lhs, rhs)
453-
}
454-
}
455-
456-
fn shift_mask_rhs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
457-
bx: &Bx,
458-
rhs: Bx::Value
459-
) -> Bx::Value {
460-
let rhs_llty = bx.cx().val_ty(rhs);
461-
bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false))
462-
}
463-
464-
pub fn shift_mask_val<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
465-
bx: &Bx,
466-
llty: Bx::Type,
467-
mask_llty: Bx::Type,
468-
invert: bool
469-
) -> Bx::Value {
470-
let kind = bx.cx().type_kind(llty);
471-
match kind {
472-
TypeKind::Integer => {
473-
// i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
474-
let val = bx.cx().int_width(llty) - 1;
475-
if invert {
476-
bx.cx().const_int(mask_llty, !val as i64)
477-
} else {
478-
bx.cx().const_uint(mask_llty, val)
479-
}
480-
},
481-
TypeKind::Vector => {
482-
let mask = shift_mask_val(
483-
bx,
484-
bx.cx().element_type(llty),
485-
bx.cx().element_type(mask_llty),
486-
invert
487-
);
488-
bx.vector_splat(bx.cx().vector_length(mask_llty), mask)
489-
},
490-
_ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
491-
}
492-
}

src/librustc_codegen_llvm/consts.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,58 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
3131

3232
use std::ffi::{CStr, CString};
3333

34+
pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value {
35+
let mut llvals = Vec::with_capacity(alloc.relocations.len() + 1);
36+
let dl = cx.data_layout();
37+
let pointer_size = dl.pointer_size.bytes() as usize;
38+
39+
let mut next_offset = 0;
40+
for &(offset, ((), alloc_id)) in alloc.relocations.iter() {
41+
let offset = offset.bytes();
42+
assert_eq!(offset as usize as u64, offset);
43+
let offset = offset as usize;
44+
if offset > next_offset {
45+
llvals.push(cx.const_bytes(&alloc.bytes[next_offset..offset]));
46+
}
47+
let ptr_offset = read_target_uint(
48+
dl.endian,
49+
&alloc.bytes[offset..(offset + pointer_size)],
50+
).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
51+
llvals.push(cx.scalar_to_backend(
52+
Pointer::new(alloc_id, Size::from_bytes(ptr_offset)).into(),
53+
&layout::Scalar {
54+
value: layout::Primitive::Pointer,
55+
valid_range: 0..=!0
56+
},
57+
cx.type_i8p()
58+
));
59+
next_offset = offset + pointer_size;
60+
}
61+
if alloc.bytes.len() >= next_offset {
62+
llvals.push(cx.const_bytes(&alloc.bytes[next_offset ..]));
63+
}
64+
65+
cx.const_struct(&llvals, true)
66+
}
67+
68+
pub fn codegen_static_initializer(
69+
cx: &CodegenCx<'ll, 'tcx>,
70+
def_id: DefId,
71+
) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> {
72+
let instance = ty::Instance::mono(cx.tcx, def_id);
73+
let cid = GlobalId {
74+
instance,
75+
promoted: None,
76+
};
77+
let param_env = ty::ParamEnv::reveal_all();
78+
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
79+
80+
let alloc = match static_.val {
81+
ConstValue::ByRef(_, alloc, n) if n.bytes() == 0 => alloc,
82+
_ => bug!("static const eval returned {:#?}", static_),
83+
};
84+
Ok((const_alloc_to_llvm(cx, alloc), alloc))
85+
}
3486

3587
fn set_global_alignment(cx: &CodegenCx<'ll, '_>,
3688
gv: &'ll Value,

src/librustc_codegen_llvm/context.rs

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

1111
use attributes;
1212
use llvm;
13+
use llvm_util;
1314
use rustc::dep_graph::DepGraphSafe;
1415
use rustc::hir;
1516
use debuginfo;
@@ -445,6 +446,9 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
445446
attributes::apply_target_cpu_attr(self, llfn)
446447
}
447448

449+
fn closure_env_needs_indirect_debuginfo(&self) {
450+
llvm_util::get_major_version() < 6
451+
}
448452

449453
fn create_used_variable(&self) {
450454
let name = const_cstr!("llvm.used");

src/librustc_codegen_llvm/debuginfo/create_scope_map.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,6 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
2626

2727
use syntax_pos::BytePos;
2828

29-
#[derive(Clone, Copy, Debug)]
30-
pub struct MirDebugScope<D> {
31-
pub scope_metadata: Option<D>,
32-
// Start and end offsets of the file to which this DIScope belongs.
33-
// These are used to quickly determine whether some span refers to the same file.
34-
pub file_start_pos: BytePos,
35-
pub file_end_pos: BytePos,
36-
}
37-
38-
impl<D> MirDebugScope<D> {
39-
pub fn is_valid(&self) -> bool {
40-
self.scope_metadata.is_some()
41-
}
42-
}
43-
4429
/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
4530
/// If debuginfo is disabled, the returned vector is empty.
4631
pub fn create_mir_scopes(

src/librustc_codegen_llvm/debuginfo/mod.rs

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -111,54 +111,6 @@ impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> {
111111
}
112112
}
113113

114-
pub enum FunctionDebugContext<D> {
115-
RegularContext(FunctionDebugContextData<D>),
116-
DebugInfoDisabled,
117-
FunctionWithoutDebugInfo,
118-
}
119-
120-
impl<D> FunctionDebugContext<D> {
121-
pub fn get_ref<'a>(&'a self, span: Span) -> &'a FunctionDebugContextData<D> {
122-
match *self {
123-
FunctionDebugContext::RegularContext(ref data) => data,
124-
FunctionDebugContext::DebugInfoDisabled => {
125-
span_bug!(span, "{}", Self::debuginfo_disabled_message());
126-
}
127-
FunctionDebugContext::FunctionWithoutDebugInfo => {
128-
span_bug!(span, "{}", Self::should_be_ignored_message());
129-
}
130-
}
131-
}
132-
133-
fn debuginfo_disabled_message() -> &'static str {
134-
"debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
135-
}
136-
137-
fn should_be_ignored_message() -> &'static str {
138-
"debuginfo: Error trying to access FunctionDebugContext for function that should be \
139-
ignored by debug info!"
140-
}
141-
}
142-
143-
pub struct FunctionDebugContextData<D> {
144-
fn_metadata: D,
145-
source_locations_enabled: Cell<bool>,
146-
pub defining_crate: CrateNum,
147-
}
148-
149-
pub enum VariableAccess<'a, V> {
150-
// The llptr given is an alloca containing the variable's value
151-
DirectVariable { alloca: V },
152-
// The llptr given is an alloca containing the start of some pointer chain
153-
// leading to the variable's content.
154-
IndirectVariable { alloca: V, address_operations: &'a [i64] }
155-
}
156-
157-
pub enum VariableKind {
158-
ArgumentVariable(usize /*index*/),
159-
LocalVariable,
160-
}
161-
162114
/// Create any deferred debug metadata nodes
163115
pub fn finalize(cx: &CodegenCx) {
164116
if cx.dbg_cx.is_none() {
@@ -578,15 +530,24 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
578530
}
579531

580532
fn extend_scope_to_file(
581-
&self,
582-
scope_metadata: &'ll DIScope,
583-
file: &syntax_pos::SourceFile,
584-
defining_crate: CrateNum,
585-
) -> &'ll DILexicalBlock {
586-
metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate)
587-
}
533+
&self,
534+
scope_metadata: &'ll DIScope,
535+
file: &syntax_pos::SourceFile,
536+
defining_crate: CrateNum,
537+
) -> &'ll DILexicalBlock {
538+
metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate)
539+
}
588540

589541
fn debuginfo_finalize(&self) {
590542
finalize(self)
591543
}
544+
545+
fn debuginfo_upvar_decls_ops_sequence(&self, byte_offset_of_var_in_env: u64) -> &[i64] {
546+
unsafe {
547+
[llvm::LLVMRustDIBuilderCreateOpDeref(),
548+
llvm::LLVMRustDIBuilderCreateOpPlusUconst(),
549+
byte_offset_of_var_in_env as i64,
550+
llvm::LLVMRustDIBuilderCreateOpDeref()]
551+
};
552+
}
592553
}

src/librustc_codegen_llvm/debuginfo/source_loc.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,6 @@ pub fn set_source_location<D>(
5050
set_debug_location(bx, dbg_loc);
5151
}
5252

53-
/// Enables emitting source locations for the given functions.
54-
///
55-
/// Since we don't want source locations to be emitted for the function prelude,
56-
/// they are disabled when beginning to codegen a new function. This functions
57-
/// switches source location emitting on and must therefore be called before the
58-
/// first real statement/expression of the function is codegened.
59-
pub fn start_emitting_source_locations<D>(dbg_context: &FunctionDebugContext<D>) {
60-
if let FunctionDebugContext::RegularContext(ref data) = *dbg_context {
61-
data.source_locations_enabled.set(true);
62-
}
63-
}
64-
6553

6654
#[derive(Copy, Clone, PartialEq)]
6755
pub enum InternalDebugLocation<'ll> {

src/librustc_codegen_llvm/diagnostics.rs

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,37 +47,4 @@ unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
4747
```
4848
"##,
4949

50-
E0668: r##"
51-
Malformed inline assembly rejected by LLVM.
52-
53-
LLVM checks the validity of the constraints and the assembly string passed to
54-
it. This error implies that LLVM seems something wrong with the inline
55-
assembly call.
56-
57-
In particular, it can happen if you forgot the closing bracket of a register
58-
constraint (see issue #51430):
59-
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
60-
#![feature(asm)]
61-
62-
fn main() {
63-
let rax: u64;
64-
unsafe {
65-
asm!("" :"={rax"(rax));
66-
println!("Accumulator is: {}", rax);
67-
}
68-
}
69-
```
70-
"##,
71-
72-
E0669: r##"
73-
Cannot convert inline assembly operand to a single LLVM value.
74-
75-
This error usually happens when trying to pass in a value to an input inline
76-
assembly operand that is actually a pair of values. In particular, this can
77-
happen when trying to pass in a slice, for instance a `&str`. In Rust, these
78-
values are represented internally as a pair of values, the pointer and its
79-
length. When passed as an input operand, this pair of values can not be
80-
coerced into a register and thus we must fail with an error.
81-
"##,
82-
8350
}

0 commit comments

Comments
 (0)