Skip to content

Commit

Permalink
Register LLVM passes with the correct LLVM pass manager.
Browse files Browse the repository at this point in the history
LLVM was upgraded to a new version in this commit:

f9d4149

which was part of this pull request:

#26025

Consider the following two lines from that commit:

f9d4149#diff-a3b24dbe2ea7c1981f9ac79f9745f40aL462

f9d4149#diff-a3b24dbe2ea7c1981f9ac79f9745f40aL469

The purpose of these lines is to register LLVM passes. Prior to the that
commit, the passes being handled were assumed to be ModulePasses (a
specific type of LLVM pass) since they were being added to a ModulePass
manager. After that commit, both lines were refactored (presumably in an
attempt to DRY out the code), but the ModulePasses were changed to be
registered to a FunctionPass manager. This change resulted in
ModulePasses being run, but a Function object was being passed as a
parameter to the pass instead of a Module, which resulted in
segmentation faults.

In this commit, I changed relevant sections of the code to check the
type of the passes being added and register them to the appropriate pass
manager.

Closes #31067
  • Loading branch information
frewsxcv committed Jan 25, 2016
1 parent 289020b commit d942621
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 12 deletions.
14 changes: 13 additions & 1 deletion src/librustc_llvm/lib.rs
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
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
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
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

0 comments on commit d942621

Please sign in to comment.