From d3096c2348b463ccdbb1c066b688d487e72e6c73 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 5 Jul 2014 13:24:57 -0700 Subject: [PATCH] Move llvm bindings to their own crate --- .gitignore | 2 +- mk/crates.mk | 7 +- mk/llvm.mk | 2 +- mk/target.mk | 2 +- src/librustc/lib.rs | 4 +- src/librustc/lib/llvmdeps.rs | 64 +++++++++++++ src/librustc/middle/trans/context.rs | 4 +- src/librustc/middle/trans/type_.rs | 54 ++++++++++- .../lib/llvm.rs => librustc_llvm/lib.rs} | 89 +++++++++++++++++-- 9 files changed, 209 insertions(+), 19 deletions(-) create mode 100644 src/librustc/lib/llvmdeps.rs rename src/{librustc/lib/llvm.rs => librustc_llvm/lib.rs} (96%) diff --git a/.gitignore b/.gitignore index 896480ba257..bc34fc2dcdf 100644 --- a/.gitignore +++ b/.gitignore @@ -86,5 +86,5 @@ src/etc/dl .settings/ /build i686-pc-mingw32/ -src/librustc/lib/llvmdeps.rs +src/librustc_llvm/llvmdeps.rs *.pot diff --git a/mk/crates.mk b/mk/crates.mk index 48a5bf6caf4..e565d3eb2b9 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -53,7 +53,7 @@ TARGET_CRATES := libc std green rustuv native flate arena glob term semver \ uuid serialize sync getopts collections num test time rand \ url log regex graphviz core rlibc alloc debug rustrt \ unicode -HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros +HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros rustc_llvm CRATES := $(TARGET_CRATES) $(HOST_CRATES) TOOLS := compiletest rustdoc rustc @@ -70,8 +70,9 @@ DEPS_green := std native:context_switch DEPS_rustuv := std native:uv native:uv_support DEPS_native := std DEPS_syntax := std term serialize log fmt_macros debug -DEPS_rustc := syntax native:rustllvm flate arena serialize getopts \ - time log graphviz debug +DEPS_rustc := syntax flate arena serialize getopts \ + time log graphviz debug rustc_llvm +DEPS_rustc_llvm := native:rustllvm libc std DEPS_rustdoc := rustc native:hoedown serialize getopts \ test time debug DEPS_flate := std native:miniz diff --git a/mk/llvm.mk b/mk/llvm.mk index 789ce2dabc2..177e4de3103 100644 --- a/mk/llvm.mk +++ b/mk/llvm.mk @@ -57,7 +57,7 @@ $(foreach host,$(CFG_HOST), \ $(foreach host,$(CFG_HOST), \ $(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host)))) -$(S)src/librustc/lib/llvmdeps.rs: \ +$(S)src/librustc_llvm/llvmdeps.rs: \ $(LLVM_CONFIGS) \ $(S)src/etc/mklldeps.py \ $(MKFILE_DEPS) diff --git a/mk/target.mk b/mk/target.mk index e6fb22e8c42..7da11a21a7c 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -134,7 +134,7 @@ SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD))/rustc$(X_$(CFG_BUILD)) define TARGET_HOST_RULES -$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc: $(S)src/librustc/lib/llvmdeps.rs +$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $(S)src/librustc_llvm/llvmdeps.rs $$(TBIN$(1)_T_$(2)_H_$(3))/: mkdir -p $$@ diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 63fba0fd4b4..7da3ae02087 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -41,6 +41,7 @@ extern crate flate; extern crate getopts; extern crate graphviz; extern crate libc; +extern crate llvm = "rustc_llvm"; extern crate serialize; extern crate time; #[phase(plugin, link)] extern crate log; @@ -128,8 +129,7 @@ pub mod util { } pub mod lib { - pub mod llvm; - pub mod llvmdeps; + pub use llvm; } __build_diagnostic_array!(DIAGNOSTICS) diff --git a/src/librustc/lib/llvmdeps.rs b/src/librustc/lib/llvmdeps.rs new file mode 100644 index 00000000000..05e5e585a63 --- /dev/null +++ b/src/librustc/lib/llvmdeps.rs @@ -0,0 +1,64 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// WARNING: THIS IS A GENERATED FILE, DO NOT MODIFY +// take a look at src/etc/mklldeps.py if you're interested + +#[cfg(target_arch = "x86_64", target_os = "linux")] +#[link(name = "LLVMInstrumentation", kind = "static")] +#[link(name = "LLVMInterpreter", kind = "static")] +#[link(name = "LLVMMCJIT", kind = "static")] +#[link(name = "LLVMRuntimeDyld", kind = "static")] +#[link(name = "LLVMJIT", kind = "static")] +#[link(name = "LLVMExecutionEngine", kind = "static")] +#[link(name = "LLVMAsmParser", kind = "static")] +#[link(name = "LLVMLinker", kind = "static")] +#[link(name = "LLVMBitWriter", kind = "static")] +#[link(name = "LLVMipo", kind = "static")] +#[link(name = "LLVMVectorize", kind = "static")] +#[link(name = "LLVMMipsDisassembler", kind = "static")] +#[link(name = "LLVMMipsCodeGen", kind = "static")] +#[link(name = "LLVMMipsAsmParser", kind = "static")] +#[link(name = "LLVMMipsDesc", kind = "static")] +#[link(name = "LLVMMipsInfo", kind = "static")] +#[link(name = "LLVMMipsAsmPrinter", kind = "static")] +#[link(name = "LLVMARMDisassembler", kind = "static")] +#[link(name = "LLVMARMCodeGen", kind = "static")] +#[link(name = "LLVMARMAsmParser", kind = "static")] +#[link(name = "LLVMARMDesc", kind = "static")] +#[link(name = "LLVMARMInfo", kind = "static")] +#[link(name = "LLVMARMAsmPrinter", kind = "static")] +#[link(name = "LLVMX86Disassembler", kind = "static")] +#[link(name = "LLVMX86AsmParser", kind = "static")] +#[link(name = "LLVMX86CodeGen", kind = "static")] +#[link(name = "LLVMSelectionDAG", kind = "static")] +#[link(name = "LLVMAsmPrinter", kind = "static")] +#[link(name = "LLVMMCParser", kind = "static")] +#[link(name = "LLVMCodeGen", kind = "static")] +#[link(name = "LLVMScalarOpts", kind = "static")] +#[link(name = "LLVMInstCombine", kind = "static")] +#[link(name = "LLVMTransformUtils", kind = "static")] +#[link(name = "LLVMipa", kind = "static")] +#[link(name = "LLVMAnalysis", kind = "static")] +#[link(name = "LLVMTarget", kind = "static")] +#[link(name = "LLVMX86Desc", kind = "static")] +#[link(name = "LLVMX86Info", kind = "static")] +#[link(name = "LLVMX86AsmPrinter", kind = "static")] +#[link(name = "LLVMMC", kind = "static")] +#[link(name = "LLVMObject", kind = "static")] +#[link(name = "LLVMBitReader", kind = "static")] +#[link(name = "LLVMCore", kind = "static")] +#[link(name = "LLVMX86Utils", kind = "static")] +#[link(name = "LLVMSupport", kind = "static")] +#[link(name = "pthread")] +#[link(name = "dl")] +#[link(name = "m")] +#[link(name = "stdc++")] +extern {} diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 6387ec791ba..5ee69e02af9 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -11,7 +11,7 @@ use driver::config::NoDebugInfo; use driver::session::Session; use lib::llvm::{ContextRef, ModuleRef, ValueRef}; -use lib::llvm::{llvm, TargetData, TypeNames}; +use lib::llvm::{llvm, TargetData}; use lib::llvm::mk_target_data; use metadata::common::LinkMeta; use middle::resolve; @@ -21,7 +21,7 @@ use middle::trans::builder::Builder; use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res}; use middle::trans::debuginfo; use middle::trans::monomorphize::MonoId; -use middle::trans::type_::Type; +use middle::trans::type_::{Type, TypeNames}; use middle::ty; use util::sha2::Sha256; use util::nodemap::{NodeMap, NodeSet, DefIdMap}; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index b10f6eda880..54de3996811 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -10,7 +10,7 @@ #![allow(non_uppercase_pattern_statics)] -use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; +use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind, ValueRef}; use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use middle::trans::context::CrateContext; @@ -20,8 +20,11 @@ use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel}; use std::c_str::ToCStr; use std::mem; +use std::cell::RefCell; +use std::collections::HashMap; +use std::str::raw::from_c_str; -use libc::{c_uint}; +use libc::{c_uint, c_void, free}; #[deriving(Clone, PartialEq, Show)] pub struct Type { @@ -303,3 +306,50 @@ impl Type { } } } + +/* Memory-managed object interface to type handles. */ + +pub struct TypeNames { + named_types: RefCell>, +} + +impl TypeNames { + pub fn new() -> TypeNames { + TypeNames { + named_types: RefCell::new(HashMap::new()) + } + } + + pub fn associate_type(&self, s: &str, t: &Type) { + assert!(self.named_types.borrow_mut().insert(s.to_string(), + t.to_ref())); + } + + pub fn find_type(&self, s: &str) -> Option { + self.named_types.borrow().find_equiv(&s).map(|x| Type::from_ref(*x)) + } + + pub fn type_to_str(&self, ty: Type) -> String { + unsafe { + let s = llvm::LLVMTypeToString(ty.to_ref()); + let ret = from_c_str(s); + free(s as *mut c_void); + ret.to_string() + } + } + + pub fn types_to_str(&self, tys: &[Type]) -> String { + let strs: Vec = tys.iter().map(|t| self.type_to_str(*t)).collect(); + format!("[{}]", strs.connect(",")) + } + + pub fn val_to_str(&self, val: ValueRef) -> String { + unsafe { + let s = llvm::LLVMValueToString(val); + let ret = from_c_str(s); + free(s as *mut c_void); + ret.to_string() + } + } +} + diff --git a/src/librustc/lib/llvm.rs b/src/librustc_llvm/lib.rs similarity index 96% rename from src/librustc/lib/llvm.rs rename to src/librustc_llvm/lib.rs index a4425183cde..121e8882f1a 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc_llvm/lib.rs @@ -13,13 +13,24 @@ #![allow(non_snake_case_functions)] #![allow(dead_code)] -use std::c_str::ToCStr; -use std::cell::RefCell; -use std::collections::HashMap; -use libc::{c_uint, c_ushort, c_void, free, uint64_t}; -use std::str::raw::from_c_str; +#![crate_id = "rustc_llvm#0.11.0"] +#![crate_name = "rustc_llvm"] +#![experimental] +#![license = "MIT/ASL2"] +#![crate_type = "dylib"] +#![crate_type = "rlib"] +#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://doc.rust-lang.org/")] -use middle::trans::type_::Type; +#![feature(globs)] +#![feature(link_args)] +#![allow(unused_attribute)] // NOTE: remove after stage0 + +extern crate libc; + +use std::c_str::ToCStr; +use libc::{c_uint, c_ushort, uint64_t, c_int, size_t}; pub type Opcode = u32; pub type Bool = c_uint; @@ -338,6 +349,10 @@ pub mod llvm { use libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong, size_t, uint64_t}; + pub unsafe fn LLVMInitializeX86AsmPrinter() { + LLVMInitializeX86AsmPrinter_() + } + // Link to our native llvm bindings (things that we need to use the C++ api // for) and because llvm is written in C++ we need to link against libstdc++ // @@ -1747,7 +1762,8 @@ pub mod llvm { pub fn LLVMInitializeX86TargetInfo(); pub fn LLVMInitializeX86Target(); pub fn LLVMInitializeX86TargetMC(); - pub fn LLVMInitializeX86AsmPrinter(); + #[link_name = "LLVMInitializeX86AsmPrinter"] + pub fn LLVMInitializeX86AsmPrinter_(); pub fn LLVMInitializeX86AsmParser(); pub fn LLVMInitializeARMTargetInfo(); pub fn LLVMInitializeARMTarget(); @@ -1861,6 +1877,7 @@ pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) { llvm::LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t) } } + /* Memory-managed object interface to type handles. */ pub struct TypeNames { @@ -1981,3 +1998,61 @@ pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter { } } } + +// FIXME #15460 - create a public function that actually calls our +// static LLVM symbols. Otherwise the linker will just throw llvm +// away. We're just calling lots of stuff until we transitively get +// all of LLVM. This is worse than anything. +pub unsafe fn static_link_hack_this_sucks() { + llvm::LLVMInitializePasses(); + + llvm::LLVMInitializeX86TargetInfo(); + llvm::LLVMInitializeX86Target(); + llvm::LLVMInitializeX86TargetMC(); + llvm::LLVMInitializeX86AsmPrinter(); + llvm::LLVMInitializeX86AsmParser(); + + llvm::LLVMInitializeARMTargetInfo(); + llvm::LLVMInitializeARMTarget(); + llvm::LLVMInitializeARMTargetMC(); + llvm::LLVMInitializeARMAsmPrinter(); + llvm::LLVMInitializeARMAsmParser(); + + llvm::LLVMInitializeMipsTargetInfo(); + llvm::LLVMInitializeMipsTarget(); + llvm::LLVMInitializeMipsTargetMC(); + llvm::LLVMInitializeMipsAsmPrinter(); + llvm::LLVMInitializeMipsAsmParser(); + + llvm::LLVMRustSetLLVMOptions(0 as c_int, + 0 as *const _); + + llvm::LLVMPassManagerBuilderPopulateModulePassManager(0 as *mut _, 0 as *mut _); + llvm::LLVMPassManagerBuilderPopulateLTOPassManager(0 as *mut _, 0 as *mut _, False, False); + llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(0 as *mut _, 0 as *mut _); + llvm::LLVMPassManagerBuilderSetOptLevel(0 as *mut _, 0 as c_uint); + llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(0 as *mut _, 0 as c_uint); + llvm::LLVMWriteBitcodeToFile(0 as *mut _, 0 as *const _); + llvm::LLVMPassManagerBuilderCreate(); + llvm::LLVMPassManagerBuilderDispose(0 as *mut _); + + llvm::LLVMRustLinkInExternalBitcode(0 as *mut _, 0 as *const _, 0 as size_t); + + LLVMLinkInJIT(); + LLVMLinkInMCJIT(); + LLVMLinkInInterpreter(); + + extern { + fn LLVMLinkInJIT(); + fn LLVMLinkInMCJIT(); + fn LLVMLinkInInterpreter(); + } +} + +// The module containing the native LLVM dependencies, generated by the build system +// Note that this must come after the rustllvm extern declaration so that +// parts of LLVM that rustllvm depends on aren't thrown away by the linker. +// Works to the above fix for #15460 to ensure LLVM dependencies that +// are only used by rustllvm don't get stripped by the linker. +mod llvmdeps; +