281 lines
14 KiB
Python
281 lines
14 KiB
Python
#
|
|
# Copyright (c) 2008-10, Mahadevan R All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are met:
|
|
#
|
|
# * Redistributions of source code must retain the above copyright notice,
|
|
# this list of conditions and the following disclaimer.
|
|
#
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
# and/or other materials provided with the distribution.
|
|
#
|
|
# * Neither the name of this software, nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
|
|
"""Pass managers and passes.
|
|
|
|
This module provides the LLVM pass managers and the passes themselves.
|
|
All transformation passes listed at http://www.llvm.org/docs/Passes.html
|
|
are available.
|
|
"""
|
|
|
|
import llvm # top-level, for common stuff
|
|
import llvm.ee as ee # target data
|
|
import llvm.core as core # module, function etc.
|
|
import llvm._core as _core # C wrappers
|
|
|
|
|
|
# passes
|
|
PASS_AAEVAL = 1
|
|
PASS_AGGRESSIVE_DCE = 3
|
|
PASS_ALIAS_ANALYSIS_COUNTER = 4
|
|
PASS_ALWAYS_INLINER = 5
|
|
PASS_ARGUMENT_PROMOTION = 6
|
|
PASS_BASIC_ALIAS_ANALYSIS = 7
|
|
PASS_BLOCK_PLACEMENT = 8
|
|
PASS_BREAK_CRITICAL_EDGES = 9
|
|
PASS_CFG_SIMPLIFICATION = 10
|
|
PASS_CODE_GEN_PREPARE = 11
|
|
PASS_CONSTANT_MERGE = 12
|
|
PASS_CONSTANT_PROPAGATION = 13
|
|
PASS_DBG_INFO_PRINTER = 14
|
|
PASS_DEAD_ARG_ELIMINATION = 15
|
|
PASS_DEAD_CODE_ELIMINATION = 16
|
|
PASS_DEAD_INST_ELIMINATION = 17
|
|
PASS_DEAD_STORE_ELIMINATION = 18
|
|
PASS_DEAD_TYPE_ELIMINATION = 19
|
|
PASS_DEMOTE_REGISTER_TO_MEMORY = 20
|
|
PASS_DOM_ONLY_PRINTER = 21
|
|
PASS_DOM_ONLY_VIEWER = 22
|
|
PASS_DOM_PRINTER = 23
|
|
PASS_DOM_VIEWER = 24
|
|
PASS_EDGE_PROFILER = 25
|
|
PASS_FUNCTION_ATTRS = 26
|
|
PASS_FUNCTION_INLINING = 27
|
|
#PASS_GEP_SPLITTER = 28
|
|
PASS_GLOBAL_DCE = 29
|
|
PASS_GLOBAL_OPTIMIZER = 30
|
|
PASS_GLOBALS_MOD_REF = 31
|
|
PASS_GVN = 32
|
|
PASS_IND_VAR_SIMPLIFY = 33
|
|
PASS_INST_COUNT = 34
|
|
PASS_INSTRUCTION_COMBINING = 35
|
|
PASS_INSTRUCTION_NAMER = 36
|
|
PASS_IP_CONSTANT_PROPAGATION = 37
|
|
PASS_IPSCCP = 38
|
|
PASS_JUMP_THREADING = 39
|
|
PASS_LAZY_VALUE_INFO = 40
|
|
PASS_LCSSA = 41
|
|
PASS_LICM = 42
|
|
#PASS_LIVE_VALUES = 43
|
|
PASS_LOOP_DELETION = 44
|
|
PASS_LOOP_DEPENDENCE_ANALYSIS = 45
|
|
PASS_LOOP_EXTRACTOR = 46
|
|
#PASS_LOOP_INDEX_SPLIT = 47
|
|
PASS_LOOP_ROTATE = 48
|
|
PASS_LOOP_SIMPLIFY = 49
|
|
PASS_LOOP_STRENGTH_REDUCE = 50
|
|
PASS_LOOP_UNROLL = 51
|
|
PASS_LOOP_UNSWITCH = 52
|
|
PASS_LOWER_INVOKE = 53
|
|
PASS_LOWER_SET_JMP = 54
|
|
PASS_LOWER_SWITCH = 55
|
|
PASS_MEM_CPY_OPT = 56
|
|
PASS_MERGE_FUNCTIONS = 57
|
|
PASS_NO_AA = 58
|
|
PASS_NO_PROFILE_INFO = 59
|
|
PASS_OPTIMAL_EDGE_PROFILER = 60
|
|
PASS_PARTIAL_INLINING = 61
|
|
#PASS_PARTIAL_SPECIALIZATION = 62
|
|
#PASS_POST_DOM_ONLY_PRINTER = 63
|
|
#PASS_POST_DOM_ONLY_VIEWER = 64
|
|
#PASS_POST_DOM_PRINTER = 65
|
|
#PASS_POST_DOM_VIEWER = 66
|
|
PASS_PROFILE_ESTIMATOR = 67
|
|
PASS_PROFILE_LOADER = 68
|
|
PASS_PROFILE_VERIFIER = 69
|
|
PASS_PROMOTE_MEMORY_TO_REGISTER = 70
|
|
PASS_PRUNE_EH = 71
|
|
PASS_REASSOCIATE = 72
|
|
PASS_SCALAR_EVOLUTION_ALIAS_ANALYSIS = 73
|
|
PASS_SCALAR_REPL_AGGREGATES = 74
|
|
PASS_SCCP = 76
|
|
#PASS_SIMPLIFY_HALF_POWR_LIB_CALLS = 77
|
|
PASS_SIMPLIFY_LIB_CALLS = 78
|
|
PASS_SINGLE_LOOP_EXTRACTOR = 79
|
|
PASS_STRIP_DEAD_PROTOTYPES = 82
|
|
PASS_STRIP_NON_DEBUG_SYMBOLS = 83
|
|
PASS_STRIP_SYMBOLS = 84
|
|
PASS_STRUCT_RET_PROMOTION = 85
|
|
PASS_TAIL_CALL_ELIMINATION = 86
|
|
PASS_TAIL_DUPLICATION = 87
|
|
PASS_UNIFY_FUNCTION_EXIT_NODES = 88
|
|
PASS_INTERNALIZE = 89
|
|
|
|
|
|
|
|
#===----------------------------------------------------------------------===
|
|
# Helper functions
|
|
#===----------------------------------------------------------------------===
|
|
|
|
_pass_creator = {
|
|
PASS_AAEVAL : _core.LLVMAddAAEvalPass,
|
|
PASS_AGGRESSIVE_DCE : _core.LLVMAddAggressiveDCEPass,
|
|
PASS_ALIAS_ANALYSIS_COUNTER : _core.LLVMAddAliasAnalysisCounterPass,
|
|
PASS_ALWAYS_INLINER : _core.LLVMAddAlwaysInlinerPass,
|
|
PASS_ARGUMENT_PROMOTION : _core.LLVMAddArgumentPromotionPass,
|
|
PASS_BASIC_ALIAS_ANALYSIS : _core.LLVMAddBasicAliasAnalysisPass,
|
|
PASS_BLOCK_PLACEMENT : _core.LLVMAddBlockPlacementPass,
|
|
PASS_BREAK_CRITICAL_EDGES : _core.LLVMAddBreakCriticalEdgesPass,
|
|
PASS_CFG_SIMPLIFICATION : _core.LLVMAddCFGSimplificationPass,
|
|
PASS_CODE_GEN_PREPARE : _core.LLVMAddCodeGenPreparePass,
|
|
PASS_CONSTANT_MERGE : _core.LLVMAddConstantMergePass,
|
|
PASS_CONSTANT_PROPAGATION : _core.LLVMAddConstantPropagationPass,
|
|
PASS_DBG_INFO_PRINTER : _core.LLVMAddDbgInfoPrinterPass,
|
|
PASS_DEAD_ARG_ELIMINATION : _core.LLVMAddDeadArgEliminationPass,
|
|
PASS_DEAD_CODE_ELIMINATION : _core.LLVMAddDeadCodeEliminationPass,
|
|
PASS_DEAD_INST_ELIMINATION : _core.LLVMAddDeadInstEliminationPass,
|
|
PASS_DEAD_STORE_ELIMINATION : _core.LLVMAddDeadStoreEliminationPass,
|
|
# PASS_DEAD_TYPE_ELIMINATION : _core.LLVMAddDeadTypeEliminationPass,
|
|
PASS_DEMOTE_REGISTER_TO_MEMORY : _core.LLVMAddDemoteRegisterToMemoryPass,
|
|
PASS_DOM_ONLY_PRINTER : _core.LLVMAddDomOnlyPrinterPass,
|
|
PASS_DOM_ONLY_VIEWER : _core.LLVMAddDomOnlyViewerPass,
|
|
PASS_DOM_PRINTER : _core.LLVMAddDomPrinterPass,
|
|
PASS_DOM_VIEWER : _core.LLVMAddDomViewerPass,
|
|
PASS_EDGE_PROFILER : _core.LLVMAddEdgeProfilerPass,
|
|
PASS_FUNCTION_ATTRS : _core.LLVMAddFunctionAttrsPass,
|
|
PASS_FUNCTION_INLINING : _core.LLVMAddFunctionInliningPass,
|
|
# PASS_GEP_SPLITTER : _core.LLVMAddGEPSplitterPass,
|
|
PASS_GLOBAL_DCE : _core.LLVMAddGlobalDCEPass,
|
|
PASS_GLOBAL_OPTIMIZER : _core.LLVMAddGlobalOptimizerPass,
|
|
PASS_GLOBALS_MOD_REF : _core.LLVMAddGlobalsModRefPass,
|
|
PASS_GVN : _core.LLVMAddGVNPass,
|
|
PASS_IND_VAR_SIMPLIFY : _core.LLVMAddIndVarSimplifyPass,
|
|
PASS_INST_COUNT : _core.LLVMAddInstCountPass,
|
|
PASS_INSTRUCTION_COMBINING : _core.LLVMAddInstructionCombiningPass,
|
|
PASS_INSTRUCTION_NAMER : _core.LLVMAddInstructionNamerPass,
|
|
PASS_IP_CONSTANT_PROPAGATION : _core.LLVMAddIPConstantPropagationPass,
|
|
PASS_IPSCCP : _core.LLVMAddIPSCCPPass,
|
|
PASS_JUMP_THREADING : _core.LLVMAddJumpThreadingPass,
|
|
PASS_LAZY_VALUE_INFO : _core.LLVMAddLazyValueInfoPass,
|
|
PASS_LCSSA : _core.LLVMAddLCSSAPass,
|
|
PASS_LICM : _core.LLVMAddLICMPass,
|
|
# PASS_LIVE_VALUES : _core.LLVMAddLiveValuesPass,
|
|
PASS_LOOP_DELETION : _core.LLVMAddLoopDeletionPass,
|
|
PASS_LOOP_DEPENDENCE_ANALYSIS : _core.LLVMAddLoopDependenceAnalysisPass,
|
|
PASS_LOOP_EXTRACTOR : _core.LLVMAddLoopExtractorPass,
|
|
# PASS_LOOP_INDEX_SPLIT : _core.LLVMAddLoopIndexSplitPass,
|
|
PASS_LOOP_ROTATE : _core.LLVMAddLoopRotatePass,
|
|
PASS_LOOP_SIMPLIFY : _core.LLVMAddLoopSimplifyPass,
|
|
PASS_LOOP_STRENGTH_REDUCE : _core.LLVMAddLoopStrengthReducePass,
|
|
PASS_LOOP_UNROLL : _core.LLVMAddLoopUnrollPass,
|
|
PASS_LOOP_UNSWITCH : _core.LLVMAddLoopUnswitchPass,
|
|
PASS_LOWER_INVOKE : _core.LLVMAddLowerInvokePass,
|
|
PASS_LOWER_SWITCH : _core.LLVMAddLowerSwitchPass,
|
|
PASS_MEM_CPY_OPT : _core.LLVMAddMemCpyOptPass,
|
|
PASS_MERGE_FUNCTIONS : _core.LLVMAddMergeFunctionsPass,
|
|
PASS_NO_AA : _core.LLVMAddNoAAPass,
|
|
PASS_NO_PROFILE_INFO : _core.LLVMAddNoProfileInfoPass,
|
|
PASS_OPTIMAL_EDGE_PROFILER : _core.LLVMAddOptimalEdgeProfilerPass,
|
|
PASS_PARTIAL_INLINING : _core.LLVMAddPartialInliningPass,
|
|
# PASS_PARTIAL_SPECIALIZATION : _core.LLVMAddPartialSpecializationPass,
|
|
# PASS_POST_DOM_ONLY_PRINTER : _core.LLVMAddPostDomOnlyPrinterPass,
|
|
# PASS_POST_DOM_ONLY_VIEWER : _core.LLVMAddPostDomOnlyViewerPass,
|
|
# PASS_POST_DOM_PRINTER : _core.LLVMAddPostDomPrinterPass,
|
|
# PASS_POST_DOM_VIEWER : _core.LLVMAddPostDomViewerPass,
|
|
PASS_PROFILE_ESTIMATOR : _core.LLVMAddProfileEstimatorPass,
|
|
PASS_PROFILE_LOADER : _core.LLVMAddProfileLoaderPass,
|
|
PASS_PROFILE_VERIFIER : _core.LLVMAddProfileVerifierPass,
|
|
PASS_PROMOTE_MEMORY_TO_REGISTER : _core.LLVMAddPromoteMemoryToRegisterPass,
|
|
PASS_PRUNE_EH : _core.LLVMAddPruneEHPass,
|
|
PASS_REASSOCIATE : _core.LLVMAddReassociatePass,
|
|
PASS_SCALAR_EVOLUTION_ALIAS_ANALYSIS : _core.LLVMAddScalarEvolutionAliasAnalysisPass,
|
|
PASS_SCALAR_REPL_AGGREGATES : _core.LLVMAddScalarReplAggregatesPass,
|
|
PASS_SCCP : _core.LLVMAddSCCPPass,
|
|
# PASS_SIMPLIFY_HALF_POWR_LIB_CALLS : _core.LLVMAddSimplifyHalfPowrLibCallsPass,
|
|
PASS_SIMPLIFY_LIB_CALLS : _core.LLVMAddSimplifyLibCallsPass,
|
|
PASS_SINGLE_LOOP_EXTRACTOR : _core.LLVMAddSingleLoopExtractorPass,
|
|
PASS_STRIP_DEAD_PROTOTYPES : _core.LLVMAddStripDeadPrototypesPass,
|
|
PASS_STRIP_NON_DEBUG_SYMBOLS : _core.LLVMAddStripNonDebugSymbolsPass,
|
|
PASS_STRIP_SYMBOLS : _core.LLVMAddStripSymbolsPass,
|
|
# PASS_STRUCT_RET_PROMOTION : _core.LLVMAddStructRetPromotionPass,
|
|
PASS_TAIL_CALL_ELIMINATION : _core.LLVMAddTailCallEliminationPass,
|
|
# PASS_TAIL_DUPLICATION : _core.LLVMAddTailDuplicationPass,
|
|
PASS_UNIFY_FUNCTION_EXIT_NODES : _core.LLVMAddUnifyFunctionExitNodesPass,
|
|
PASS_INTERNALIZE : _core.LLVMAddInternalize2Pass,
|
|
}
|
|
|
|
|
|
#===----------------------------------------------------------------------===
|
|
# Pass manager
|
|
#===----------------------------------------------------------------------===
|
|
|
|
class PassManager(object):
|
|
|
|
@staticmethod
|
|
def new():
|
|
return PassManager(_core.LLVMCreatePassManager())
|
|
|
|
def __init__(self, ptr):
|
|
self.ptr = ptr
|
|
|
|
def __del__(self):
|
|
_core.LLVMDisposePassManager(self.ptr)
|
|
|
|
def add(self, tgt_data_or_pass_id):
|
|
if isinstance(tgt_data_or_pass_id, ee.TargetData):
|
|
self._add_target_data(tgt_data_or_pass_id)
|
|
elif tgt_data_or_pass_id in _pass_creator:
|
|
self._add_pass(tgt_data_or_pass_id)
|
|
else:
|
|
raise llvm.LLVMException("invalid pass_id (%s)" % str(tgt_data_or_pass_id))
|
|
|
|
def _add_target_data(self, tgt):
|
|
_core.LLVMAddTargetData(tgt.ptr, self.ptr)
|
|
|
|
def _add_pass(self, pass_id):
|
|
cfn = _pass_creator[pass_id]
|
|
cfn(self.ptr)
|
|
|
|
def run(self, module):
|
|
core.check_is_module(module)
|
|
return _core.LLVMRunPassManager(self.ptr, module.ptr)
|
|
|
|
|
|
class FunctionPassManager(PassManager):
|
|
|
|
@staticmethod
|
|
def new(module):
|
|
core.check_is_module(module)
|
|
ptr = _core.LLVMCreateFunctionPassManagerForModule(module.ptr)
|
|
return FunctionPassManager(ptr)
|
|
|
|
def __init__(self, ptr):
|
|
PassManager.__init__(self, ptr)
|
|
|
|
def initialize(self):
|
|
_core.LLVMInitializeFunctionPassManager(self.ptr)
|
|
|
|
def run(self, fn):
|
|
core.check_is_function(fn)
|
|
return _core.LLVMRunFunctionPassManager(self.ptr, fn.ptr)
|
|
|
|
def finalize(self):
|
|
_core.LLVMFinalizeFunctionPassManager(self.ptr)
|
|
|