rustc_codegen_llvm: use safe references for PassManager.
This commit is contained in:
parent
0ab3444540
commit
e22eebaf2b
|
@ -25,7 +25,7 @@ use rustc::session::config::{self, OutputFilenames, OutputType, Passes, SomePass
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use time_graph::{self, TimeGraph, Timeline};
|
use time_graph::{self, TimeGraph, Timeline};
|
||||||
use llvm::{self, DiagnosticInfo, PassManagerRef, SMDiagnostic};
|
use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
|
||||||
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};
|
||||||
|
@ -92,9 +92,9 @@ pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
|
||||||
|
|
||||||
pub fn write_output_file(
|
pub fn write_output_file(
|
||||||
handler: &errors::Handler,
|
handler: &errors::Handler,
|
||||||
target: &llvm::TargetMachine,
|
target: &'ll llvm::TargetMachine,
|
||||||
pm: llvm::PassManagerRef,
|
pm: &llvm::PassManager<'ll>,
|
||||||
m: &llvm::Module,
|
m: &'ll llvm::Module,
|
||||||
output: &Path,
|
output: &Path,
|
||||||
file_type: llvm::FileType) -> Result<(), FatalError> {
|
file_type: llvm::FileType) -> Result<(), FatalError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -516,50 +516,52 @@ unsafe fn optimize(cgcx: &CodegenContext,
|
||||||
let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod);
|
let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod);
|
||||||
let mpm = llvm::LLVMCreatePassManager();
|
let mpm = llvm::LLVMCreatePassManager();
|
||||||
|
|
||||||
// If we're verifying or linting, add them to the function pass
|
{
|
||||||
// manager.
|
// If we're verifying or linting, add them to the function pass
|
||||||
let addpass = |pass_name: &str| {
|
// manager.
|
||||||
let pass_name = CString::new(pass_name).unwrap();
|
let addpass = |pass_name: &str| {
|
||||||
let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) {
|
let pass_name = CString::new(pass_name).unwrap();
|
||||||
Some(pass) => pass,
|
let pass = match llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr()) {
|
||||||
None => return false,
|
Some(pass) => pass,
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
let pass_manager = match llvm::LLVMRustPassKind(pass) {
|
||||||
|
llvm::PassKind::Function => &*fpm,
|
||||||
|
llvm::PassKind::Module => &*mpm,
|
||||||
|
llvm::PassKind::Other => {
|
||||||
|
diag_handler.err("Encountered LLVM pass kind we can't handle");
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
};
|
||||||
|
llvm::LLVMRustAddPass(pass_manager, pass);
|
||||||
|
true
|
||||||
};
|
};
|
||||||
let pass_manager = match llvm::LLVMRustPassKind(pass) {
|
|
||||||
llvm::PassKind::Function => fpm,
|
|
||||||
llvm::PassKind::Module => mpm,
|
|
||||||
llvm::PassKind::Other => {
|
|
||||||
diag_handler.err("Encountered LLVM pass kind we can't handle");
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
};
|
|
||||||
llvm::LLVMRustAddPass(pass_manager, pass);
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
if config.verify_llvm_ir { assert!(addpass("verify")); }
|
if config.verify_llvm_ir { assert!(addpass("verify")); }
|
||||||
if !config.no_prepopulate_passes {
|
if !config.no_prepopulate_passes {
|
||||||
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
|
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
|
||||||
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
|
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
|
||||||
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
|
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
|
||||||
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal;
|
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal;
|
||||||
with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
|
with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
|
||||||
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
|
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
|
||||||
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
|
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
for pass in &config.passes {
|
|
||||||
if !addpass(pass) {
|
|
||||||
diag_handler.warn(&format!("unknown pass `{}`, ignoring",
|
|
||||||
pass));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for pass in &cgcx.plugin_passes {
|
for pass in &config.passes {
|
||||||
if !addpass(pass) {
|
if !addpass(pass) {
|
||||||
diag_handler.err(&format!("a plugin asked for LLVM pass \
|
diag_handler.warn(&format!("unknown pass `{}`, ignoring",
|
||||||
`{}` but LLVM does not \
|
pass));
|
||||||
recognize it", pass));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for pass in &cgcx.plugin_passes {
|
||||||
|
if !addpass(pass) {
|
||||||
|
diag_handler.err(&format!("a plugin asked for LLVM pass \
|
||||||
|
`{}` but LLVM does not \
|
||||||
|
recognize it", pass));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,11 +638,11 @@ unsafe fn codegen(cgcx: &CodegenContext,
|
||||||
// pass manager passed to the closure should be ensured to not
|
// pass manager passed to the closure should be ensured to not
|
||||||
// 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: &llvm::TargetMachine,
|
unsafe fn with_codegen<'ll, F, R>(tm: &'ll llvm::TargetMachine,
|
||||||
llmod: &llvm::Module,
|
llmod: &'ll llvm::Module,
|
||||||
no_builtins: bool,
|
no_builtins: bool,
|
||||||
f: F) -> R
|
f: F) -> R
|
||||||
where F: FnOnce(PassManagerRef) -> R,
|
where F: FnOnce(&'ll mut PassManager<'ll>) -> R,
|
||||||
{
|
{
|
||||||
let cpm = llvm::LLVMCreatePassManager();
|
let cpm = llvm::LLVMCreatePassManager();
|
||||||
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
|
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
|
||||||
|
|
|
@ -397,8 +397,7 @@ extern { pub type Metadata; }
|
||||||
extern { pub type BasicBlock; }
|
extern { pub type BasicBlock; }
|
||||||
extern { pub type Builder; }
|
extern { pub type Builder; }
|
||||||
extern { pub type MemoryBuffer; }
|
extern { pub type MemoryBuffer; }
|
||||||
extern { pub type PassManager; }
|
pub struct PassManager<'a>(InvariantOpaque<'a>);
|
||||||
pub type PassManagerRef = *mut PassManager;
|
|
||||||
extern { pub type PassManagerBuilder; }
|
extern { pub type PassManagerBuilder; }
|
||||||
extern { pub type ObjectFile; }
|
extern { pub type ObjectFile; }
|
||||||
extern { pub type SectionIterator; }
|
extern { pub type SectionIterator; }
|
||||||
|
@ -1105,16 +1104,16 @@ extern "C" {
|
||||||
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
|
||||||
|
|
||||||
/// Creates a pass manager.
|
/// Creates a pass manager.
|
||||||
pub fn LLVMCreatePassManager() -> PassManagerRef;
|
pub fn LLVMCreatePassManager() -> &'a mut PassManager<'a>;
|
||||||
|
|
||||||
/// Creates a function-by-function pass manager
|
/// Creates a function-by-function pass manager
|
||||||
pub fn LLVMCreateFunctionPassManagerForModule(M: &Module) -> PassManagerRef;
|
pub fn LLVMCreateFunctionPassManagerForModule(M: &'a Module) -> &'a mut PassManager<'a>;
|
||||||
|
|
||||||
/// Disposes a pass manager.
|
/// Disposes a pass manager.
|
||||||
pub fn LLVMDisposePassManager(PM: PassManagerRef);
|
pub fn LLVMDisposePassManager(PM: &'a mut PassManager<'a>);
|
||||||
|
|
||||||
/// Runs a pass manager on a module.
|
/// Runs a pass manager on a module.
|
||||||
pub fn LLVMRunPassManager(PM: PassManagerRef, M: &Module) -> Bool;
|
pub fn LLVMRunPassManager(PM: &PassManager<'a>, M: &'a Module) -> Bool;
|
||||||
|
|
||||||
pub fn LLVMInitializePasses();
|
pub fn LLVMInitializePasses();
|
||||||
|
|
||||||
|
@ -1125,17 +1124,17 @@ extern "C" {
|
||||||
pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(PMB: &PassManagerBuilder,
|
pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(PMB: &PassManagerBuilder,
|
||||||
threshold: c_uint);
|
threshold: c_uint);
|
||||||
pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: &PassManagerBuilder,
|
pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: &PassManagerBuilder,
|
||||||
PM: PassManagerRef);
|
PM: &PassManager);
|
||||||
|
|
||||||
pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: &PassManagerBuilder,
|
pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: &PassManagerBuilder,
|
||||||
PM: PassManagerRef);
|
PM: &PassManager);
|
||||||
pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: &PassManagerBuilder,
|
pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: &PassManagerBuilder,
|
||||||
PM: PassManagerRef,
|
PM: &PassManager,
|
||||||
Internalize: Bool,
|
Internalize: Bool,
|
||||||
RunInliner: Bool);
|
RunInliner: Bool);
|
||||||
pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
|
pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
|
||||||
PMB: &PassManagerBuilder,
|
PMB: &PassManagerBuilder,
|
||||||
PM: PassManagerRef) -> bool;
|
PM: &PassManager) -> bool;
|
||||||
|
|
||||||
// Stuff that's in rustllvm/ because it's not upstream yet.
|
// Stuff that's in rustllvm/ because it's not upstream yet.
|
||||||
|
|
||||||
|
@ -1416,7 +1415,7 @@ extern "C" {
|
||||||
|
|
||||||
pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
|
pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
|
||||||
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
|
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
|
||||||
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: &'static mut Pass);
|
pub fn LLVMRustAddPass(PM: &PassManager, Pass: &'static mut Pass);
|
||||||
|
|
||||||
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
|
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
|
||||||
|
|
||||||
|
@ -1437,7 +1436,7 @@ extern "C" {
|
||||||
Singlethread: bool)
|
Singlethread: bool)
|
||||||
-> Option<&'static mut TargetMachine>;
|
-> Option<&'static mut TargetMachine>;
|
||||||
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
|
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
|
||||||
pub fn LLVMRustAddAnalysisPasses(T: &TargetMachine, PM: PassManagerRef, M: &Module);
|
pub fn LLVMRustAddAnalysisPasses(T: &'a TargetMachine, PM: &PassManager<'a>, M: &'a Module);
|
||||||
pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder,
|
pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder,
|
||||||
M: &'a Module,
|
M: &'a Module,
|
||||||
DisableSimplifyLibCalls: bool);
|
DisableSimplifyLibCalls: bool);
|
||||||
|
@ -1449,18 +1448,18 @@ extern "C" {
|
||||||
PrepareForThinLTO: bool,
|
PrepareForThinLTO: bool,
|
||||||
PGOGenPath: *const c_char,
|
PGOGenPath: *const c_char,
|
||||||
PGOUsePath: *const c_char);
|
PGOUsePath: *const c_char);
|
||||||
pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef,
|
pub fn LLVMRustAddLibraryInfo(PM: &PassManager<'a>,
|
||||||
M: &Module,
|
M: &'a Module,
|
||||||
DisableSimplifyLibCalls: bool);
|
DisableSimplifyLibCalls: bool);
|
||||||
pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: &Module);
|
pub fn LLVMRustRunFunctionPassManager(PM: &PassManager<'a>, M: &'a Module);
|
||||||
pub fn LLVMRustWriteOutputFile(T: &'a TargetMachine,
|
pub fn LLVMRustWriteOutputFile(T: &'a TargetMachine,
|
||||||
PM: PassManagerRef,
|
PM: &PassManager<'a>,
|
||||||
M: &'a Module,
|
M: &'a Module,
|
||||||
Output: *const c_char,
|
Output: *const c_char,
|
||||||
FileType: FileType)
|
FileType: FileType)
|
||||||
-> LLVMRustResult;
|
-> LLVMRustResult;
|
||||||
pub fn LLVMRustPrintModule(PM: PassManagerRef,
|
pub fn LLVMRustPrintModule(PM: &PassManager<'a>,
|
||||||
M: &Module,
|
M: &'a Module,
|
||||||
Output: *const c_char,
|
Output: *const c_char,
|
||||||
Demangle: extern fn(*const c_char,
|
Demangle: extern fn(*const c_char,
|
||||||
size_t,
|
size_t,
|
||||||
|
|
Loading…
Reference in New Issue