Skip to content

Register LLVM passes with the correct LLVM pass manager. #31176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,15 @@ pub enum ArchiveKind {
K_COFF,
}

/// Represents the different LLVM passes Rust supports
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
pub enum SupportedPassKind {
Function,
Module,
Unsupported,
}

// Opaque pointer types
#[allow(missing_copy_implementations)]
pub enum Module_opaque {}
Expand Down Expand Up @@ -2008,7 +2017,10 @@ extern {
pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;

pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
pub fn LLVMRustPassKind(Pass: PassRef) -> SupportedPassKind;
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);

pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
CPU: *const c_char,
Features: *const c_char,
Expand Down
8 changes: 6 additions & 2 deletions src/librustc_trans/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,19 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
unsafe {
let pm = llvm::LLVMCreatePassManager();
llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
assert!(!pass.is_null());
llvm::LLVMRustAddPass(pm, pass);

with_llvm_pmb(llmod, config, &mut |b| {
llvm::LLVMPassManagerBuilderPopulateLTOPassManager(b, pm,
/* Internalize = */ False,
/* RunInliner = */ True);
});

llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
assert!(!pass.is_null());
llvm::LLVMRustAddPass(pm, pass);

time(sess.time_passes(), "LTO passes", ||
llvm::LLVMRunPassManager(pm, llmod));
Expand Down
19 changes: 16 additions & 3 deletions src/librustc_trans/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,22 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,

// If we're verifying or linting, add them to the function pass
// manager.
let addpass = |pass: &str| {
let pass = CString::new(pass).unwrap();
llvm::LLVMRustAddPass(fpm, pass.as_ptr())
let addpass = |pass_name: &str| {
let pass_name = CString::new(pass_name).unwrap();
let pass = llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr());
if pass.is_null() {
return false;
}
let pass_manager = match llvm::LLVMRustPassKind(pass) {
llvm::SupportedPassKind::Function => fpm,
llvm::SupportedPassKind::Module => mpm,
llvm::SupportedPassKind::Unsupported => {
cgcx.handler.err("Encountered LLVM pass kind we can't handle");
return true
},
};
llvm::LLVMRustAddPass(pass_manager, pass);
true
};

if !config.no_verify { assert!(addpass("verify")); }
Expand Down
36 changes: 30 additions & 6 deletions src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,43 @@ LLVMInitializePasses() {
initializeTarget(Registry);
}

extern "C" bool
LLVMRustAddPass(LLVMPassManagerRef PM, const char *PassName) {
PassManagerBase *pm = unwrap(PM);

enum class SupportedPassKind {
Function,
Module,
Unsupported
};

extern "C" Pass*
LLVMRustFindAndCreatePass(const char *PassName) {
StringRef SR(PassName);
PassRegistry *PR = PassRegistry::getPassRegistry();

const PassInfo *PI = PR->getPassInfo(SR);
if (PI) {
pm->add(PI->createPass());
return true;
return PI->createPass();
}
return false;
return NULL;
}

extern "C" SupportedPassKind
LLVMRustPassKind(Pass *pass) {
assert(pass);
PassKind passKind = pass->getPassKind();
if (passKind == PT_Module) {
return SupportedPassKind::Module;
} else if (passKind == PT_Function) {
return SupportedPassKind::Function;
} else {
return SupportedPassKind::Unsupported;
}
}

extern "C" void
LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
assert(pass);
PassManagerBase *pm = unwrap(PM);
pm->add(pass);
}

extern "C" LLVMTargetMachineRef
Expand Down