Added PassManagerBuilder.

Updated test/passes.py for PassManagerBuilder.
This commit is contained in:
Siu Kwan Lam 2012-07-24 23:42:28 -07:00
commit 6a02c36f04
8 changed files with 318 additions and 19 deletions

View file

@ -842,6 +842,50 @@ _wLLVMCreateMemoryBufferWithSTDIN(PyObject *self, PyObject *args)
_wrap_obj2none(LLVMDisposeMemoryBuffer, LLVMMemoryBufferRef)
/*===----------------------------------------------------------------------===*/
/* Pass Manager Builder */
/*===----------------------------------------------------------------------===*/
_wrap_none2obj(LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderRef)
_wrap_obj2none(LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderRef)
_wrap_objint2none(LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderRef)
_wrap_obj2obj(LLVMPassManagerBuilderGetOptLevel, LLVMPassManagerBuilderRef, int)
_wrap_objint2none(LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderRef)
_wrap_obj2obj(LLVMPassManagerBuilderGetSizeLevel, LLVMPassManagerBuilderRef, int)
_wrap_objint2none(LLVMPassManagerBuilderSetVectorize, LLVMPassManagerBuilderRef)
_wrap_obj2obj(LLVMPassManagerBuilderGetVectorize, LLVMPassManagerBuilderRef, int)
_wrap_objint2none(LLVMPassManagerBuilderSetDisableUnitAtATime,
LLVMPassManagerBuilderRef)
_wrap_obj2obj(LLVMPassManagerBuilderGetDisableUnitAtATime,
LLVMPassManagerBuilderRef, int)
_wrap_objint2none(LLVMPassManagerBuilderSetDisableUnrollLoops,
LLVMPassManagerBuilderRef)
_wrap_obj2obj(LLVMPassManagerBuilderGetDisableUnrollLoops,
LLVMPassManagerBuilderRef, int)
_wrap_objint2none(LLVMPassManagerBuilderSetDisableSimplifyLibCalls,
LLVMPassManagerBuilderRef)
_wrap_obj2obj(LLVMPassManagerBuilderGetDisableSimplifyLibCalls,
LLVMPassManagerBuilderRef, int)
_wrap_objint2none(LLVMPassManagerBuilderUseInlinerWithThreshold,
LLVMPassManagerBuilderRef)
_wrap_objobj2none(LLVMPassManagerBuilderPopulateFunctionPassManager,
LLVMPassManagerBuilderRef,
LLVMPassManagerRef)
_wrap_objobj2none(LLVMPassManagerBuilderPopulateModulePassManager,
LLVMPassManagerBuilderRef,
LLVMPassManagerRef)
/*===----------------------------------------------------------------------===*/
/* Pass Manager */
/*===----------------------------------------------------------------------===*/
@ -1687,6 +1731,35 @@ static PyMethodDef core_methods[] = {
_method( LLVMCreateMemoryBufferWithSTDIN )
_method( LLVMDisposeMemoryBuffer )
/* Pass Manager Builder */
_method( LLVMPassManagerBuilderCreate )
_method( LLVMPassManagerBuilderDispose )
_method( LLVMPassManagerBuilderSetOptLevel )
_method( LLVMPassManagerBuilderGetOptLevel )
_method( LLVMPassManagerBuilderSetSizeLevel )
_method( LLVMPassManagerBuilderGetSizeLevel )
_method( LLVMPassManagerBuilderSetVectorize )
_method( LLVMPassManagerBuilderGetVectorize )
_method( LLVMPassManagerBuilderSetDisableUnitAtATime )
_method( LLVMPassManagerBuilderGetDisableUnitAtATime )
_method( LLVMPassManagerBuilderSetDisableUnrollLoops )
_method( LLVMPassManagerBuilderGetDisableUnrollLoops )
_method( LLVMPassManagerBuilderSetDisableSimplifyLibCalls )
_method( LLVMPassManagerBuilderGetDisableSimplifyLibCalls )
_method( LLVMPassManagerBuilderUseInlinerWithThreshold )
_method( LLVMPassManagerBuilderPopulateFunctionPassManager )
_method( LLVMPassManagerBuilderPopulateModulePassManager )
/* Pass Manager */
_method( LLVMCreatePassManager )
_method( LLVMCreateFunctionPassManagerForModule )

View file

@ -620,11 +620,7 @@ class Type(object):
@staticmethod
def __struct(element_tys, packed, name):
elems = unpack_types(element_tys)
if packed:
packed=1
else:
packed=0
packed = int(bool(packed))
if name: # create Identified StructType
objptr = _core.LLVMStructTypeIdentified(name)

View file

@ -76,8 +76,6 @@
// our includes
#include "extra.h"
//using namespace llvm;
/*
* For use in LLVMDumpPasses to dump passes.
*/
@ -106,6 +104,42 @@ char *do_print(W obj)
return strdup(buf.str().c_str());
}
int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb)
{
return llvm::unwrap(pmb)->OptLevel;
}
int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb)
{
return llvm::unwrap(pmb)->SizeLevel;
}
void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag)
{
llvm::unwrap(pmb)->Vectorize = flag;
}
int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb){
return llvm::unwrap(pmb)->Vectorize;
}
int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb)
{
return llvm::unwrap(pmb)->DisableUnitAtATime;
}
int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb)
{
return llvm::unwrap(pmb)->DisableUnrollLoops;
}
int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb)
{
return llvm::unwrap(pmb)->DisableSimplifyLibCalls;
}
int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name)
{
using namespace llvm;

View file

@ -37,22 +37,62 @@
#ifndef LLVM_PY_EXTRA_H
#define LLVM_PY_EXTRA_H
#include "llvm-c/Transforms/PassManagerBuilder.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Wraps PassManagerBuilder::OptLevel
*/
int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::SizeLevel
*/
int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::Vectorize
*/
void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag);
/*
* Wraps PassManagerBuilder::Vectorize
*/
int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::DisableUnitAtATime
*/
int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::DisableUnrollLoops
*/
int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManagerBuilder::DisableSimplifyLibCalls
*/
int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb);
/*
* Wraps PassManager::add
*/
int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name);
/*
* Wraps initialize*
*/
void LLVMInitializePasses();
void LLVMInitializePasses(void);
/*
* Wraps PassRegistry::enumerateWith()
* Returns a '\n' separated string of all passes available to `opt`.
*/
const char * LLVMDumpPasses();
const char * LLVMDumpPasses(void);
/*
* Wraps StructType::isLiteral()

View file

@ -40,6 +40,89 @@ import llvm.ee as ee # target data
import llvm.core as core # module, function etc.
import llvm._core as _core # C wrappers
#===----------------------------------------------------------------------===
# Pass manager builder
#===----------------------------------------------------------------------===
class PassManagerBuilder(object):
@staticmethod
def new():
return PassManagerBuilder(_core.LLVMPassManagerBuilderCreate())
def __init__(self, ptr):
self.ptr = ptr
def __del__(self):
_core.LLVMPassManagerBuilderDispose(self.ptr)
def populate(self, pm):
if isinstance(pm, FunctionPassManager):
return _core.LLVMPassManagerBuilderPopulateFunctionPassManager(
self.ptr, pm.ptr)
else:
return _core.LLVMPassManagerBuilderPopulateModulePassManager(
self.ptr, pm.ptr)
def _set_opt_level(self, optlevel):
_core.LLVMPassManagerBuilderSetOptLevel(self.ptr, optlevel)
def _get_opt_level(self):
return _core.LLVMPassManagerBuilderGetOptLevel(self.ptr)
opt_level = property(_get_opt_level, _set_opt_level)
def _set_size_level(self, sizelevel):
_core.LLVMPassManagerBuilderSetSizeLevel(self.ptr, sizelevel)
def _get_size_level(self):
return _core.LLVMPassManagerBuilderGetSizeLevel(self.ptr)
size_level = property(_get_size_level, _set_size_level)
def _set_vectorize(self, enable):
_core.LLVMPassManagerBuilderSetVectorize(self.ptr, int(bool(enable)))
def _get_vectorize(self):
return bool(_core.LLVMPassManagerBuilderGetVectorize(self.ptr))
vectorize = property(_get_vectorize, _set_vectorize)
def _set_disable_unit_at_a_time(self, disable):
return _core.LLVMPassManagerBuilderSetDisableUnitAtATime(
self.ptr, disable)
def _get_disable_unit_at_a_time(self):
return _core.LLVMPassManagerBuilderGetDisableUnitAtATime(
self.ptr)
disable_unit_at_a_time = property(_get_disable_unit_at_a_time,
_set_disable_unit_at_a_time)
def _set_disable_unroll_loops(self, disable):
return _core.LLVMPassManagerBuilderGetDisableUnrollLoops(
self.ptr, disable)
def _get_disable_unroll_loops(self):
return _core.LLVMPassManagerBuilderGetDisableUnrollLoops(self.ptr)
disable_unroll_loops = property(_get_disable_unroll_loops,
_set_disable_unroll_loops)
def _set_disable_simplify_lib_calls(self, disable):
return _core.LLVMPassManagerBuilderGetDisableSimplifyLibCalls(
self.ptr, disable)
def _get_disable_simplify_lib_calls(self):
return _core.LLVMPassManagerBuilderGetDisableSimplifyLibCalls(self.ptr)
disable_simplify_lib_calls = property(_get_disable_simplify_lib_calls,
_set_disable_simplify_lib_calls)
def use_inliner_with_threshold(self, threshold):
_core.LLVMPassManagerBuilderUseInlinerWithThreshold(self.ptr, threshold)
#===----------------------------------------------------------------------===
# Pass manager
#===----------------------------------------------------------------------===

View file

@ -11,7 +11,7 @@
* 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
* * 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.
*
@ -31,7 +31,7 @@
#include "wrap.h"
/* Project-wide setting */
#if (PY_MAJOR_VERSION >= 3)
#if (PY_MAJOR_VERSION >= 3)
#define LLVM_PY_USE_PYCAPSULE
#endif
@ -39,7 +39,7 @@
/* Helper functions/macros */
/*===----------------------------------------------------------------------===*/
#ifdef LLVM_PY_USE_PYCAPSULE
#ifdef LLVM_PY_USE_PYCAPSULE
#define _define_std_ctor(typ) \
PyObject * ctor_ ## typ ( typ p) \
@ -76,6 +76,8 @@ _define_std_ctor(LLVMExecutionEngineRef)
_define_std_ctor(LLVMTargetDataRef)
_define_std_ctor(LLVMGenericValueRef)
_define_std_ctor(LLVMPassManagerBuilderRef)
PyObject *ctor_int(int i)
{
return PyLong_FromLong((long)i);
@ -108,7 +110,7 @@ void **make_array_from_list(PyObject *list, int n)
{
int i;
void **arr;
arr = (void **)malloc(sizeof(void *) * n);
if (!arr)
return NULL;
@ -121,7 +123,7 @@ void **make_array_from_list(PyObject *list, int n)
arr[i] = PyCObject_AsVoidPtr(e);
#endif
}
return arr;
}

View file

@ -45,6 +45,10 @@
#include "llvm-c/Analysis.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Target.h"
// workaround missing bool type
#define bool int
#include "llvm-c/Transforms/PassManagerBuilder.h"
#undef bool
/* Project-wide setting */
#if PY_MAJOR_VERSION >= 3
@ -58,6 +62,7 @@
typedef unsigned long long llvmwrap_ull;
/*===----------------------------------------------------------------------===*/
/* Type ctor/dtor */
/*===----------------------------------------------------------------------===*/
@ -83,6 +88,9 @@ _declare_std_ctor(LLVMExecutionEngineRef)
_declare_std_ctor(LLVMTargetDataRef)
_declare_std_ctor(LLVMGenericValueRef)
// extra LLVM class not defined in LLVM-C
_declare_std_ctor(LLVMPassManagerBuilderRef)
/* standard types */
_declare_std_ctor(int)
_declare_std_ctor(llvmwrap_ull)

View file

@ -9,11 +9,11 @@ from StringIO import StringIO
import logging, unittest
# A helper class.
class strstream(object):
def __init__(self, s):
self.s = s
def read(self):
return self.s
#class strstream(object):
# def __init__(self, s):
# self.s = s
# def read(self):
# return self.s
# Create a module.
asm = """
@ -100,9 +100,72 @@ class TestPasses(unittest.TestCase):
# Make sure test1 is modified
self.assertNotEqual(str(fn_test1).strip(), original_test1.strip())
def test_passes_with_pmb(self):
m = Module.from_assembly(StringIO(asm))
logging.debug("-"*72)
logging.debug(m)
fn_test1 = m.get_function_named('test1')
fn_test2 = m.get_function_named('test2')
original_test1 = str(fn_test1)
original_test2 = str(fn_test2)
# Try out the PassManagerBuilder
pmb = PassManagerBuilder.new()
self.assertEqual(pmb.opt_level, 2) # ensure default is level 2
pmb.opt_level = 3
self.assertEqual(pmb.opt_level, 3) # make sure it works
self.assertEqual(pmb.size_level, 0) # ensure default is level 0
pmb.size_level = 2
self.assertEqual(pmb.size_level, 2) # make sure it works
self.assertFalse(pmb.vectorize) # ensure default is False
pmb.vectorize = True
self.assertTrue(pmb.vectorize) # make sure it works
# make sure the default is False
self.assertFalse(pmb.disable_unit_at_a_time)
self.assertFalse(pmb.disable_unroll_loops)
self.assertFalse(pmb.disable_simplify_lib_calls)
# Do function pass
fpm = FunctionPassManager.new(m)
pmb.populate(fpm)
fpm.run(fn_test1)
# Print the result. Note the change in @test1.
logging.debug("-"*72)
logging.debug(m)
# Make sure test1 has changed
self.assertNotEqual(str(fn_test1).strip(), original_test1.strip())
# Do module pass
pm = PassManager.new()
pmb.populate(pm)
pm.run(m)
# Print the result. Note the change in @test2.
logging.debug("-"*72)
logging.debug(m)
# Make sure test2 has changed
self.assertNotEqual(str(fn_test2).strip(), original_test2.strip())
def test_dump_passes(self):
self.assertTrue(len(PASSES)>0, msg="Cannot have no passes")
if __name__ == '__main__':
unittest.main()