Begin to expose Pass class.

This commit is contained in:
Siu Kwan Lam 2012-12-31 18:46:57 -06:00
commit ff92a05858
6 changed files with 182 additions and 259 deletions

View file

@ -1057,97 +1057,11 @@ _wrap_none2none(LLVMInitializePTXAsmPrinter)
/*===----------------------------------------------------------------------===*/
/* Passes */
/*===----------------------------------------------------------------------===*/
/*
#define _wrap_pass(P) \
_wrap_obj2none( LLVMAdd ## P ## Pass, LLVMPassManagerRef)
_wrap_pass( AAEval )
_wrap_pass( AggressiveDCE )
_wrap_pass( AliasAnalysisCounter )
_wrap_pass( AlwaysInliner )
_wrap_pass( ArgumentPromotion )
_wrap_pass( BasicAliasAnalysis )
_wrap_pass( BlockPlacement )
_wrap_pass( BreakCriticalEdges )
_wrap_pass( CFGSimplification )
_wrap_pass( CodeGenPrepare )
_wrap_pass( ConstantMerge )
_wrap_pass( ConstantPropagation )
_wrap_pass( DbgInfoPrinter )
_wrap_pass( DeadArgElimination )
_wrap_pass( DeadCodeElimination )
_wrap_pass( DeadInstElimination )
_wrap_pass( DeadStoreElimination )
_wrap_pass( DemoteRegisterToMemory )
_wrap_pass( DomOnlyPrinter )
_wrap_pass( DomOnlyViewer )
_wrap_pass( DomPrinter )
_wrap_pass( DomViewer )
_wrap_pass( EdgeProfiler )
_wrap_pass( FunctionAttrs )
_wrap_pass( FunctionInlining )
//_wrap_pass( GEPSplitter )
_wrap_pass( GlobalDCE )
_wrap_pass( GlobalOptimizer )
_wrap_pass( GlobalsModRef )
_wrap_pass( GVN )
_wrap_pass( IndVarSimplify )
_wrap_pass( InstCount )
_wrap_pass( InstructionCombining )
_wrap_pass( InstructionNamer )
_wrap_pass( IPConstantPropagation )
_wrap_pass( IPSCCP )
_wrap_pass( JumpThreading )
_wrap_pass( LazyValueInfo )
_wrap_pass( LCSSA )
_wrap_pass( LICM )
//_wrap_pass( LiveValues )
_wrap_pass( LoopDeletion )
_wrap_pass( LoopDependenceAnalysis )
_wrap_pass( LoopExtractor )
//_wrap_pass( LoopIndexSplit )
_wrap_pass( LoopRotate )
_wrap_pass( LoopSimplify )
_wrap_pass( LoopStrengthReduce )
_wrap_pass( LoopUnroll )
_wrap_pass( LoopUnswitch )
_wrap_pass( LowerInvoke )
_wrap_pass( LowerSwitch )
_wrap_pass( MemCpyOpt )
_wrap_pass( MergeFunctions )
_wrap_pass( NoAA )
_wrap_pass( NoProfileInfo )
_wrap_pass( OptimalEdgeProfiler )
_wrap_pass( PartialInlining )
//_wrap_pass( PartialSpecialization )
_wrap_pass( PostDomOnlyPrinter )
_wrap_pass( PostDomOnlyViewer )
_wrap_pass( PostDomPrinter )
_wrap_pass( PostDomViewer )
_wrap_pass( ProfileEstimator )
_wrap_pass( ProfileLoader )
_wrap_pass( ProfileVerifier )
_wrap_pass( PromoteMemoryToRegister )
_wrap_pass( PruneEH )
_wrap_pass( Reassociate )
_wrap_pass( ScalarEvolutionAliasAnalysis )
_wrap_pass( ScalarReplAggregates )
_wrap_pass( SCCP )
//_wrap_pass( SimplifyHalfPowrLibCalls )
_wrap_pass( SimplifyLibCalls )
_wrap_pass( SingleLoopExtractor )
_wrap_pass( StripDeadPrototypes )
_wrap_pass( StripNonDebugSymbols )
_wrap_pass( StripSymbols )
//_wrap_pass( StructRetPromotion )
_wrap_pass( TailCallElimination )
//_wrap_pass( TailDuplication )
_wrap_pass( UnifyFunctionExitNodes )
_wrap_pass( Internalize2 )
*/
_wrap_str2obj(LLVMCreatePassByName, LLVMPassRef)
_wrap_obj2none(LLVMDisposePass, LLVMPassRef)
_wrap_obj2str(LLVMGetPassName, LLVMPassRef)
_wrap_objobj2none(LLVMAddPass, LLVMPassManagerRef, LLVMPassRef)
/*===----------------------------------------------------------------------===*/
/* Target Machine */
@ -2040,94 +1954,6 @@ static PyMethodDef core_methods[] = {
_method( LLVMInitializePTXAsmPrinter )
# endif
#endif
/* Passes */
/*
_pass( AAEval )
_pass( AggressiveDCE )
_pass( AliasAnalysisCounter )
_pass( AlwaysInliner )
_pass( ArgumentPromotion )
_pass( BasicAliasAnalysis )
_pass( BlockPlacement )
_pass( BreakCriticalEdges )
_pass( CFGSimplification )
_pass( CodeGenPrepare )
_pass( ConstantMerge )
_pass( ConstantPropagation )
_pass( DbgInfoPrinter )
_pass( DeadArgElimination )
_pass( DeadCodeElimination )
_pass( DeadInstElimination )
_pass( DeadStoreElimination )
_pass( DemoteRegisterToMemory )
_pass( DomOnlyPrinter )
_pass( DomOnlyViewer )
_pass( DomPrinter )
_pass( DomViewer )
_pass( EdgeProfiler )
_pass( FunctionAttrs )
_pass( FunctionInlining )
//_pass( GEPSplitter )
_pass( GlobalDCE )
_pass( GlobalOptimizer )
_pass( GlobalsModRef )
_pass( GVN )
_pass( IndVarSimplify )
_pass( InstCount )
_pass( InstructionCombining )
_pass( InstructionNamer )
_pass( IPConstantPropagation )
_pass( IPSCCP )
_pass( JumpThreading )
_pass( LazyValueInfo )
_pass( LCSSA )
_pass( LICM )
//_pass( LiveValues )
_pass( LoopDeletion )
_pass( LoopDependenceAnalysis )
_pass( LoopExtractor )
//_pass( LoopIndexSplit )
_pass( LoopRotate )
_pass( LoopSimplify )
_pass( LoopStrengthReduce )
_pass( LoopUnroll )
_pass( LoopUnswitch )
_pass( LowerInvoke )
_pass( LowerSwitch )
_pass( MemCpyOpt )
_pass( MergeFunctions )
_pass( NoAA )
_pass( NoProfileInfo )
_pass( OptimalEdgeProfiler )
_pass( PartialInlining )
//_pass( PartialSpecialization )
_pass( PostDomOnlyPrinter )
_pass( PostDomOnlyViewer )
_pass( PostDomPrinter )
_pass( PostDomViewer )
_pass( ProfileEstimator )
_pass( ProfileLoader )
_pass( ProfileVerifier )
_pass( PromoteMemoryToRegister )
_pass( PruneEH )
_pass( Reassociate )
_pass( ScalarEvolutionAliasAnalysis )
_pass( ScalarReplAggregates )
_pass( SCCP )
//_pass( SimplifyHalfPowrLibCalls )
_pass( SimplifyLibCalls )
_pass( SingleLoopExtractor )
_pass( StripDeadPrototypes )
_pass( StripNonDebugSymbols )
_pass( StripSymbols )
//_pass( StructRetPromotion )
_pass( TailCallElimination )
//_pass( TailDuplication )
_pass( UnifyFunctionExitNodes )
_pass( Internalize2 )
*/
/* Target Machine */
_method( LLVMTargetMachineFromEngineBuilder )
@ -2194,6 +2020,12 @@ static PyMethodDef core_methods[] = {
_method( LLVMGenericValueToPointer )
_method( LLVMDisposeGenericValue )
/* Passes */
_method( LLVMCreatePassByName )
_method( LLVMDisposePass )
_method( LLVMGetPassName )
_method( LLVMAddPass )
/* Misc */
_method( LLVMGetIntrinsic )
_method( LLVMLoadLibraryPermanently )

View file

@ -40,6 +40,10 @@ import logging
logger = logging.getLogger(__name__)
# re-export TargetData for backward compatibility.
from llvm.passes import TargetData
#===----------------------------------------------------------------------===
# Enumerations
#===----------------------------------------------------------------------===
@ -48,76 +52,6 @@ BO_BIG_ENDIAN = 0
BO_LITTLE_ENDIAN = 1
#===----------------------------------------------------------------------===
# Target data
#===----------------------------------------------------------------------===
class TargetData(llvm.Ownable):
@staticmethod
def new(strrep):
return TargetData(_core.LLVMCreateTargetData(strrep))
def __init__(self, ptr):
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetData)
def __str__(self):
return _core.LLVMTargetDataAsString(self.ptr)
@property
def byte_order(self):
return _core.LLVMByteOrder(self.ptr)
@property
def pointer_size(self):
return _core.LLVMPointerSize(self.ptr)
@property
def target_integer_type(self):
ptr = _core.LLVMIntPtrType(self.ptr);
return core.IntegerType(ptr, core.TYPE_INTEGER)
def size(self, ty):
core.check_is_type(ty)
return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr)
def store_size(self, ty):
core.check_is_type(ty)
return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr)
def abi_size(self, ty):
core.check_is_type(ty)
return _core.LLVMABISizeOfType(self.ptr, ty.ptr)
def abi_alignment(self, ty):
core.check_is_type(ty)
return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr)
def callframe_alignment(self, ty):
core.check_is_type(ty)
return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr)
def preferred_alignment(self, ty_or_gv):
if isinstance(ty_or_gv, core.Type):
return _core.LLVMPreferredAlignmentOfType(self.ptr,
ty_or_gv.ptr)
elif isinstance(ty_or_gv, core.GlobalVariable):
return _core.LLVMPreferredAlignmentOfGlobal(self.ptr,
ty_or_gv.ptr)
else:
raise core.LLVMException("argument is neither a type nor a global variable")
def element_at_offset(self, ty, ofs):
core.check_is_type_struct(ty)
ofs = int(ofs) # ofs is unsigned long long
return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs)
def offset_of_element(self, ty, el):
core.check_is_type_struct(ty)
el = int(el) # el should be an int
return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el)
#===----------------------------------------------------------------------===
# Generic value
#===----------------------------------------------------------------------===
@ -383,3 +317,4 @@ class TargetMachine(object):
@property
def feature_string(self):
return _core.LLVMTargetMachineGetFS(self.ptr)

View file

@ -95,6 +95,7 @@ namespace llvm{
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
template<typename T>
inline T **unwrap(LLVMTypeRef *Tys, unsigned Length) {
@ -143,6 +144,31 @@ const CodeGenOpt::Level OptLevelMap[] = {
} // end anony namespace
LLVMPassRef LLVMCreatePassByName(const char *name){
using namespace llvm;
const PassInfo * pi = Pass::lookupPassInfo(StringRef(name));
if (pi) {
return wrap(pi->createPass());
} else { // cannot find pass
return NULL;
}
}
void LLVMDisposePass(LLVMPassRef passref){
using namespace llvm;
delete unwrap(passref);
}
const char * LLVMGetPassName(LLVMPassRef passref){
using namespace llvm;
return unwrap(passref)->getPassName();
}
void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref){
using namespace llvm;
unwrap(pmref)->add(unwrap(passref));
}
LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType,
const char inlineAsm[],
const char constrains[],

View file

@ -54,6 +54,26 @@
extern "C" {
#endif
/*
* Wraps Pass::lookupPassInfo and PassInfo::createPass
*/
LLVMPassRef LLVMCreatePassByName(const char *name);
/*
* Wraps operator delete (Pass*)
*/
void LLVMDisposePass(LLVMPassRef passref);
/*
* Wraps Pass::getPassName
*/
const char * LLVMGetPassName(LLVMPassRef passref);
/*
* Wraps PassManager::add
*/
void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref);
/*
* Wraps llvm:InlineAsm::get
*/

View file

@ -21,7 +21,7 @@ inline ref wrap(const ty *P) { \
typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef;
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
typedef struct LLVMOpaqueNamedMD *LLVMNamedMDRef;
typedef struct LLVMOpaquePass *LLVMPassRef;
#ifdef __cplusplus
}

View file

@ -36,7 +36,6 @@ 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
import llvm._util as _util # Utility functions
@ -155,16 +154,18 @@ class PassManager(object):
def __del__(self):
_core.LLVMDisposePassManager(self.ptr)
def add(self, tgt_data_or_pass_name):
if isinstance(tgt_data_or_pass_name, ee.TargetData):
self._add_target_data(tgt_data_or_pass_name)
elif _util.isstring(tgt_data_or_pass_name):
self._add_pass(tgt_data_or_pass_name)
def add(self, pass_obj):
'''Add a pass to the pass manager.
pass_obj --- Either a Pass instance, a string name of a pass
'''
if isinstance(pass_obj, Pass):
_core.LLVMAddPass(self.ptr, pass_obj.ptr)
pass_obj._own(self) # PassManager owns the pass
elif _util.isstring(pass_obj):
self._add_pass(pass_obj)
else:
raise llvm.LLVMException("invalid pass_id (%s)" % tgt_data_or_pass_name)
def _add_target_data(self, tgt):
_core.LLVMAddTargetData(tgt.ptr, self.ptr)
raise llvm.LLVMException("invalid pass_id (%s)" % pass_obj)
def _add_pass(self, pass_name):
status = _core.LLVMAddPassByName(self.ptr, pass_name)
@ -197,6 +198,115 @@ class FunctionPassManager(PassManager):
def finalize(self):
_core.LLVMFinalizeFunctionPassManager(self.ptr)
#===----------------------------------------------------------------------===
# Passes
#===----------------------------------------------------------------------===
class Pass(llvm.Ownable):
'''Pass Inferface
'''
def __init__(self, ptr):
llvm.Ownable.__init__(self, ptr, _core.LLVMDisposePass)
@staticmethod
def new(name):
'''Create a new pass by name.
Note: Not all pass has a default constructor. LLVM will kill
the process if an the pass requires arguments to construct.
The error cannot be caught.
'''
ptr = _core.LLVMCreatePassByName(name)
p = Pass(ptr)
p.__name = name
return p
@property
def name(self):
return self.__name
@property
def description(self):
return _core.LLVMGetPassName(self.ptr)
def dump(self):
return _core.LLVMPassDump(self.ptr)
#===----------------------------------------------------------------------===
# Target data
#===----------------------------------------------------------------------===
class TargetData(Pass):
@staticmethod
def new(strrep):
return TargetData(_core.LLVMCreateTargetData(strrep))
def __str__(self):
return _core.LLVMTargetDataAsString(self.ptr)
@property
def byte_order(self):
return _core.LLVMByteOrder(self.ptr)
@property
def pointer_size(self):
return _core.LLVMPointerSize(self.ptr)
@property
def target_integer_type(self):
ptr = _core.LLVMIntPtrType(self.ptr);
return core.IntegerType(ptr, core.TYPE_INTEGER)
def size(self, ty):
core.check_is_type(ty)
return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr)
def store_size(self, ty):
core.check_is_type(ty)
return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr)
def abi_size(self, ty):
core.check_is_type(ty)
return _core.LLVMABISizeOfType(self.ptr, ty.ptr)
def abi_alignment(self, ty):
core.check_is_type(ty)
return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr)
def callframe_alignment(self, ty):
core.check_is_type(ty)
return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr)
def preferred_alignment(self, ty_or_gv):
if isinstance(ty_or_gv, core.Type):
return _core.LLVMPreferredAlignmentOfType(self.ptr,
ty_or_gv.ptr)
elif isinstance(ty_or_gv, core.GlobalVariable):
return _core.LLVMPreferredAlignmentOfGlobal(self.ptr,
ty_or_gv.ptr)
else:
raise core.LLVMException("argument is neither a type nor a global variable")
def element_at_offset(self, ty, ofs):
core.check_is_type_struct(ty)
ofs = int(ofs) # ofs is unsigned long long
return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs)
def offset_of_element(self, ty, el):
core.check_is_type_struct(ty)
el = int(el) # el should be an int
return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el)
#===----------------------------------------------------------------------===
# Misc.
#===----------------------------------------------------------------------===
# Intialize passes
PASSES = None