提交 249d5aca 编写于 作者: I Irina Popa

rustc_codegen_llvm: use safe references for Context and Module.

上级 af04e942
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
use llvm::{self, False, True}; use llvm::{self, False, True};
pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) { pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) {
let llcx = mods.llcx; let llcx = &*mods.llcx;
let llmod = mods.llmod; let llmod = mods.llmod();
let usize = match &tcx.sess.target.target.target_pointer_width[..] { let usize = match &tcx.sess.target.target.target_pointer_width[..] {
"16" => llvm::LLVMInt16TypeInContext(llcx), "16" => llvm::LLVMInt16TypeInContext(llcx),
"32" => llvm::LLVMInt32TypeInContext(llcx), "32" => llvm::LLVMInt32TypeInContext(llcx),
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
use back::write; use back::write;
use errors::{FatalError, Handler}; use errors::{FatalError, Handler};
use llvm::archive_ro::ArchiveRO; use llvm::archive_ro::ArchiveRO;
use llvm::{ModuleRef, TargetMachineRef, True, False}; use llvm::{TargetMachineRef, True, False};
use llvm; use llvm;
use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::def_id::LOCAL_CRATE;
use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::middle::exported_symbols::SymbolExportLevel;
...@@ -73,11 +73,13 @@ pub(crate) unsafe fn optimize(&mut self, ...@@ -73,11 +73,13 @@ pub(crate) unsafe fn optimize(&mut self,
match *self { match *self {
LtoModuleCodegen::Fat { ref mut module, .. } => { LtoModuleCodegen::Fat { ref mut module, .. } => {
let module = module.take().unwrap(); let module = module.take().unwrap();
{
let config = cgcx.config(module.kind); let config = cgcx.config(module.kind);
let llmod = module.llvm().unwrap().llmod; let llmod = module.llvm().unwrap().llmod();
let tm = module.llvm().unwrap().tm; let tm = &*module.llvm().unwrap().tm;
run_pass_manager(cgcx, tm, llmod, config, false); run_pass_manager(cgcx, tm, llmod, config, false);
timeline.record("fat-done"); timeline.record("fat-done");
}
Ok(module) Ok(module)
} }
LtoModuleCodegen::Thin(ref mut thin) => thin.optimize(cgcx, timeline), LtoModuleCodegen::Thin(ref mut thin) => thin.optimize(cgcx, timeline),
...@@ -223,14 +225,16 @@ fn fat_lto(cgcx: &CodegenContext, ...@@ -223,14 +225,16 @@ fn fat_lto(cgcx: &CodegenContext,
.filter(|&(_, module)| module.kind == ModuleKind::Regular) .filter(|&(_, module)| module.kind == ModuleKind::Regular)
.map(|(i, module)| { .map(|(i, module)| {
let cost = unsafe { let cost = unsafe {
llvm::LLVMRustModuleCost(module.llvm().unwrap().llmod) llvm::LLVMRustModuleCost(module.llvm().unwrap().llmod())
}; };
(cost, i) (cost, i)
}) })
.max() .max()
.expect("must be codegen'ing at least one module"); .expect("must be codegen'ing at least one module");
let module = modules.remove(costliest_module); let module = modules.remove(costliest_module);
let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod; let mut serialized_bitcode = Vec::new();
{
let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod();
info!("using {:?} as a base module", module.llmod_id); info!("using {:?} as a base module", module.llmod_id);
// For all other modules we codegened we'll need to link them into our own // For all other modules we codegened we'll need to link them into our own
...@@ -240,7 +244,7 @@ fn fat_lto(cgcx: &CodegenContext, ...@@ -240,7 +244,7 @@ fn fat_lto(cgcx: &CodegenContext,
// them later. Not great but hey, that's why it's "fat" LTO, right? // them later. Not great but hey, that's why it's "fat" LTO, right?
for module in modules { for module in modules {
let llvm = module.llvm().expect("can't lto pre-codegened modules"); let llvm = module.llvm().expect("can't lto pre-codegened modules");
let buffer = ModuleBuffer::new(llvm.llmod); let buffer = ModuleBuffer::new(llvm.llmod());
let llmod_id = CString::new(&module.llmod_id[..]).unwrap(); let llmod_id = CString::new(&module.llmod_id[..]).unwrap();
serialized_modules.push((SerializedModule::Local(buffer), llmod_id)); serialized_modules.push((SerializedModule::Local(buffer), llmod_id));
} }
...@@ -249,7 +253,6 @@ fn fat_lto(cgcx: &CodegenContext, ...@@ -249,7 +253,6 @@ fn fat_lto(cgcx: &CodegenContext,
// above, this is all mostly handled in C++. Like above, though, we don't // above, this is all mostly handled in C++. Like above, though, we don't
// know much about the memory management here so we err on the side of being // know much about the memory management here so we err on the side of being
// save and persist everything with the original module. // save and persist everything with the original module.
let mut serialized_bitcode = Vec::new();
let mut linker = Linker::new(llmod); let mut linker = Linker::new(llmod);
for (bc_decoded, name) in serialized_modules { for (bc_decoded, name) in serialized_modules {
info!("linking {:?}", name); info!("linking {:?}", name);
...@@ -283,6 +286,7 @@ fn fat_lto(cgcx: &CodegenContext, ...@@ -283,6 +286,7 @@ fn fat_lto(cgcx: &CodegenContext,
cgcx.save_temp_bitcode(&module, "lto.after-nounwind"); cgcx.save_temp_bitcode(&module, "lto.after-nounwind");
} }
timeline.record("passes"); timeline.record("passes");
}
Ok(vec![LtoModuleCodegen::Fat { Ok(vec![LtoModuleCodegen::Fat {
module: Some(module), module: Some(module),
...@@ -293,7 +297,7 @@ fn fat_lto(cgcx: &CodegenContext, ...@@ -293,7 +297,7 @@ fn fat_lto(cgcx: &CodegenContext,
struct Linker(llvm::LinkerRef); struct Linker(llvm::LinkerRef);
impl Linker { impl Linker {
fn new(llmod: ModuleRef) -> Linker { fn new(llmod: &llvm::Module) -> Linker {
unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) } unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) }
} }
...@@ -371,7 +375,7 @@ fn thin_lto(diag_handler: &Handler, ...@@ -371,7 +375,7 @@ fn thin_lto(diag_handler: &Handler,
info!("local module: {} - {}", i, module.llmod_id); info!("local module: {} - {}", i, module.llmod_id);
let llvm = module.llvm().expect("can't lto precodegened module"); let llvm = module.llvm().expect("can't lto precodegened module");
let name = CString::new(module.llmod_id.clone()).unwrap(); let name = CString::new(module.llmod_id.clone()).unwrap();
let buffer = ThinBuffer::new(llvm.llmod); let buffer = ThinBuffer::new(llvm.llmod());
thin_modules.push(llvm::ThinLTOModule { thin_modules.push(llvm::ThinLTOModule {
identifier: name.as_ptr(), identifier: name.as_ptr(),
data: buffer.data().as_ptr(), data: buffer.data().as_ptr(),
...@@ -449,7 +453,7 @@ fn thin_lto(diag_handler: &Handler, ...@@ -449,7 +453,7 @@ fn thin_lto(diag_handler: &Handler,
fn run_pass_manager(cgcx: &CodegenContext, fn run_pass_manager(cgcx: &CodegenContext,
tm: TargetMachineRef, tm: TargetMachineRef,
llmod: ModuleRef, llmod: &llvm::Module,
config: &ModuleConfig, config: &ModuleConfig,
thin: bool) { thin: bool) {
// Now we have one massive module inside of llmod. Time to run the // Now we have one massive module inside of llmod. Time to run the
...@@ -531,7 +535,7 @@ unsafe impl Send for ModuleBuffer {} ...@@ -531,7 +535,7 @@ unsafe impl Send for ModuleBuffer {}
unsafe impl Sync for ModuleBuffer {} unsafe impl Sync for ModuleBuffer {}
impl ModuleBuffer { impl ModuleBuffer {
pub fn new(m: ModuleRef) -> ModuleBuffer { pub fn new(m: &llvm::Module) -> ModuleBuffer {
ModuleBuffer(unsafe { ModuleBuffer(unsafe {
llvm::LLVMRustModuleBufferCreate(m) llvm::LLVMRustModuleBufferCreate(m)
}) })
...@@ -583,7 +587,7 @@ unsafe impl Send for ThinBuffer {} ...@@ -583,7 +587,7 @@ unsafe impl Send for ThinBuffer {}
unsafe impl Sync for ThinBuffer {} unsafe impl Sync for ThinBuffer {}
impl ThinBuffer { impl ThinBuffer {
pub fn new(m: ModuleRef) -> ThinBuffer { pub fn new(m: &llvm::Module) -> ThinBuffer {
unsafe { unsafe {
let buffer = llvm::LLVMRustThinLTOBufferCreate(m); let buffer = llvm::LLVMRustThinLTOBufferCreate(m);
ThinBuffer(buffer) ThinBuffer(buffer)
...@@ -640,19 +644,18 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline) ...@@ -640,19 +644,18 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
// crates but for locally codegened modules we may be able to reuse // crates but for locally codegened modules we may be able to reuse
// that LLVM Context and Module. // that LLVM Context and Module.
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
let llmod = llvm::LLVMRustParseBitcodeForThinLTO( let llmod_raw = llvm::LLVMRustParseBitcodeForThinLTO(
llcx, llcx,
self.data().as_ptr(), self.data().as_ptr(),
self.data().len(), self.data().len(),
self.shared.module_names[self.idx].as_ptr(), self.shared.module_names[self.idx].as_ptr(),
); ).ok_or_else(|| {
if llmod.is_null() {
let msg = "failed to parse bitcode for thin LTO module".to_string(); let msg = "failed to parse bitcode for thin LTO module".to_string();
return Err(write::llvm_err(&diag_handler, msg)); write::llvm_err(&diag_handler, msg)
} })? as *const _;
let module = ModuleCodegen { let module = ModuleCodegen {
source: ModuleSource::Codegened(ModuleLlvm { source: ModuleSource::Codegened(ModuleLlvm {
llmod, llmod_raw,
llcx, llcx,
tm, tm,
}), }),
...@@ -660,6 +663,8 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline) ...@@ -660,6 +663,8 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
name: self.name().to_string(), name: self.name().to_string(),
kind: ModuleKind::Regular, kind: ModuleKind::Regular,
}; };
{
let llmod = module.llvm().unwrap().llmod();
cgcx.save_temp_bitcode(&module, "thin-lto-input"); cgcx.save_temp_bitcode(&module, "thin-lto-input");
// Before we do much else find the "main" `DICompileUnit` that we'll be // Before we do much else find the "main" `DICompileUnit` that we'll be
...@@ -755,9 +760,10 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline) ...@@ -755,9 +760,10 @@ unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
// little differently. // little differently.
info!("running thin lto passes over {}", module.name); info!("running thin lto passes over {}", module.name);
let config = cgcx.config(module.kind); let config = cgcx.config(module.kind);
run_pass_manager(cgcx, tm, llmod, config, true); run_pass_manager(cgcx, module.llvm().unwrap().tm, llmod, config, true);
cgcx.save_temp_bitcode(&module, "thin-lto-after-pm"); cgcx.save_temp_bitcode(&module, "thin-lto-after-pm");
timeline.record("thin-done"); timeline.record("thin-done");
}
Ok(module) Ok(module)
} }
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use time_graph::{self, TimeGraph, Timeline}; use time_graph::{self, TimeGraph, Timeline};
use llvm; use llvm;
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef}; use llvm::{TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
use llvm::{SMDiagnosticRef, ContextRef}; use llvm::SMDiagnosticRef;
use {CodegenResults, ModuleSource, ModuleCodegen, CompiledModule, ModuleKind}; use {CodegenResults, ModuleSource, ModuleCodegen, CompiledModule, ModuleKind};
use CrateInfo; use CrateInfo;
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
...@@ -96,7 +96,7 @@ pub fn write_output_file( ...@@ -96,7 +96,7 @@ pub fn write_output_file(
handler: &errors::Handler, handler: &errors::Handler,
target: llvm::TargetMachineRef, target: llvm::TargetMachineRef,
pm: llvm::PassManagerRef, pm: llvm::PassManagerRef,
m: ModuleRef, m: &llvm::Module,
output: &Path, output: &Path,
file_type: llvm::FileType) -> Result<(), FatalError> { file_type: llvm::FileType) -> Result<(), FatalError> {
unsafe { unsafe {
...@@ -130,7 +130,7 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize { ...@@ -130,7 +130,7 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize {
} }
} }
pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachineRef { pub fn create_target_machine(sess: &Session, find_features: bool) -> &'static mut llvm::TargetMachine {
target_machine_factory(sess, find_features)().unwrap_or_else(|err| { target_machine_factory(sess, find_features)().unwrap_or_else(|err| {
llvm_err(sess.diagnostic(), err).raise() llvm_err(sess.diagnostic(), err).raise()
}) })
...@@ -140,7 +140,7 @@ pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachi ...@@ -140,7 +140,7 @@ pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachi
// that `is_pie_binary` is false. When we discover LLVM target features // that `is_pie_binary` is false. When we discover LLVM target features
// `sess.crate_types` is uninitialized so we cannot access it. // `sess.crate_types` is uninitialized so we cannot access it.
pub fn target_machine_factory(sess: &Session, find_features: bool) pub fn target_machine_factory(sess: &Session, find_features: bool)
-> Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync> -> Arc<dyn Fn() -> Result<&'static mut llvm::TargetMachine, String> + Send + Sync>
{ {
let reloc_model = get_reloc_model(sess); let reloc_model = get_reloc_model(sess);
...@@ -199,12 +199,10 @@ pub fn target_machine_factory(sess: &Session, find_features: bool) ...@@ -199,12 +199,10 @@ pub fn target_machine_factory(sess: &Session, find_features: bool)
) )
}; };
if tm.is_null() { tm.ok_or_else(|| {
Err(format!("Could not create LLVM TargetMachine for triple: {}", format!("Could not create LLVM TargetMachine for triple: {}",
triple.to_str().unwrap())) triple.to_str().unwrap())
} else { })
Ok(tm)
}
}) })
} }
...@@ -343,7 +341,7 @@ pub struct CodegenContext { ...@@ -343,7 +341,7 @@ pub struct CodegenContext {
regular_module_config: Arc<ModuleConfig>, regular_module_config: Arc<ModuleConfig>,
metadata_module_config: Arc<ModuleConfig>, metadata_module_config: Arc<ModuleConfig>,
allocator_module_config: Arc<ModuleConfig>, allocator_module_config: Arc<ModuleConfig>,
pub tm_factory: Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>, pub tm_factory: Arc<dyn Fn() -> Result<&'static mut llvm::TargetMachine, String> + Send + Sync>,
pub msvc_imps_needed: bool, pub msvc_imps_needed: bool,
pub target_pointer_width: String, pub target_pointer_width: String,
debuginfo: config::DebugInfoLevel, debuginfo: config::DebugInfoLevel,
...@@ -392,7 +390,7 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) { ...@@ -392,7 +390,7 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
let cgu = Some(&module.name[..]); let cgu = Some(&module.name[..]);
let path = self.output_filenames.temp_path_ext(&ext, cgu); let path = self.output_filenames.temp_path_ext(&ext, cgu);
let cstr = path2cstr(&path); let cstr = path2cstr(&path);
let llmod = module.llvm().unwrap().llmod; let llmod = module.llvm().unwrap().llmod();
llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr()); llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr());
} }
} }
...@@ -400,13 +398,13 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) { ...@@ -400,13 +398,13 @@ pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
struct DiagnosticHandlers<'a> { struct DiagnosticHandlers<'a> {
data: *mut (&'a CodegenContext, &'a Handler), data: *mut (&'a CodegenContext, &'a Handler),
llcx: ContextRef, llcx: &'a llvm::Context,
} }
impl<'a> DiagnosticHandlers<'a> { impl<'a> DiagnosticHandlers<'a> {
fn new(cgcx: &'a CodegenContext, fn new(cgcx: &'a CodegenContext,
handler: &'a Handler, handler: &'a Handler,
llcx: ContextRef) -> DiagnosticHandlers<'a> { llcx: &'a llvm::Context) -> Self {
let data = Box::into_raw(Box::new((cgcx, handler))); let data = Box::into_raw(Box::new((cgcx, handler)));
unsafe { unsafe {
llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data as *mut _); llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data as *mut _);
...@@ -495,7 +493,7 @@ unsafe fn optimize(cgcx: &CodegenContext, ...@@ -495,7 +493,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
-> Result<(), FatalError> -> Result<(), FatalError>
{ {
let (llmod, llcx, tm) = match module.source { let (llmod, llcx, tm) = match module.source {
ModuleSource::Codegened(ref llvm) => (llvm.llmod, llvm.llcx, llvm.tm), ModuleSource::Codegened(ref llvm) => (llvm.llmod(), &*llvm.llcx, &*llvm.tm),
ModuleSource::Preexisting(_) => { ModuleSource::Preexisting(_) => {
bug!("optimize_and_codegen: called with ModuleSource::Preexisting") bug!("optimize_and_codegen: called with ModuleSource::Preexisting")
} }
...@@ -617,8 +615,9 @@ unsafe fn codegen(cgcx: &CodegenContext, ...@@ -617,8 +615,9 @@ unsafe fn codegen(cgcx: &CodegenContext,
-> Result<CompiledModule, FatalError> -> Result<CompiledModule, FatalError>
{ {
timeline.record("codegen"); timeline.record("codegen");
{
let (llmod, llcx, tm) = match module.source { let (llmod, llcx, tm) = match module.source {
ModuleSource::Codegened(ref llvm) => (llvm.llmod, llvm.llcx, llvm.tm), ModuleSource::Codegened(ref llvm) => (llvm.llmod(), &*llvm.llcx, &*llvm.tm),
ModuleSource::Preexisting(_) => { ModuleSource::Preexisting(_) => {
bug!("codegen: called with ModuleSource::Preexisting") bug!("codegen: called with ModuleSource::Preexisting")
} }
...@@ -640,7 +639,7 @@ unsafe fn codegen(cgcx: &CodegenContext, ...@@ -640,7 +639,7 @@ unsafe fn codegen(cgcx: &CodegenContext,
// escape the closure itself, and the manager should only be // escape the closure itself, and the manager should only be
// used once. // used once.
unsafe fn with_codegen<F, R>(tm: TargetMachineRef, unsafe fn with_codegen<F, R>(tm: TargetMachineRef,
llmod: ModuleRef, llmod: &llvm::Module,
no_builtins: bool, no_builtins: bool,
f: F) -> R f: F) -> R
where F: FnOnce(PassManagerRef) -> R, where F: FnOnce(PassManagerRef) -> R,
...@@ -763,9 +762,6 @@ extern "C" fn demangle_callback(input_ptr: *const c_char, ...@@ -763,9 +762,6 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
write_output_file(diag_handler, tm, cpm, llmod, &path, write_output_file(diag_handler, tm, cpm, llmod, &path,
llvm::FileType::AssemblyFile) llvm::FileType::AssemblyFile)
})?; })?;
if config.emit_obj {
llvm::LLVMDisposeModule(llmod);
}
timeline.record("asm"); timeline.record("asm");
} }
...@@ -803,6 +799,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char, ...@@ -803,6 +799,7 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
} }
drop(handlers); drop(handlers);
}
Ok(module.into_compiled_module(config.emit_obj, Ok(module.into_compiled_module(config.emit_obj,
config.emit_bc, config.emit_bc,
config.emit_bc_compressed, config.emit_bc_compressed,
...@@ -828,8 +825,8 @@ extern "C" fn demangle_callback(input_ptr: *const c_char, ...@@ -828,8 +825,8 @@ extern "C" fn demangle_callback(input_ptr: *const c_char,
/// Basically all of this is us attempting to follow in the footsteps of clang /// Basically all of this is us attempting to follow in the footsteps of clang
/// on iOS. See #35968 for lots more info. /// on iOS. See #35968 for lots more info.
unsafe fn embed_bitcode(cgcx: &CodegenContext, unsafe fn embed_bitcode(cgcx: &CodegenContext,
llcx: ContextRef, llcx: &llvm::Context,
llmod: ModuleRef, llmod: &llvm::Module,
bitcode: Option<&[u8]>) { bitcode: Option<&[u8]>) {
let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[])); let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
let llglobal = llvm::LLVMAddGlobal( let llglobal = llvm::LLVMAddGlobal(
...@@ -2050,7 +2047,7 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path, ...@@ -2050,7 +2047,7 @@ pub fn run_assembler(cgcx: &CodegenContext, handler: &Handler, assembly: &Path,
} }
} }
pub unsafe fn with_llvm_pmb(llmod: ModuleRef, pub unsafe fn with_llvm_pmb(llmod: &llvm::Module,
config: &ModuleConfig, config: &ModuleConfig,
opt_level: llvm::CodeGenOptLevel, opt_level: llvm::CodeGenOptLevel,
prepare_for_thin_lto: bool, prepare_for_thin_lto: bool,
...@@ -2353,7 +2350,7 @@ fn msvc_imps_needed(tcx: TyCtxt) -> bool { ...@@ -2353,7 +2350,7 @@ fn msvc_imps_needed(tcx: TyCtxt) -> bool {
// when using MSVC linker. We do this only for data, as linker can fix up // when using MSVC linker. We do this only for data, as linker can fix up
// code references on its own. // code references on its own.
// See #26591, #27438 // See #26591, #27438
fn create_msvc_imps(cgcx: &CodegenContext, llcx: ContextRef, llmod: ModuleRef) { fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module) {
if !cgcx.msvc_imps_needed { if !cgcx.msvc_imps_needed {
return return
} }
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
use abi; use abi;
use back::link; use back::link;
use back::write::{self, OngoingCodegen, create_target_machine}; use back::write::{self, OngoingCodegen};
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param}; use llvm::{ValueRef, Vector, get_param};
use llvm; use llvm;
use metadata; use metadata;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
use rustc_mir::monomorphize::item::DefPathBasedNames; use rustc_mir::monomorphize::item::DefPathBasedNames;
use common::{self, C_struct_in_context, C_array, val_ty}; use common::{self, C_struct_in_context, C_array, val_ty};
use consts; use consts;
use context::{self, CodegenCx}; use context::CodegenCx;
use debuginfo; use debuginfo;
use declare; use declare;
use meth; use meth;
...@@ -77,7 +77,6 @@ ...@@ -77,7 +77,6 @@
use std::any::Any; use std::any::Any;
use std::ffi::CString; use std::ffi::CString;
use std::str;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Instant, Duration}; use std::time::{Instant, Duration};
use std::i32; use std::i32;
...@@ -609,16 +608,14 @@ fn create_entry_fn<'cx>(cx: &'cx CodegenCx, ...@@ -609,16 +608,14 @@ fn create_entry_fn<'cx>(cx: &'cx CodegenCx,
} }
fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
llmod_id: &str, llvm_module: &ModuleLlvm,
link_meta: &LinkMeta) link_meta: &LinkMeta)
-> (ContextRef, ModuleRef, EncodedMetadata) { -> EncodedMetadata {
use std::io::Write; use std::io::Write;
use flate2::Compression; use flate2::Compression;
use flate2::write::DeflateEncoder; use flate2::write::DeflateEncoder;
let (metadata_llcx, metadata_llmod) = unsafe { let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());
context::create_context_and_module(tcx.sess, llmod_id)
};
#[derive(PartialEq, Eq, PartialOrd, Ord)] #[derive(PartialEq, Eq, PartialOrd, Ord)]
enum MetadataKind { enum MetadataKind {
...@@ -641,14 +638,12 @@ enum MetadataKind { ...@@ -641,14 +638,12 @@ enum MetadataKind {
}).max().unwrap_or(MetadataKind::None); }).max().unwrap_or(MetadataKind::None);
if kind == MetadataKind::None { if kind == MetadataKind::None {
return (metadata_llcx, return EncodedMetadata::new();
metadata_llmod,
EncodedMetadata::new());
} }
let metadata = tcx.encode_metadata(link_meta); let metadata = tcx.encode_metadata(link_meta);
if kind == MetadataKind::Uncompressed { if kind == MetadataKind::Uncompressed {
return (metadata_llcx, metadata_llmod, metadata); return metadata;
} }
assert!(kind == MetadataKind::Compressed); assert!(kind == MetadataKind::Compressed);
...@@ -676,7 +671,7 @@ enum MetadataKind { ...@@ -676,7 +671,7 @@ enum MetadataKind {
let directive = CString::new(directive).unwrap(); let directive = CString::new(directive).unwrap();
llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr()) llvm::LLVMSetModuleInlineAsm(metadata_llmod, directive.as_ptr())
} }
return (metadata_llcx, metadata_llmod, metadata); return metadata;
} }
pub struct ValueIter { pub struct ValueIter {
...@@ -698,7 +693,7 @@ fn next(&mut self) -> Option<ValueRef> { ...@@ -698,7 +693,7 @@ fn next(&mut self) -> Option<ValueRef> {
} }
} }
pub fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { pub fn iter_globals(llmod: &llvm::Module) -> ValueIter {
unsafe { unsafe {
ValueIter { ValueIter {
cur: llvm::LLVMGetFirstGlobal(llmod), cur: llvm::LLVMGetFirstGlobal(llmod),
...@@ -731,19 +726,15 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -731,19 +726,15 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Codegen the metadata. // Codegen the metadata.
let llmod_id = "metadata"; let llmod_id = "metadata";
let (metadata_llcx, metadata_llmod, metadata) = let metadata_llvm_module = ModuleLlvm::new(tcx.sess, llmod_id);
time(tcx.sess, "write metadata", || { let metadata = time(tcx.sess, "write metadata", || {
write_metadata(tcx, llmod_id, &link_meta) write_metadata(tcx, &metadata_llvm_module, &link_meta)
}); });
let metadata_module = ModuleCodegen { let metadata_module = ModuleCodegen {
name: link::METADATA_MODULE_NAME.to_string(), name: link::METADATA_MODULE_NAME.to_string(),
llmod_id: llmod_id.to_string(), llmod_id: llmod_id.to_string(),
source: ModuleSource::Codegened(ModuleLlvm { source: ModuleSource::Codegened(metadata_llvm_module),
llcx: metadata_llcx,
llmod: metadata_llmod,
tm: create_target_machine(tcx.sess, false),
}),
kind: ModuleKind::Metadata, kind: ModuleKind::Metadata,
}; };
...@@ -803,13 +794,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -803,13 +794,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() { let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() {
unsafe { unsafe {
let llmod_id = "allocator"; let llmod_id = "allocator";
let (llcx, llmod) = let modules = ModuleLlvm::new(tcx.sess, llmod_id);
context::create_context_and_module(tcx.sess, llmod_id);
let modules = ModuleLlvm {
llmod,
llcx,
tm: create_target_machine(tcx.sess, false),
};
time(tcx.sess, "write allocator module", || { time(tcx.sess, "write allocator module", || {
allocator::codegen(tcx, &modules, kind) allocator::codegen(tcx, &modules, kind)
}); });
...@@ -1200,8 +1185,9 @@ fn module_codegen<'a, 'tcx>( ...@@ -1200,8 +1185,9 @@ fn module_codegen<'a, 'tcx>(
.to_fingerprint().to_hex()); .to_fingerprint().to_hex());
// Instantiate monomorphizations without filling out definitions yet... // Instantiate monomorphizations without filling out definitions yet...
let cx = CodegenCx::new(tcx, cgu, &llmod_id); let llvm_module = ModuleLlvm::new(tcx.sess, &llmod_id);
let module = { let stats = {
let cx = CodegenCx::new(tcx, cgu, &llvm_module);
let mono_items = cx.codegen_unit let mono_items = cx.codegen_unit
.items_in_deterministic_order(cx.tcx); .items_in_deterministic_order(cx.tcx);
for &(mono_item, (linkage, visibility)) in &mono_items { for &(mono_item, (linkage, visibility)) in &mono_items {
...@@ -1248,21 +1234,15 @@ fn module_codegen<'a, 'tcx>( ...@@ -1248,21 +1234,15 @@ fn module_codegen<'a, 'tcx>(
debuginfo::finalize(&cx); debuginfo::finalize(&cx);
} }
let llvm_module = ModuleLlvm { cx.stats.into_inner()
llcx: cx.llcx,
llmod: cx.llmod,
tm: create_target_machine(cx.sess(), false),
}; };
ModuleCodegen { (stats, ModuleCodegen {
name: cgu_name, name: cgu_name,
source: ModuleSource::Codegened(llvm_module), source: ModuleSource::Codegened(llvm_module),
kind: ModuleKind::Regular, kind: ModuleKind::Regular,
llmod_id, llmod_id,
} })
};
(cx.into_stats(), module)
} }
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
//! Code that is useful in various codegen modules. //! Code that is useful in various codegen modules.
use llvm; use llvm;
use llvm::{ValueRef, ContextRef, TypeKind}; use llvm::{ValueRef, TypeKind};
use llvm::{True, False, Bool, OperandBundleDef}; use llvm::{True, False, Bool, OperandBundleDef};
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::middle::lang_items::LangItem; use rustc::middle::lang_items::LangItem;
...@@ -225,7 +225,7 @@ pub fn C_struct(cx: &CodegenCx, elts: &[ValueRef], packed: bool) -> ValueRef { ...@@ -225,7 +225,7 @@ pub fn C_struct(cx: &CodegenCx, elts: &[ValueRef], packed: bool) -> ValueRef {
C_struct_in_context(cx.llcx, elts, packed) C_struct_in_context(cx.llcx, elts, packed)
} }
pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef { pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool) -> ValueRef {
unsafe { unsafe {
llvm::LLVMConstStructInContext(llcx, llvm::LLVMConstStructInContext(llcx,
elts.as_ptr(), elts.len() as c_uint, elts.as_ptr(), elts.len() as c_uint,
...@@ -249,7 +249,7 @@ pub fn C_bytes(cx: &CodegenCx, bytes: &[u8]) -> ValueRef { ...@@ -249,7 +249,7 @@ pub fn C_bytes(cx: &CodegenCx, bytes: &[u8]) -> ValueRef {
C_bytes_in_context(cx.llcx, bytes) C_bytes_in_context(cx.llcx, bytes)
} }
pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef { pub fn C_bytes_in_context(llcx: &llvm::Context, bytes: &[u8]) -> ValueRef {
unsafe { unsafe {
let ptr = bytes.as_ptr() as *const c_char; let ptr = bytes.as_ptr() as *const c_char;
return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True); return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
use common; use common;
use llvm; use llvm;
use llvm::{ContextRef, ModuleRef, ValueRef}; use llvm::ValueRef;
use rustc::dep_graph::DepGraphSafe; use rustc::dep_graph::DepGraphSafe;
use rustc::hir; use rustc::hir;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
...@@ -42,16 +42,16 @@ ...@@ -42,16 +42,16 @@
use abi::Abi; use abi::Abi;
/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
/// `ContextRef` so that several compilation units may be optimized in parallel. /// `llvm::Context` so that several compilation units may be optimized in parallel.
/// All other LLVM data structures in the `CodegenCx` are tied to that `ContextRef`. /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
pub struct CodegenCx<'a, 'tcx: 'a> { pub struct CodegenCx<'a, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub check_overflow: bool, pub check_overflow: bool,
pub use_dll_storage_attrs: bool, pub use_dll_storage_attrs: bool,
pub tls_model: llvm::ThreadLocalMode, pub tls_model: llvm::ThreadLocalMode,
pub llmod: ModuleRef, pub llmod: &'a llvm::Module,
pub llcx: ContextRef, pub llcx: &'a llvm::Context,
pub stats: RefCell<Stats>, pub stats: RefCell<Stats>,
pub codegen_unit: Arc<CodegenUnit<'tcx>>, pub codegen_unit: Arc<CodegenUnit<'tcx>>,
...@@ -94,7 +94,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> { ...@@ -94,7 +94,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>, pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
pub isize_ty: Type, pub isize_ty: Type,
pub dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>, pub dbg_cx: Option<debuginfo::CrateDebugContext<'a, 'tcx>>,
eh_personality: Cell<Option<ValueRef>>, eh_personality: Cell<Option<ValueRef>>,
eh_unwind_resume: Cell<Option<ValueRef>>, eh_unwind_resume: Cell<Option<ValueRef>>,
...@@ -155,8 +155,7 @@ pub fn is_pie_binary(sess: &Session) -> bool { ...@@ -155,8 +155,7 @@ pub fn is_pie_binary(sess: &Session) -> bool {
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
} }
pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) { pub unsafe fn create_module(sess: &Session, llcx: &'ll llvm::Context, mod_name: &str) -> &'ll llvm::Module {
let llcx = llvm::LLVMRustContextCreate(sess.fewer_names());
let mod_name = CString::new(mod_name).unwrap(); let mod_name = CString::new(mod_name).unwrap();
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
...@@ -208,13 +207,13 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont ...@@ -208,13 +207,13 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont
llvm::LLVMRustSetModulePIELevel(llmod); llvm::LLVMRustSetModulePIELevel(llmod);
} }
(llcx, llmod) llmod
} }
impl<'a, 'tcx> CodegenCx<'a, 'tcx> { impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
codegen_unit: Arc<CodegenUnit<'tcx>>, codegen_unit: Arc<CodegenUnit<'tcx>>,
llmod_id: &str) llvm_module: &'a ::ModuleLlvm)
-> CodegenCx<'a, 'tcx> { -> CodegenCx<'a, 'tcx> {
// An interesting part of Windows which MSVC forces our hand on (and // An interesting part of Windows which MSVC forces our hand on (and
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport` // apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
...@@ -265,9 +264,7 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -265,9 +264,7 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let tls_model = get_tls_model(&tcx.sess); let tls_model = get_tls_model(&tcx.sess);
unsafe { let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());
let (llcx, llmod) = create_context_and_module(&tcx.sess,
&llmod_id[..]);
let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo {
let dctx = debuginfo::CrateDebugContext::new(llmod); let dctx = debuginfo::CrateDebugContext::new(llmod);
...@@ -310,11 +307,6 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -310,11 +307,6 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
local_gen_sym_counter: Cell::new(0), local_gen_sym_counter: Cell::new(0),
} }
} }
}
pub fn into_stats(self) -> Stats {
self.stats.into_inner()
}
} }
impl<'b, 'tcx> CodegenCx<'b, 'tcx> { impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
......
...@@ -862,7 +862,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt, ...@@ -862,7 +862,7 @@ pub fn compile_unit_metadata(tcx: TyCtxt,
return unit_metadata; return unit_metadata;
}; };
fn path_to_mdstring(llcx: llvm::ContextRef, path: &Path) -> llvm::ValueRef { fn path_to_mdstring(llcx: &llvm::Context, path: &Path) -> llvm::ValueRef {
let path_str = path2cstr(path); let path_str = path2cstr(path);
unsafe { unsafe {
llvm::LLVMMDStringInContext(llcx, llvm::LLVMMDStringInContext(llcx,
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use self::source_loc::InternalDebugLocation::{self, UnknownLocation};
use llvm; use llvm;
use llvm::{ModuleRef, ContextRef, ValueRef}; use llvm::ValueRef;
use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags}; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags};
use rustc::hir::CodegenFnAttrFlags; use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def_id::{DefId, CrateNum}; use rustc::hir::def_id::{DefId, CrateNum};
...@@ -67,9 +67,9 @@ ...@@ -67,9 +67,9 @@
const DW_TAG_arg_variable: c_uint = 0x101; const DW_TAG_arg_variable: c_uint = 0x101;
/// A context object for maintaining all state needed by the debuginfo module. /// A context object for maintaining all state needed by the debuginfo module.
pub struct CrateDebugContext<'tcx> { pub struct CrateDebugContext<'a, 'tcx> {
llcontext: ContextRef, llcontext: &'a llvm::Context,
llmod: ModuleRef, llmod: &'a llvm::Module,
builder: DIBuilderRef, builder: DIBuilderRef,
created_files: RefCell<FxHashMap<(Symbol, Symbol), DIFile>>, created_files: RefCell<FxHashMap<(Symbol, Symbol), DIFile>>,
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>, created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>,
...@@ -82,8 +82,8 @@ pub struct CrateDebugContext<'tcx> { ...@@ -82,8 +82,8 @@ pub struct CrateDebugContext<'tcx> {
composite_types_completed: RefCell<FxHashSet<DIType>>, composite_types_completed: RefCell<FxHashSet<DIType>>,
} }
impl<'tcx> CrateDebugContext<'tcx> { impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> {
pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> { pub fn new(llmod: &'a llvm::Module) -> Self {
debug!("CrateDebugContext::new"); debug!("CrateDebugContext::new");
let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
// DIBuilder inherits context from the module, so we'd better use the same one // DIBuilder inherits context from the module, so we'd better use the same one
......
...@@ -50,7 +50,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc { ...@@ -50,7 +50,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
#[inline] #[inline]
pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>) pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>)
-> &'a CrateDebugContext<'tcx> { -> &'a CrateDebugContext<'a, 'tcx> {
cx.dbg_cx.as_ref().unwrap() cx.dbg_cx.as_ref().unwrap()
} }
......
...@@ -20,9 +20,11 @@ ...@@ -20,9 +20,11 @@
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(crate_visibility_modifier)]
#![feature(custom_attribute)] #![feature(custom_attribute)]
#![feature(extern_types)] #![feature(extern_types)]
#![feature(fs_read_write)] #![feature(fs_read_write)]
#![feature(in_band_lifetimes)]
#![allow(unused_attributes)] #![allow(unused_attributes)]
#![feature(libc)] #![feature(libc)]
#![feature(quote)] #![feature(quote)]
...@@ -34,6 +36,7 @@ ...@@ -34,6 +36,7 @@
#![feature(link_args)] #![feature(link_args)]
#![feature(static_nobundle)] #![feature(static_nobundle)]
use back::write::create_target_machine;
use rustc::dep_graph::WorkProduct; use rustc::dep_graph::WorkProduct;
use syntax_pos::symbol::Symbol; use syntax_pos::symbol::Symbol;
...@@ -340,22 +343,41 @@ enum ModuleSource { ...@@ -340,22 +343,41 @@ enum ModuleSource {
Codegened(ModuleLlvm), Codegened(ModuleLlvm),
} }
#[derive(Debug)]
struct ModuleLlvm { struct ModuleLlvm {
llcx: llvm::ContextRef, llcx: &'static mut llvm::Context,
llmod: llvm::ModuleRef, llmod_raw: *const llvm::Module,
tm: llvm::TargetMachineRef, tm: &'static mut llvm::TargetMachine,
} }
unsafe impl Send for ModuleLlvm { } unsafe impl Send for ModuleLlvm { }
unsafe impl Sync for ModuleLlvm { } unsafe impl Sync for ModuleLlvm { }
impl ModuleLlvm {
fn new(sess: &Session, mod_name: &str) -> Self {
unsafe {
let llcx = llvm::LLVMRustContextCreate(sess.fewer_names());
let llmod_raw = context::create_module(sess, llcx, mod_name) as *const _;
ModuleLlvm {
llmod_raw,
llcx,
tm: create_target_machine(sess, false),
}
}
}
fn llmod(&self) -> &llvm::Module {
unsafe {
&*self.llmod_raw
}
}
}
impl Drop for ModuleLlvm { impl Drop for ModuleLlvm {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
llvm::LLVMDisposeModule(self.llmod); llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
llvm::LLVMContextDispose(self.llcx); llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _));
llvm::LLVMRustDisposeTargetMachine(self.tm);
} }
} }
} }
......
...@@ -127,7 +127,7 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) { ...@@ -127,7 +127,7 @@ pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
// value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
// function. // function.
// For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52 // For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) { pub fn SetUniqueComdat(llmod: &Module, val: ValueRef) {
unsafe { unsafe {
LLVMRustSetComdat(llmod, val, LLVMGetValueName(val)); LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
use llvm; use llvm;
use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind}; use llvm::{TypeRef, Bool, False, True, TypeKind};
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
use context::CodegenCx; use context::CodegenCx;
...@@ -77,7 +77,7 @@ pub fn i8(cx: &CodegenCx) -> Type { ...@@ -77,7 +77,7 @@ pub fn i8(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMInt8TypeInContext(cx.llcx)) ty!(llvm::LLVMInt8TypeInContext(cx.llcx))
} }
pub fn i8_llcx(llcx: ContextRef) -> Type { pub fn i8_llcx(llcx: &llvm::Context) -> Type {
ty!(llvm::LLVMInt8TypeInContext(llcx)) ty!(llvm::LLVMInt8TypeInContext(llcx))
} }
...@@ -103,7 +103,7 @@ pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type { ...@@ -103,7 +103,7 @@ pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type {
} }
// Creates an integer type with the given number of bits, e.g. i24 // Creates an integer type with the given number of bits, e.g. i24
pub fn ix_llcx(llcx: ContextRef, num_bits: u64) -> Type { pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> Type {
ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)) ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint))
} }
...@@ -127,7 +127,7 @@ pub fn i8p(cx: &CodegenCx) -> Type { ...@@ -127,7 +127,7 @@ pub fn i8p(cx: &CodegenCx) -> Type {
Type::i8(cx).ptr_to() Type::i8(cx).ptr_to()
} }
pub fn i8p_llcx(llcx: ContextRef) -> Type { pub fn i8p_llcx(llcx: &llvm::Context) -> Type {
Type::i8_llcx(llcx).ptr_to() Type::i8_llcx(llcx).ptr_to()
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册