Added PassManagerBuilder.
Updated test/passes.py for PassManagerBuilder.
This commit is contained in:
parent
99c7a0736e
commit
6a02c36f04
8 changed files with 318 additions and 19 deletions
73
llvm/_core.c
73
llvm/_core.c
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
44
llvm/extra.h
44
llvm/extra.h
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
#===----------------------------------------------------------------------===
|
||||
|
|
|
|||
12
llvm/wrap.c
12
llvm/wrap.c
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue