passes.rs 5.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
// Copyright 2012 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use driver::session;
14
use lib::llvm::{PassRef, ModuleRef,PassManagerRef,TargetDataRef};
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
use lib::llvm::llvm;
use lib;

pub struct PassManager {
    priv llpm: PassManagerRef
}

impl Drop for PassManager {
    fn finalize(&self) {
        unsafe {
            llvm::LLVMDisposePassManager(self.llpm);
        }
    }
}

impl PassManager {
    pub fn new(td: TargetDataRef) -> PassManager {
        unsafe {
            let pm = PassManager {
                llpm: llvm::LLVMCreatePassManager()
            };
            llvm::LLVMAddTargetData(td, pm.llpm);

            return pm;
        }
    }

    pub fn addPass(&mut self, pass:PassRef) {
        unsafe {
            llvm::LLVMAddPass(self.llpm, pass);
        }
    }

    pub fn run(&self, md:ModuleRef) -> bool {
        unsafe {
            llvm::LLVMRunPassManager(self.llpm, md) == lib::llvm::True
        }
    }
}


pub fn populatePassManager(pm: &mut PassManager, level:session::OptLevel) {
    unsafe {
58 59 60 61
        // We add a lot of normally-unused prototypes, so always strip them
        // straight away, later passes will get rid of any that are optimized
        // away
        pm.addPass(llvm::LLVMCreateStripDeadPrototypesPass());
62 63
        if level == session::No {
            pm.addPass(llvm::LLVMCreateAlwaysInlinerPass());
64

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
            return;
        }

        //NOTE: Add library info

        pm.addPass(llvm::LLVMCreateTypeBasedAliasAnalysisPass());
        pm.addPass(llvm::LLVMCreateBasicAliasAnalysisPass());

        pm.addPass(llvm::LLVMCreateSROAPass());
        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
        pm.addPass(llvm::LLVMCreateLowerExpectIntrinsicPass());

        pm.addPass(llvm::LLVMCreateGlobalOptimizerPass());
        pm.addPass(llvm::LLVMCreateIPSCCPPass());
        pm.addPass(llvm::LLVMCreateDeadArgEliminationPass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());

        pm.addPass(llvm::LLVMCreatePruneEHPass());

85 86 87 88 89 90 91
        if level == session::Aggressive {
            // Do this before inlining, since inlining might
            // make minor changes to functions that mean they
            // can't be merged, despite being almost identical
            pm.addPass(llvm::LLVMCreateMergeFunctionsPass());
        }

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
        match level {
            session::Less       => pm.addPass(llvm::LLVMCreateFunctionInliningPass(200)),
            session::Default    => pm.addPass(llvm::LLVMCreateFunctionInliningPass(225)),
            session::Aggressive => pm.addPass(llvm::LLVMCreateFunctionInliningPass(275)),
            session::No         => ()
        }

        pm.addPass(llvm::LLVMCreateFunctionAttrsPass());

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateArgumentPromotionPass());
        }

        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
        pm.addPass(llvm::LLVMCreateSimplifyLibCallsPass());
        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());

        pm.addPass(llvm::LLVMCreateTailCallEliminationPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateReassociatePass());
        pm.addPass(llvm::LLVMCreateLoopRotatePass());
        pm.addPass(llvm::LLVMCreateLICMPass());

        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateIndVarSimplifyPass());
        pm.addPass(llvm::LLVMCreateLoopIdiomPass());
        pm.addPass(llvm::LLVMCreateLoopDeletionPass());

        if level == session::Aggressive {
J
James Miller 已提交
124
            pm.addPass(llvm::LLVMCreateLoopVectorizePass());
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
        }
        pm.addPass(llvm::LLVMCreateLoopUnrollPass());

        if level != session::Less {
            pm.addPass(llvm::LLVMCreateGVNPass());
        }
        pm.addPass(llvm::LLVMCreateMemCpyOptPass());
        pm.addPass(llvm::LLVMCreateSCCPPass());

        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
        pm.addPass(llvm::LLVMCreateDeadStoreEliminationPass());

        pm.addPass(llvm::LLVMCreateBBVectorizePass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
141 142 143 144 145 146 147 148
        pm.addPass(llvm::LLVMCreateEarlyCSEPass());

        pm.addPass(llvm::LLVMCreateLoopUnrollPass());

        pm.addPass(llvm::LLVMCreateAggressiveDCEPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateInstructionSimplifierPass());

149 150 151 152 153 154
        if level != session::Less {
            pm.addPass(llvm::LLVMCreateGlobalDCEPass());
            pm.addPass(llvm::LLVMCreateConstantMergePass());
        }
    }
}