Skip to content

Commit 6ceb163

Browse files
committed
Move some functions out of rustc_codegen_llvm and fix metadata_only backend
1 parent 4f0ca92 commit 6ceb163

File tree

12 files changed

+265
-139
lines changed

12 files changed

+265
-139
lines changed

src/bootstrap/bin/rustc.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ fn main() {
114114

115115
cmd.env("RUSTC_BREAK_ON_ICE", "1");
116116

117+
if args.iter().find(|s| **s == OsString::from("___")).is_some() {
118+
cmd.arg("-Zcodegen-backend=metadata_only");
119+
}
120+
117121
if let Some(target) = target {
118122
// The stage0 compiler has a special sysroot distinct from what we
119123
// actually downloaded, so we just always pass the `--sysroot` option.

src/bootstrap/compile.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,13 @@ pub fn std_cargo(builder: &Builder,
182182
// missing
183183
// We also only build the runtimes when --enable-sanitizers (or its
184184
// config.toml equivalent) is used
185-
let llvm_config = builder.ensure(native::Llvm {
186-
target: builder.config.build,
187-
emscripten: false,
188-
});
189-
cargo.env("LLVM_CONFIG", llvm_config);
185+
if !builder.config.rust_codegen_backends.is_empty() {
186+
let llvm_config = builder.ensure(native::Llvm {
187+
target: builder.config.build,
188+
emscripten: false,
189+
});
190+
cargo.env("LLVM_CONFIG", llvm_config);
191+
}
190192
}
191193

192194
cargo.arg("--features").arg(features)
@@ -675,7 +677,9 @@ impl Step for CodegenBackend {
675677
.arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
676678
rustc_cargo_env(builder, &mut cargo);
677679

678-
features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
680+
if !backend.is_empty() {
681+
features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
682+
}
679683

680684
let tmp_stamp = builder.cargo_out(compiler, Mode::Codegen, target)
681685
.join(".tmp.stamp");

src/librustc_codegen_llvm/base.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use builder::{Builder, MemFlags};
5656
use callee;
5757
use common::{C_bool, C_bytes_in_context, C_i32, C_usize};
5858
use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode};
59+
use rustc_mir::monomorphize::item::DefPathBasedNames;
5960
use common::{self, C_struct_in_context, C_array, val_ty};
6061
use consts;
6162
use context::{self, CodegenCx};
@@ -67,7 +68,7 @@ use monomorphize::Instance;
6768
use monomorphize::partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt};
6869
use rustc_codegen_utils::symbol_names_test;
6970
use time_graph;
70-
use mono_item::{MonoItem, BaseMonoItemExt, MonoItemExt, DefPathBasedNames};
71+
use mono_item::{MonoItem, BaseMonoItemExt, MonoItemExt};
7172
use type_::Type;
7273
use type_of::LayoutLlvmExt;
7374
use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
@@ -92,8 +93,6 @@ use syntax::ast;
9293

9394
use mir::operand::OperandValue;
9495

95-
pub use rustc_codegen_utils::check_for_rustc_errors_attr;
96-
9796
pub struct StatRecorder<'a, 'tcx: 'a> {
9897
cx: &'a CodegenCx<'a, 'tcx>,
9998
name: Option<String>,
@@ -715,7 +714,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
715714
rx: mpsc::Receiver<Box<Any + Send>>)
716715
-> OngoingCodegen {
717716

718-
check_for_rustc_errors_attr(tcx);
717+
::rustc_codegen_utils::check_for_rustc_errors_attr(tcx);
719718

720719
if let Some(true) = tcx.sess.opts.debugging_opts.thinlto {
721720
if unsafe { !llvm::LLVMRustThinLTOAvailable() } {

src/librustc_codegen_llvm/common.rs

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212

1313
//! Code that is useful in various codegen modules.
1414
15-
use llvm;
16-
use llvm::{ValueRef, ContextRef, TypeKind};
17-
use llvm::{True, False, Bool, OperandBundleDef};
15+
use llvm::{self, ValueRef, ContextRef, TypeKind, True, False, Bool, OperandBundleDef};
1816
use rustc::hir::def_id::DefId;
1917
use rustc::middle::lang_items::LangItem;
2018
use abi;
@@ -29,6 +27,8 @@ use rustc::ty::{self, Ty, TyCtxt};
2927
use rustc::ty::layout::{HasDataLayout, LayoutOf};
3028
use rustc::hir;
3129

30+
use meth;
31+
3232
use libc::{c_uint, c_char};
3333
use std::iter;
3434

@@ -448,3 +448,101 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
448448
_ => bug!("unexpected type {:?} to ty_fn_sig", ty)
449449
}
450450
}
451+
452+
pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef)
453+
-> (ValueRef, ValueRef) {
454+
debug!("calculate size of DST: {}; with lost info: {:?}",
455+
t, Value(info));
456+
if bx.cx.type_is_sized(t) {
457+
let (size, align) = bx.cx.size_and_align_of(t);
458+
debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}",
459+
t, Value(info), size, align);
460+
let size = C_usize(bx.cx, size.bytes());
461+
let align = C_usize(bx.cx, align.abi());
462+
return (size, align);
463+
}
464+
assert!(!info.is_null());
465+
match t.sty {
466+
ty::TyDynamic(..) => {
467+
// load size/align from vtable
468+
(meth::SIZE.get_usize(bx, info), meth::ALIGN.get_usize(bx, info))
469+
}
470+
ty::TySlice(_) | ty::TyStr => {
471+
let unit = t.sequence_element_type(bx.tcx());
472+
// The info in this case is the length of the str, so the size is that
473+
// times the unit size.
474+
let (size, align) = bx.cx.size_and_align_of(unit);
475+
(bx.mul(info, C_usize(bx.cx, size.bytes())),
476+
C_usize(bx.cx, align.abi()))
477+
}
478+
_ => {
479+
let cx = bx.cx;
480+
// First get the size of all statically known fields.
481+
// Don't use size_of because it also rounds up to alignment, which we
482+
// want to avoid, as the unsized field's alignment could be smaller.
483+
assert!(!t.is_simd());
484+
let layout = cx.layout_of(t);
485+
debug!("DST {} layout: {:?}", t, layout);
486+
487+
let i = layout.fields.count() - 1;
488+
let sized_size = layout.fields.offset(i).bytes();
489+
let sized_align = layout.align.abi();
490+
debug!("DST {} statically sized prefix size: {} align: {}",
491+
t, sized_size, sized_align);
492+
let sized_size = C_usize(cx, sized_size);
493+
let sized_align = C_usize(cx, sized_align);
494+
495+
// Recurse to get the size of the dynamically sized field (must be
496+
// the last field).
497+
let field_ty = layout.field(cx, i).ty;
498+
let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
499+
500+
// FIXME (#26403, #27023): We should be adding padding
501+
// to `sized_size` (to accommodate the `unsized_align`
502+
// required of the unsized field that follows) before
503+
// summing it with `sized_size`. (Note that since #26403
504+
// is unfixed, we do not yet add the necessary padding
505+
// here. But this is where the add would go.)
506+
507+
// Return the sum of sizes and max of aligns.
508+
let size = bx.add(sized_size, unsized_size);
509+
510+
// Packed types ignore the alignment of their fields.
511+
if let ty::TyAdt(def, _) = t.sty {
512+
if def.repr.packed() {
513+
unsized_align = sized_align;
514+
}
515+
}
516+
517+
// Choose max of two known alignments (combined value must
518+
// be aligned according to more restrictive of the two).
519+
let align = match (const_to_opt_u128(sized_align, false),
520+
const_to_opt_u128(unsized_align, false)) {
521+
(Some(sized_align), Some(unsized_align)) => {
522+
// If both alignments are constant, (the sized_align should always be), then
523+
// pick the correct alignment statically.
524+
C_usize(cx, ::std::cmp::max(sized_align, unsized_align) as u64)
525+
}
526+
_ => bx.select(bx.icmp(llvm::IntUGT, sized_align, unsized_align),
527+
sized_align,
528+
unsized_align)
529+
};
530+
531+
// Issue #27023: must add any necessary padding to `size`
532+
// (to make it a multiple of `align`) before returning it.
533+
//
534+
// Namely, the returned size should be, in C notation:
535+
//
536+
// `size + ((size & (align-1)) ? align : 0)`
537+
//
538+
// emulated via the semi-standard fast bit trick:
539+
//
540+
// `(size + (align-1)) & -align`
541+
542+
let addend = bx.sub(align, C_usize(bx.cx, 1));
543+
let size = bx.and(bx.add(size, addend), bx.neg(align));
544+
545+
(size, align)
546+
}
547+
}
548+
}

src/librustc_codegen_llvm/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ use rustc::ty::{self, TyCtxt};
7979
use rustc::util::nodemap::{FxHashSet, FxHashMap};
8080
use rustc_mir::monomorphize;
8181
use rustc_codegen_utils::codegen_backend::CodegenBackend;
82+
use rustc_codegen_utils::time_graph;
8283

8384
mod diagnostics;
8485

@@ -114,7 +115,6 @@ mod llvm_util;
114115
mod metadata;
115116
mod meth;
116117
mod mir;
117-
mod time_graph;
118118
mod mono_item;
119119
mod type_;
120120
mod type_of;
@@ -368,7 +368,7 @@ struct CodegenResults {
368368
crate_info: CrateInfo,
369369
}
370370

371-
// Misc info we load from metadata to persist beyond the tcx
371+
/// Misc info we load from metadata to persist beyond the tcx
372372
struct CrateInfo {
373373
panic_runtime: Option<CrateNum>,
374374
compiler_builtins: Option<CrateNum>,

src/librustc_codegen_llvm/llvm_util.rs

Lines changed: 2 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use syntax::feature_gate::UnstableFeatures;
2020
use std::sync::atomic::{AtomicBool, Ordering};
2121
use std::sync::Once;
2222

23+
pub use rustc_codegen_utils::llvm_target_features::*;
24+
2325
static POISONED: AtomicBool = AtomicBool::new(false);
2426
static INIT: Once = Once::new();
2527

@@ -79,108 +81,6 @@ unsafe fn configure_llvm(sess: &Session) {
7981
llvm_args.as_ptr());
8082
}
8183

82-
// WARNING: the features after applying `to_llvm_feature` must be known
83-
// to LLVM or the feature detection code will walk past the end of the feature
84-
// array, leading to crashes.
85-
86-
const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
87-
("mclass", Some("arm_target_feature")),
88-
("neon", Some("arm_target_feature")),
89-
("v7", Some("arm_target_feature")),
90-
("vfp2", Some("arm_target_feature")),
91-
("vfp3", Some("arm_target_feature")),
92-
("vfp4", Some("arm_target_feature")),
93-
];
94-
95-
const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[
96-
("fp", Some("aarch64_target_feature")),
97-
("neon", Some("aarch64_target_feature")),
98-
("sve", Some("aarch64_target_feature")),
99-
("crc", Some("aarch64_target_feature")),
100-
("crypto", Some("aarch64_target_feature")),
101-
("ras", Some("aarch64_target_feature")),
102-
("lse", Some("aarch64_target_feature")),
103-
("rdm", Some("aarch64_target_feature")),
104-
("fp16", Some("aarch64_target_feature")),
105-
("rcpc", Some("aarch64_target_feature")),
106-
("dotprod", Some("aarch64_target_feature")),
107-
("v8.1a", Some("aarch64_target_feature")),
108-
("v8.2a", Some("aarch64_target_feature")),
109-
("v8.3a", Some("aarch64_target_feature")),
110-
];
111-
112-
const X86_WHITELIST: &[(&str, Option<&str>)] = &[
113-
("aes", None),
114-
("avx", None),
115-
("avx2", None),
116-
("avx512bw", Some("avx512_target_feature")),
117-
("avx512cd", Some("avx512_target_feature")),
118-
("avx512dq", Some("avx512_target_feature")),
119-
("avx512er", Some("avx512_target_feature")),
120-
("avx512f", Some("avx512_target_feature")),
121-
("avx512ifma", Some("avx512_target_feature")),
122-
("avx512pf", Some("avx512_target_feature")),
123-
("avx512vbmi", Some("avx512_target_feature")),
124-
("avx512vl", Some("avx512_target_feature")),
125-
("avx512vpopcntdq", Some("avx512_target_feature")),
126-
("bmi1", None),
127-
("bmi2", None),
128-
("fma", None),
129-
("fxsr", None),
130-
("lzcnt", None),
131-
("mmx", Some("mmx_target_feature")),
132-
("pclmulqdq", None),
133-
("popcnt", None),
134-
("rdrand", None),
135-
("rdseed", None),
136-
("sha", None),
137-
("sse", None),
138-
("sse2", None),
139-
("sse3", None),
140-
("sse4.1", None),
141-
("sse4.2", None),
142-
("sse4a", Some("sse4a_target_feature")),
143-
("ssse3", None),
144-
("tbm", Some("tbm_target_feature")),
145-
("xsave", None),
146-
("xsavec", None),
147-
("xsaveopt", None),
148-
("xsaves", None),
149-
];
150-
151-
const HEXAGON_WHITELIST: &[(&str, Option<&str>)] = &[
152-
("hvx", Some("hexagon_target_feature")),
153-
("hvx-double", Some("hexagon_target_feature")),
154-
];
155-
156-
const POWERPC_WHITELIST: &[(&str, Option<&str>)] = &[
157-
("altivec", Some("powerpc_target_feature")),
158-
("power8-altivec", Some("powerpc_target_feature")),
159-
("power9-altivec", Some("powerpc_target_feature")),
160-
("power8-vector", Some("powerpc_target_feature")),
161-
("power9-vector", Some("powerpc_target_feature")),
162-
("vsx", Some("powerpc_target_feature")),
163-
];
164-
165-
const MIPS_WHITELIST: &[(&str, Option<&str>)] = &[
166-
("fp64", Some("mips_target_feature")),
167-
("msa", Some("mips_target_feature")),
168-
];
169-
170-
/// When rustdoc is running, provide a list of all known features so that all their respective
171-
/// primtives may be documented.
172-
///
173-
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
174-
/// iterator!
175-
pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<&'static str>)> {
176-
ARM_WHITELIST.iter().cloned()
177-
.chain(AARCH64_WHITELIST.iter().cloned())
178-
.chain(X86_WHITELIST.iter().cloned())
179-
.chain(HEXAGON_WHITELIST.iter().cloned())
180-
.chain(POWERPC_WHITELIST.iter().cloned())
181-
.chain(MIPS_WHITELIST.iter().cloned())
182-
}
183-
18484
pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
18585
let arch = if sess.target.target.arch == "x86_64" {
18686
"x86"
@@ -216,20 +116,6 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
216116
.map(|feature| Symbol::intern(feature)).collect()
217117
}
218118

219-
pub fn target_feature_whitelist(sess: &Session)
220-
-> &'static [(&'static str, Option<&'static str>)]
221-
{
222-
match &*sess.target.target.arch {
223-
"arm" => ARM_WHITELIST,
224-
"aarch64" => AARCH64_WHITELIST,
225-
"x86" | "x86_64" => X86_WHITELIST,
226-
"hexagon" => HEXAGON_WHITELIST,
227-
"mips" | "mips64" => MIPS_WHITELIST,
228-
"powerpc" | "powerpc64" => POWERPC_WHITELIST,
229-
_ => &[],
230-
}
231-
}
232-
233119
pub fn print_version() {
234120
// Can be called without initializing LLVM
235121
unsafe {

src/librustc_codegen_llvm/mono_item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use std::fmt;
3333

3434
pub use rustc::mir::mono::MonoItem;
3535

36-
pub use rustc_mir::monomorphize::item::*;
36+
use rustc_mir::monomorphize::item::*;
3737
pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt;
3838

3939
pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {

0 commit comments

Comments
 (0)