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

View file

@ -1427,6 +1427,17 @@ class Function(GlobalValue):
# failure, it appears to print result to stderr and abort. # failure, it appears to print result to stderr and abort.
return _core.LLVMVerifyFunction(self.ptr) != 0 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 # Instruction
#===----------------------------------------------------------------------=== #===----------------------------------------------------------------------===
@ -1477,6 +1488,9 @@ class Instruction(User):
def set_volatile(self, flag): def set_volatile(self, flag):
return _core.LLVMSetVolatile(self.ptr, int(bool(flag))) return _core.LLVMSetVolatile(self.ptr, int(bool(flag)))
def set_metadata(self, kind, metadata):
return _core.LLVMInstSetMetaData(self.ptr, kind, metadata.ptr)
@property @property
def opcode(self): def opcode(self):
return _core.LLVMInstGetOpcode(self.ptr) return _core.LLVMInstGetOpcode(self.ptr)

View file

@ -83,11 +83,11 @@
#include "extra.h" #include "extra.h"
#include "llvm_c_extra.h" #include "llvm_c_extra.h"
namespace llvm{ namespace llvm{
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
} }
/* /*
* For use in LLVMDumpPasses to dump passes. * For use in LLVMDumpPasses to dump passes.
*/ */
@ -127,7 +127,27 @@ const CodeGenOpt::Level OptLevelMap[] = {
} // end anony namespace } // 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) const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst)
{ {

View file

@ -53,15 +53,25 @@
extern "C" { extern "C" {
#endif #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); const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst);
/* /*
* Wraps ConstantExpr::getOpcode(); * Wraps ConstantExpr::getOpcode()
*/ */
unsigned LLVMGetConstExprOpcode(LLVMValueRef inst); unsigned LLVMGetConstExprOpcode(LLVMValueRef inst);

View file

@ -635,6 +635,30 @@ _w ## func (PyObject *self, PyObject *args) \
return ctor_ ## outtype ( func (arg1, arg2, arg3)); \ 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 * Wrap LLVM functions of the type

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()