add support for metadata.
add related test.
This commit is contained in:
parent
78cde30883
commit
82117d899e
6 changed files with 113 additions and 5 deletions
|
|
@ -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 )
|
||||
|
|
|
|||
14
llvm/core.py
14
llvm/core.py
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
16
llvm/extra.h
16
llvm/extra.h
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
26
llvm/wrap.h
26
llvm/wrap.h
|
|
@ -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
28
test/metadata.py
Normal 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()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue