$$(call CFG_CC_INCLUDE_$(1),$$(S)src/rustllvm/include)
RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=$(1)/rustllvm/%.o)
+# Flag that we are building with Rust's llvm fork
+ifeq ($(CFG_LLVM_ROOT),)
+RUSTLLVM_CXXFLAGS_$(1) := -DLLVM_RUSTLLVM
+endif
+
# Note that we appease `cl.exe` and its need for some sort of exception
# handling flag with the `EHsc` argument here as well.
ifeq ($$(findstring msvc,$(1)),msvc)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@,) \
$$(subst /,//,$$(LLVM_CXXFLAGS_$(1))) \
$$(RUSTLLVM_COMPONENTS_$(1)) \
+ $$(RUSTLLVM_CXXFLAGS_$(1)) \
$$(EXTRA_RUSTLLVM_CXXFLAGS_$(1)) \
$$(RUSTLLVM_INCS_$(1)) \
$$<
if !build.unstable_features {
cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
}
+ // Flag that rust llvm is in use
+ if build.config.target_config.get(target).is_none() {
+ cargo.env("LLVM_RUSTLLVM", "1");
+ }
cargo.env("LLVM_CONFIG", build.llvm_config(target));
if build.config.llvm_static_stdcpp {
cargo.env("LLVM_STATIC_STDCPP",
CrateName,
Cfg,
TargetList,
+ TargetCPUs,
+ TargetFeatures,
+ RelocationModels,
+ CodeModels,
}
pub enum Input {
lto: bool = (false, parse_bool,
"perform LLVM link-time optimizations"),
target_cpu: Option<String> = (None, parse_opt_string,
- "select target processor (llc -mcpu=help for details)"),
+ "select target processor (rustc --print target-cpus for details)"),
target_feature: String = ("".to_string(), parse_string,
- "target specific attributes (llc -mattr=help for details)"),
+ "target specific attributes (rustc --print target-features for details)"),
passes: Vec<String> = (Vec::new(), parse_list,
"a list of extra LLVM passes to run (space separated)"),
llvm_args: Vec<String> = (Vec::new(), parse_list,
no_redzone: Option<bool> = (None, parse_opt_bool,
"disable the use of the redzone"),
relocation_model: Option<String> = (None, parse_opt_string,
- "choose the relocation model to use (llc -relocation-model for details)"),
+ "choose the relocation model to use (rustc --print relocation-models for details)"),
code_model: Option<String> = (None, parse_opt_string,
- "choose the code model to use (llc -code-model for details)"),
+ "choose the code model to use (rustc --print code-models for details)"),
metadata: Vec<String> = (Vec::new(), parse_list,
"metadata to mangle symbol names with"),
extra_filename: String = ("".to_string(), parse_string,
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
opt::multi_s("", "print", "Comma separated list of compiler information to \
print on stdout",
- "[crate-name|file-names|sysroot|cfg|target-list]"),
+ "[crate-name|file-names|sysroot|cfg|target-list|target-cpus|\
+ target-features|relocation-models|code-models]"),
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
early_error(error_format, "Value for codegen units must be a positive nonzero integer");
}
+ let mut prints = Vec::<PrintRequest>::new();
+ if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
+ prints.push(PrintRequest::TargetCPUs);
+ cg.target_cpu = None;
+ };
+ if cg.target_feature == "help" {
+ prints.push(PrintRequest::TargetFeatures);
+ cg.target_feature = "".to_string();
+ }
+ if cg.relocation_model.as_ref().map_or(false, |s| s == "help") {
+ prints.push(PrintRequest::RelocationModels);
+ cg.relocation_model = None;
+ }
+ if cg.code_model.as_ref().map_or(false, |s| s == "help") {
+ prints.push(PrintRequest::CodeModels);
+ cg.code_model = None;
+ }
+
let cg = cg;
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
let test = matches.opt_present("test");
- let prints = matches.opt_strs("print").into_iter().map(|s| {
+ prints.extend(matches.opt_strs("print").into_iter().map(|s| {
match &*s {
"crate-name" => PrintRequest::CrateName,
"file-names" => PrintRequest::FileNames,
"sysroot" => PrintRequest::Sysroot,
"cfg" => PrintRequest::Cfg,
"target-list" => PrintRequest::TargetList,
+ "target-cpus" => PrintRequest::TargetCPUs,
+ "target-features" => PrintRequest::TargetFeatures,
+ "relocation-models" => PrintRequest::RelocationModels,
+ "code-models" => PrintRequest::CodeModels,
req => {
early_error(error_format, &format!("unknown print request `{}`", req))
}
}
- }).collect::<Vec<_>>();
+ }));
if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
early_warn(error_format, "-C remark will not show source locations without \
use rustc_resolve as resolve;
use rustc_save_analysis as save;
use rustc_trans::back::link;
+use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config, Session, build_session, CompileResult};
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
}
}
}
+ PrintRequest::TargetCPUs => {
+ let tm = create_target_machine(sess);
+ unsafe { llvm::LLVMRustPrintTargetCPUs(tm); }
+ }
+ PrintRequest::TargetFeatures => {
+ let tm = create_target_machine(sess);
+ unsafe { llvm::LLVMRustPrintTargetFeatures(tm); }
+ }
+ PrintRequest::RelocationModels => {
+ println!("Available relocation models:");
+ for &(name, _) in RELOC_MODEL_ARGS.iter() {
+ println!(" {}", name);
+ }
+ println!("");
+ }
+ PrintRequest::CodeModels => {
+ println!("Available code models:");
+ for &(name, _) in CODE_GEN_MODEL_ARGS.iter(){
+ println!(" {}", name);
+ }
+ println!("");
+ }
}
}
return Compilation::Stop;
cfg.flag(&flag);
}
+ if env::var_os("LLVM_RUSTLLVM").is_some() {
+ cfg.flag("-DLLVM_RUSTLLVM");
+ }
+
cfg.file("../rustllvm/PassWrapper.cpp")
.file("../rustllvm/RustWrapper.cpp")
.file("../rustllvm/ArchiveWrapper.cpp")
pub fn LLVMRustHasFeature(T: TargetMachineRef,
s: *const c_char) -> bool;
+ pub fn LLVMRustPrintTargetCPUs(T: TargetMachineRef);
+ pub fn LLVMRustPrintTargetFeatures(T: TargetMachineRef);
+
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
CPU: *const c_char,
Features: *const c_char,
use std::thread;
use libc::{c_uint, c_void};
+pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 4] = [
+ ("pic", llvm::RelocMode::PIC),
+ ("static", llvm::RelocMode::Static),
+ ("default", llvm::RelocMode::Default),
+ ("dynamic-no-pic", llvm::RelocMode::DynamicNoPic),
+];
+
+pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [
+ ("default", llvm::CodeModel::Default),
+ ("small", llvm::CodeModel::Small),
+ ("kernel", llvm::CodeModel::Kernel),
+ ("medium", llvm::CodeModel::Medium),
+ ("large", llvm::CodeModel::Large),
+];
+
pub fn llvm_err(handler: &errors::Handler, msg: String) -> ! {
match llvm::last_error() {
Some(err) => panic!(handler.fatal(&format!("{}: {}", msg, err))),
None => &sess.target.target.options.code_model[..],
};
- let code_model = match code_model_arg {
- "default" => llvm::CodeModel::Default,
- "small" => llvm::CodeModel::Small,
- "kernel" => llvm::CodeModel::Kernel,
- "medium" => llvm::CodeModel::Medium,
- "large" => llvm::CodeModel::Large,
+ let code_model = match CODE_GEN_MODEL_ARGS.iter().find(
+ |&&arg| arg.0 == code_model_arg) {
+ Some(x) => x.1,
_ => {
sess.err(&format!("{:?} is not a valid code model",
sess.opts
None => &sess.target.target.options.relocation_model[..],
};
- match reloc_model_arg {
- "pic" => llvm::RelocMode::PIC,
- "static" => llvm::RelocMode::Static,
- "default" => llvm::RelocMode::Default,
- "dynamic-no-pic" => llvm::RelocMode::DynamicNoPic,
+ match ::back::write::RELOC_MODEL_ARGS.iter().find(
+ |&&arg| arg.0 == reloc_model_arg) {
+ Some(x) => x.1,
_ => {
sess.err(&format!("{:?} is not a valid relocation mode",
sess.opts
.cg
- .relocation_model));
+ .code_model));
sess.abort_if_errors();
bug!();
}
-Subproject commit d1cc48989b13780f21c408fef17dceb104a09c9d
+Subproject commit d295833b773313dbef26041f481fc91a2954fbb9
}
}
+#if LLVM_RUSTLLVM
+/// getLongestEntryLength - Return the length of the longest entry in the table.
+///
+static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
+ size_t MaxLen = 0;
+ for (auto &I : Table)
+ MaxLen = std::max(MaxLen, std::strlen(I.Key));
+ return MaxLen;
+}
+
+extern "C" void
+LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
+ const TargetMachine *Target = unwrap(TM);
+ const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
+ const ArrayRef<SubtargetFeatureKV> CPUTable = MCInfo->getCPUTable();
+ unsigned MaxCPULen = getLongestEntryLength(CPUTable);
+
+ printf("Available CPUs for this target:\n");
+ for (auto &CPU : CPUTable)
+ printf(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
+ printf("\n");
+}
+
+extern "C" void
+LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
+ const TargetMachine *Target = unwrap(TM);
+ const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
+ const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
+ unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
+
+ printf("Available features for this target:\n");
+ for (auto &Feature : FeatTable)
+ printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
+ printf("\n");
+
+ printf("Use +feature to enable a feature, or -feature to disable it.\n"
+ "For example, rustc -C -target-cpu=mycpu -C target-feature=+feature1,-feature2\n\n");
+}
+
+#else
+
+extern "C" void
+LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
+ printf("Target CPU help is not supported by this LLVM version.\n\n");
+}
+
+extern "C" void
+LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
+ printf("Target features help is not supported by this LLVM version.\n\n");
+}
+#endif
+
extern "C" LLVMTargetMachineRef
LLVMRustCreateTargetMachine(const char *triple,
const char *cpu,