add support for metadata.

add related test.
This commit is contained in:
Siu Kwan Lam 2012-09-06 15:47:23 -07:00
commit 82117d899e
6 changed files with 113 additions and 5 deletions

View file

@ -618,6 +618,11 @@ _wrap_objstr2obj(LLVMAppendBasicBlock, LLVMValueRef, LLVMBasicBlockRef)
_wrap_objstr2obj(LLVMInsertBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef)
_wrap_obj2none(LLVMDeleteBasicBlock, LLVMBasicBlockRef)
/*===-- MetaData -----------------------------------------------------===*/
_wrap_objlist2obj(LLVMMetaDataGet, LLVMModuleRef, LLVMValueRef, LLVMValueRef)
/*===-- Instructions -----------------------------------------------------===*/
_wrap_obj2obj(LLVMGetInstructionParent, LLVMValueRef, LLVMBasicBlockRef)
@ -636,6 +641,8 @@ _wrap_objint2none(LLVMSetVolatile, LLVMValueRef)
_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int)
_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef)
_wrap_objstrobj2none(LLVMInstSetMetaData, LLVMValueRef, LLVMValueRef)
/*===-- Call Sites (Call or Invoke) --------------------------------------===*/
_wrap_objint2none(LLVMSetInstructionCallConv, LLVMValueRef)
@ -1691,6 +1698,9 @@ static PyMethodDef core_methods[] = {
_method( LLVMInsertBasicBlock )
_method( LLVMDeleteBasicBlock )
/* MetaData */
_method( LLVMMetaDataGet )
/* Instructions */
_method( LLVMGetInstructionParent )
_method( LLVMGetFirstInstruction )
@ -1708,6 +1718,8 @@ static PyMethodDef core_methods[] = {
_method( LLVMInstGetOpcode )
_method( LLVMInstGetOpcodeName )
_method( LLVMInstSetMetaData )
/* Call Sites (Call or Invoke) */
_method( LLVMSetInstructionCallConv )
_method( LLVMGetInstructionCallConv )

View file

@ -1427,6 +1427,17 @@ class Function(GlobalValue):
# failure, it appears to print result to stderr and abort.
return _core.LLVMVerifyFunction(self.ptr) != 0
#===----------------------------------------------------------------------===
# MetaData
#===----------------------------------------------------------------------===
class MetaData(Value):
@staticmethod
def get(module, values):
vs = unpack_values(values)
ptr = _core.LLVMMetaDataGet(module.ptr, vs)
return MetaData(ptr)
#===----------------------------------------------------------------------===
# Instruction
#===----------------------------------------------------------------------===
@ -1477,6 +1488,9 @@ class Instruction(User):
def set_volatile(self, flag):
return _core.LLVMSetVolatile(self.ptr, int(bool(flag)))
def set_metadata(self, kind, metadata):
return _core.LLVMInstSetMetaData(self.ptr, kind, metadata.ptr)
@property
def opcode(self):
return _core.LLVMInstGetOpcode(self.ptr)

View file

@ -83,11 +83,11 @@
#include "extra.h"
#include "llvm_c_extra.h"
namespace llvm{
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
}
/*
* For use in LLVMDumpPasses to dump passes.
*/
@ -127,7 +127,27 @@ const CodeGenOpt::Level OptLevelMap[] = {
} // end anony namespace
void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind,
LLVMValueRef metaref)
{
using namespace llvm;
unwrap<Instruction>(instref)->setMetadata(mdkind, unwrap<MDNode>(metaref));
}
LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs,
unsigned valct)
{
using namespace llvm;
LLVMContext & context = unwrap(modref)->getContext();
std::vector<Value*> vals;
vals.reserve(valct);
for(unsigned i = 0; i < valct; ++i ){
vals.push_back(unwrap(valrefs[i]));
}
MDNode * const node = MDNode::get(context, vals);
return wrap(node);
}
const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst)
{

View file

@ -53,15 +53,25 @@
extern "C" {
#endif
/*
* Wraps Instruction::setMetadata()
*/
void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind,
LLVMValueRef metaref);
/*
* Wraps ConstantExpr::getOpcodeName();
* Wraps MDNode::get()
*/
LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs,
unsigned valct);
/*
* Wraps ConstantExpr::getOpcodeName()
*/
const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst);
/*
* Wraps ConstantExpr::getOpcode();
* Wraps ConstantExpr::getOpcode()
*/
unsigned LLVMGetConstExprOpcode(LLVMValueRef inst);

View file

@ -635,6 +635,30 @@ _w ## func (PyObject *self, PyObject *args) \
return ctor_ ## outtype ( func (arg1, arg2, arg3)); \
}
/**
* Wrap LLVM functions of the type
* void func(intype1 arg1, const char *arg2, intype3 arg3)
*/
#define _wrap_objstrobj2none(func, intype1, intype3) \
static PyObject * \
_w ## func (PyObject *self, PyObject *args) \
{ \
PyObject *obj1, *obj3; \
intype1 arg1; \
const char *arg2; \
intype3 arg3; \
\
if (!PyArg_ParseTuple(args, "OsO", &obj1, &arg2, &obj3)) \
return NULL; \
\
arg1 = ( intype1 ) PyCapsule_GetPointer(obj1, NULL); \
arg3 = ( intype3 ) PyCapsule_GetPointer(obj3, NULL); \
\
func(arg1, arg2, arg3); \
\
Py_RETURN_NONE; \
}
/**
* Wrap LLVM functions of the type
@ -660,7 +684,7 @@ _w ## func (PyObject *self, PyObject *args) \
}
/**
* Wrap LLVM functions of the type
* Wrap LLVM functions of the type
* outtype func(intype1 arg1, intype2 arg2, intype3, int arg3, const char *arg4)
*/
#define _wrap_objobjobjintstr2obj(func, intype1, intype2, intype3, outtype) \

28
test/metadata.py Normal file
View file

@ -0,0 +1,28 @@
import unittest
from llvm.core import *
class TestMetaData(unittest.TestCase):
def test_metadata_get(self):
module = Module.new('test_metadata')
md = MetaData.get(module, [Constant.int(Type.int(), 1234)])
def test_meta_load_nt(self):
module = Module.new('test_meta_load_nt')
func = module.add_function(Type.function(Type.void(), []),
name='test_load_nt')
bldr = Builder.new(func.append_basic_block('entry'))
addr = Constant.int(Type.int(), 0xdeadbeef)
loadinst = bldr.load(bldr.inttoptr(addr, Type.pointer(Type.int(8))))
md = MetaData.get(module, [Constant.int(Type.int(), 1)])
loadinst.set_metadata('nontemporal', md)
bldr.ret_void()
module.verify()
self.assertIn('!nontemporal', str(loadinst))
if __name__ == '__main__':
unittest.main()