Code cleanup.

git-svn-id: http://llvm-py.googlecode.com/svn/trunk@47 8d1e9007-1d4e-0410-b67e-1979fd6579aa
This commit is contained in:
mdevan.foobar 2008-11-17 16:45:40 +00:00
commit b52355d84e
11 changed files with 588 additions and 212 deletions

View file

@ -1,6 +1,7 @@
0.4, in progress:
* Code cleanup, added license headers.
* Added llvm.core.load_library_permanently() (Issue #12).
* Fix comparison using != (Issue #11).
* Instruction.is_terminator added.

View file

@ -1,3 +1,33 @@
#
# Copyright (c) 2008, Mahadevan R All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# 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
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Common classes related to LLVM.
"""

View file

@ -1,3 +1,32 @@
/*
* Copyright (c) 2008, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* 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
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* our includes */
#include "wrap.h"
@ -427,13 +456,11 @@ _wrap_obj2none(LLVMViewFunctionCFGOnly, LLVMValueRef)
static PyObject *
_wLLVMVerifyFunction(PyObject *self, PyObject *args)
{
PyObject *obj;
LLVMValueRef fn;
if (!PyArg_ParseTuple(args, "O", &obj))
if (!(fn = (LLVMValueRef)get_object_arg(args)))
return NULL;
fn = (LLVMValueRef) PyCObject_AsVoidPtr(obj);
return ctor_int(LLVMVerifyFunction(fn, LLVMReturnStatusAction));
}
@ -473,8 +500,8 @@ _wrap_obj2obj(LLVMInstIsArithmeticShift, LLVMValueRef, int)
_wrap_obj2obj(LLVMInstIsAssociative, LLVMValueRef, int)
_wrap_obj2obj(LLVMInstIsCommutative, LLVMValueRef, int)
_wrap_obj2obj(LLVMInstIsTrapping, LLVMValueRef, int)
_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int)
_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef)
_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int)
_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef)
/*===-- Call Sites (Call or Invoke) --------------------------------------===*/
@ -493,7 +520,7 @@ static void LLVMAddIncoming1(LLVMValueRef PhiNode, LLVMValueRef IncomingValue, L
}
_wrap_objobjobj2none(LLVMAddIncoming1, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef)
_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int)
_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int)
_wrap_objint2obj(LLVMGetIncomingValue, LLVMValueRef, LLVMValueRef)
_wrap_objint2obj(LLVMGetIncomingBlock, LLVMValueRef, LLVMBasicBlockRef)
@ -766,15 +793,13 @@ _wrap_obj2none(LLVMDisposeTargetData, LLVMTargetDataRef)
static PyObject *
_wLLVMTargetDataAsString(PyObject *self, PyObject *args)
{
PyObject *obj;
LLVMTargetDataRef td;
char *tdrep = 0;
PyObject *ret;
if (!PyArg_ParseTuple(args, "O", &obj))
if (!(td = (LLVMTargetDataRef)get_object_arg(args)))
return NULL;
td = (LLVMTargetDataRef) PyCObject_AsVoidPtr(obj);
tdrep = LLVMCopyStringRepOfTargetData(td);
ret = PyString_FromString(tdrep);
LLVMDisposeMessage(tdrep);

View file

@ -1,3 +1,33 @@
#
# Copyright (c) 2008, Mahadevan R All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# 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
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Utility functions and classes.
Used only in other modules, not for public use."""

View file

@ -1,3 +1,33 @@
#
# Copyright (c) 2008, Mahadevan R All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# 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
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Core classes of LLVM.
The llvm.core module contains classes and constants required to build the
@ -880,6 +910,8 @@ class Module(llvm.Ownable):
return Function.get(self, name)
def get_or_insert_function(self, ty, name):
"""Like get_function_named(), but does add_function() first, if
function is not present."""
return Function.get_or_insert(self, ty, name)
@property
@ -1143,6 +1175,7 @@ class FunctionType(Type):
class StructType(Type):
"""Represents a structure type."""
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.
@ -1152,19 +1185,26 @@ class StructType(Type):
@property
def element_count(self):
"""Number of elements (members) in the structure.
Same as len(obj.elements), but faster."""
return _core.LLVMCountStructElementTypes(self.ptr)
@property
def elements(self):
"""An iterable that yieldsd Type objects, representing the types of the
elements (members) of the structure, in order."""
pp = _core.LLVMGetStructElementTypes(self.ptr)
return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ]
@property
def packed(self):
"""True if the structure is packed, False otherwise."""
return _core.LLVMIsPackedStruct(self.ptr) != 0
class ArrayType(Type):
"""Represents an array type."""
def __init__(self, ptr, kind):
"""DO NOT CALL DIRECTLY.

View file

@ -1,3 +1,33 @@
#
# Copyright (c) 2008, Mahadevan R All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# 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
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Execution Engine and related classes.
"""

View file

@ -1,14 +1,46 @@
/*
* Copyright (c) 2008, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* 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
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* These are some "extra" functions not available in the standard LLVM-C
* bindings, but are required / good-to-have inorder to implement the
* Python bindings.
*/
// standard includes
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
// LLVM includes
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Constants.h"
@ -22,202 +54,271 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/System/DynamicLibrary.h"
// +includes for passes
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Instrumentation.h"
// -includes for passes
// LLVM-C includes
#include "llvm-c/Core.h"
// our includes
#include "extra.h"
using namespace llvm;
//using namespace llvm;
char *LLVMDumpModuleToString(LLVMModuleRef M) {
std::ostringstream buf;
unwrap(M)->print(buf);
return strdup(buf.str().c_str());
}
char *LLVMDumpTypeToString(LLVMTypeRef Ty) {
std::ostringstream buf;
unwrap(Ty)->print(buf);
return strdup(buf.str().c_str());
}
char *LLVMDumpValueToString(LLVMValueRef Val) {
std::ostringstream buf;
unwrap(Val)->print(buf);
return strdup(buf.str().c_str());
}
#if 0 /* after LLVM 2.3! */
LLVMValueRef LLVMConstVICmp(LLVMIntPredicate Predicate,
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getVICmp(Predicate,
unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
}
LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate Predicate,
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getVFCmp(Predicate,
unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
}
LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef B, LLVMIntPredicate Op,
LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name) {
return wrap(unwrap(B)->CreateVICmp(static_cast<ICmpInst::Predicate>(Op),
unwrap(LHS), unwrap(RHS), Name));
}
LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef B, LLVMRealPredicate Op,
LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name) {
return wrap(unwrap(B)->CreateVFCmp(static_cast<FCmpInst::Predicate>(Op),
unwrap(LHS), unwrap(RHS), Name));
}
#endif
unsigned LLVMModuleGetPointerSize(LLVMModuleRef M)
/* Helper method for LLVMDumpXXXToString() methods. */
template <typename W, typename UW>
char *do_print(W obj)
{
Module::PointerSize p = unwrap(M)->getPointerSize();
if (p == Module::Pointer32)
std::ostringstream buf;
UW *p = llvm::unwrap(obj);
assert(p);
p->print(buf);
return strdup(buf.str().c_str());
}
char *LLVMDumpModuleToString(LLVMModuleRef module)
{
return do_print<LLVMModuleRef, llvm::Module>(module);
}
char *LLVMDumpTypeToString(LLVMTypeRef type)
{
return do_print<LLVMTypeRef, llvm::Type>(type);
}
char *LLVMDumpValueToString(LLVMValueRef value)
{
return do_print<LLVMValueRef, llvm::Value>(value);
}
unsigned LLVMModuleGetPointerSize(LLVMModuleRef module)
{
llvm::Module *modulep = llvm::unwrap(module);
assert(modulep);
llvm::Module::PointerSize p = modulep->getPointerSize();
if (p == llvm::Module::Pointer32)
return 32;
else if (p == Module::Pointer64)
else if (p == llvm::Module::Pointer64)
return 64;
return 0;
}
LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef M,
const char *Name, LLVMTypeRef FunctionTy)
LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module,
const char *name, LLVMTypeRef function_type)
{
FunctionType *ft = unwrap<FunctionType>(FunctionTy);
Constant *f = unwrap(M)->getOrInsertFunction(Name, ft);
assert(name);
llvm::Module *modulep = llvm::unwrap(module);
assert(modulep);
llvm::FunctionType *ftp = llvm::unwrap<llvm::FunctionType>(function_type);
assert(ftp);
llvm::Constant *f = modulep->getOrInsertFunction(name, ftp);
return wrap(f);
}
#define inst_checkfn(ourfn, llvmfn) \
unsigned ourfn (LLVMValueRef I) { \
return unwrap<Instruction>(I)-> llvmfn () ? 1 : 0; \
#define inst_checkfn(ourfn, llvmfn) \
unsigned ourfn (LLVMValueRef v) { \
llvm::Instruction *ip = llvm::unwrap<llvm::Instruction>(v); \
assert(ip); \
return ip-> llvmfn () ? 1 : 0; \
}
inst_checkfn(LLVMInstIsTerminator, isTerminator)
inst_checkfn(LLVMInstIsBinaryOp, isBinaryOp)
inst_checkfn(LLVMInstIsShift, isShift)
inst_checkfn(LLVMInstIsCast, isCast)
inst_checkfn(LLVMInstIsLogicalShift, isLogicalShift)
inst_checkfn(LLVMInstIsArithmeticShift, isArithmeticShift)
inst_checkfn(LLVMInstIsAssociative, isAssociative)
inst_checkfn(LLVMInstIsCommutative, isCommutative)
inst_checkfn(LLVMInstIsTrapping, isTrapping)
const char *LLVMInstGetOpcodeName(LLVMValueRef inst)
{
llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
assert(instp);
return instp->getOpcodeName();
}
unsigned LLVMInstGetOpcode(LLVMValueRef inst)
{
llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
assert(instp);
return instp->getOpcode();
}
/* llvm::unwrap a set of `n' wrapped objects starting at `values',
* into a vector of pointers to llvm::unwrapped objects `out'. */
template <typename W, typename UW>
void unwrap_vec(W *values, unsigned n, std::vector<UW *>& out)
{
out.clear();
while (n--) {
UW *p = llvm::unwrap(*values);
assert(p);
out.push_back(p);
++values;
}
}
inst_checkfn(LLVMInstIsTerminator, isTerminator)
inst_checkfn(LLVMInstIsBinaryOp, isBinaryOp)
inst_checkfn(LLVMInstIsShift, isShift)
inst_checkfn(LLVMInstIsCast, isCast)
inst_checkfn(LLVMInstIsLogicalShift,isLogicalShift)
inst_checkfn(LLVMInstIsArithmeticShift,isArithmeticShift)
inst_checkfn(LLVMInstIsAssociative, isAssociative)
inst_checkfn(LLVMInstIsCommutative, isCommutative)
inst_checkfn(LLVMInstIsTrapping, isTrapping)
const char *LLVMInstGetOpcodeName(LLVMValueRef I)
/* Same as llvm::unwrap_vec, but use a vector of const pointers. */
template <typename W, typename UW>
void unwrap_cvec(W *values, unsigned n, std::vector<const UW *>& out)
{
return unwrap<Instruction>(I)->getOpcodeName();
out.clear();
while (n--) {
UW *p = llvm::unwrap(*values);
assert(p);
out.push_back(p);
++values;
}
}
unsigned LLVMInstGetOpcode(LLVMValueRef I)
LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef builder,
LLVMValueRef *values, unsigned n_values)
{
return unwrap<Instruction>(I)->getOpcode();
assert(values);
std::vector<llvm::Value *> values_vec;
unwrap_vec(values, n_values, values_vec);
llvm::IRBuilder *builderp = llvm::unwrap(builder);
assert(builderp);
return wrap(builderp->CreateRet(&values_vec[0], values_vec.size()));
}
LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef B, LLVMValueRef *Values,
unsigned NumValues) {
std::vector<Value *> Vs;
for (LLVMValueRef *I = Values, *E = Values + NumValues; I != E; ++I)
Vs.push_back(unwrap(*I));
return wrap(unwrap(B)->CreateRet(&Vs[0], NumValues));
}
LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef B, LLVMValueRef V,
unsigned Index, const char *Name) {
return wrap(unwrap(B)->CreateGetResult(unwrap(V), Index, Name));
}
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef M, int ID,
LLVMTypeRef *Types, unsigned Count)
LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder,
LLVMValueRef value, unsigned index, const char *name)
{
std::vector<const Type*> Tys;
for (LLVMTypeRef *I = Types, *E = Types + Count; I != E; ++I)
Tys.push_back(unwrap(*I));
Function *intfunc = Intrinsic::getDeclaration(unwrap(M),
Intrinsic::ID(ID), &Tys[0], Count);
assert(name);
llvm::IRBuilder *builderp = llvm::unwrap(builder);
assert(builderp);
return wrap(builderp->CreateGetResult(llvm::unwrap(value), index, name));
}
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id,
LLVMTypeRef *types, unsigned n_types)
{
assert(types);
std::vector<const llvm::Type*> types_vec;
unwrap_cvec(types, n_types, types_vec);
llvm::Module *modulep = llvm::unwrap(module);
assert(modulep);
llvm::Function *intfunc = llvm::Intrinsic::getDeclaration(modulep,
llvm::Intrinsic::ID(id), &types_vec[0], types_vec.size());
return wrap(intfunc);
}
LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len,
char **OutMessage)
LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtext, unsigned txtlen,
char **out)
{
ParseError e;
assert(asmtext);
assert(out);
Module *MP = ParseAssemblyString(A, NULL /*unused within!*/, &e);
if (!MP) {
*OutMessage = strdup(e.getMessage().c_str());
llvm::Module *modulep;
llvm::ParseError error;
if (!(modulep = llvm::ParseAssemblyString(asmtext, NULL /*unused within!*/,
&error))) {
*out = strdup(error.getMessage().c_str());
return NULL;
}
return wrap(MP);
return wrap(modulep);
}
LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len,
char **OutMessage)
LLVMModuleRef LLVMGetModuleFromBitcode(const char *bitcode, unsigned bclen,
char **out)
{
MemoryBuffer *mb = MemoryBuffer::getMemBufferCopy(BC, BC+Len);
if (!mb)
assert(bitcode);
assert(out);
llvm::MemoryBuffer *mbp;
if (!(mbp = llvm::MemoryBuffer::getMemBufferCopy(bitcode, bitcode+bclen)))
return NULL;
std::string msg;
LLVMModuleRef mr = wrap(ParseBitcodeFile(mb, &msg));
if (!mr)
*OutMessage = strdup(msg.c_str());
llvm::Module *modulep;
if (!(modulep = llvm::ParseBitcodeFile(mbp, &msg)))
*out = strdup(msg.c_str());
delete mb;
return mr;
delete mbp;
return wrap(modulep);
}
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len)
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *lenp)
{
assert(lenp);
llvm::Module *modulep = llvm::unwrap(module);
assert(modulep);
/* get bc into a string */
std::ostringstream buf;
WriteBitcodeToFile(unwrap(M), buf);
const std::string& s = buf.str();
size_t len = s.size();
unsigned char *bytes = (unsigned char *)malloc(len);
llvm::WriteBitcodeToFile(modulep, buf);
const std::string& bc = buf.str();
/* and then into a malloc()-ed block */
size_t bclen = bc.size();
unsigned char *bytes = (unsigned char *)malloc(bclen);
if (!bytes)
return NULL;
memcpy(bytes, s.data(), len);
*Len = len;
memcpy(bytes, bc.data(), bclen);
/* return */
*lenp = bclen;
return bytes;
}
/* Return 0 on failure (with ErrMsg filled in), 1 on success. */
unsigned LLVMLoadLibraryPermanently(const char* filename, char **ErrMsg)
/* Return 0 on failure (with errmsg filled in), 1 on success. */
unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg)
{
std::string msg;
assert(filename);
assert(errmsg);
/* Note: the LLVM API returns true on failure. Don't ask why. */
if (sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) {
*ErrMsg = strdup(msg.c_str());
std::string msg;
if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) {
*errmsg = strdup(msg.c_str());
return 0;
}
return 1;
}
/* passes */
#define define_pass(P) \
void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM) { \
unwrap(PM)->add( create ## P ## Pass ()); \
/* Passes. A few passes (listed below) are used directly from LLVM-C,
* rest are defined here.
*
* ConstantPropagation
* GVN
* InstructionCombining
* PromoteMemoryToRegister
* Reassociate
* CFGSimplification
*/
#define define_pass(P) \
void LLVMAdd ## P ## Pass (LLVMPassManagerRef passmgr) { \
using namespace llvm; \
llvm::PassManagerBase *pmp = llvm::unwrap(passmgr); \
assert(pmp); \
pmp->add( create ## P ## Pass ()); \
}
define_pass( AggressiveDCE )
@ -227,7 +328,6 @@ define_pass( BreakCriticalEdges )
define_pass( CodeGenPrepare )
define_pass( CondPropagation )
define_pass( ConstantMerge )
//LLVM-C define_pass( ConstantPropagation )
define_pass( DeadCodeElimination )
define_pass( DeadArgElimination )
define_pass( DeadTypeElimination )
@ -236,7 +336,6 @@ define_pass( DeadStoreElimination )
define_pass( GCSE )
define_pass( GlobalDCE )
define_pass( GlobalOptimizer )
//LLVM-C define_pass( GVN )
define_pass( GVNPRE )
define_pass( IndMemRem )
define_pass( IndVarSimplify )
@ -246,9 +345,8 @@ define_pass( EdgeProfiler )
define_pass( FunctionProfiler )
define_pass( NullProfilerRS )
define_pass( RSProfiling )
//LLVM-C define_pass( InstructionCombining )
/* we support only internalize(true) */
ModulePass *createInternalizePass() { return llvm::createInternalizePass(true); }
llvm::ModulePass *createInternalizePass() { return llvm::createInternalizePass(true); }
define_pass( Internalize )
define_pass( IPConstantPropagation )
define_pass( IPSCCP )
@ -268,18 +366,15 @@ define_pass( LowerAllocations )
define_pass( LowerInvoke )
define_pass( LowerSetJmp )
define_pass( LowerSwitch )
//LLVM-C define_pass( PromoteMemoryToRegister )
define_pass( MemCpyOpt )
define_pass( UnifyFunctionExitNodes )
define_pass( PredicateSimplifier )
define_pass( PruneEH )
define_pass( RaiseAllocations )
//LLVM-C define_pass( Reassociate )
define_pass( DemoteRegisterToMemory )
define_pass( ScalarReplAggregates )
define_pass( SCCP )
define_pass( SimplifyLibCalls )
//LLVM-C define_pass( CFGSimplification )
define_pass( StripSymbols )
define_pass( StripDeadPrototypes )
define_pass( StructRetPromotion )

View file

@ -1,3 +1,33 @@
/*
* Copyright (c) 2008, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* 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
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* These are some "extra" functions not available in the standard LLVM-C
* bindings, but are required / good-to-have inorder to implement the
@ -11,81 +41,92 @@
extern "C" {
#endif
/** Dumps module contents to a string. See Module::print. Free the
returned string with LLVMDisposeMessage, after use. */
char *LLVMDumpModuleToString(LLVMModuleRef M);
/* Notes:
* - Some returned strings must be disposed of by LLVMDisposeMessage. These are
* indicated in the comments. Where it is not indicated, DO NOT call dispose.
*/
/** Dumps type to a string. See Type::print. Free the returned string with
LLVMDisposeMessage, after use. */
char *LLVMDumpTypeToString(LLVMTypeRef Ty);
/* Wraps llvm::Module::print(). Dispose the returned string after use, via
* LLVMDisposeMessage(). */
char *LLVMDumpModuleToString(LLVMModuleRef module);
/** Dumps value to a string. See Value::print. Free the returned string with
LLVMDisposeMessage, after use. */
/* Wraps llvm::Type::print(). Dispose the returned string after use, via
* LLVMDisposeMessage(). */
char *LLVMDumpTypeToString(LLVMTypeRef type);
/* Wraps llvm::Value::print(). Dispose the returned string after use, via
* LLVMDisposeMessage(). */
char *LLVMDumpValueToString(LLVMValueRef Val);
/* missing constant expressions */
/* Wraps llvm::IRBuilder::CreateRet(). */
LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values,
unsigned n_values);
#if 0 /* after LLVM 2.3! */
LLVMValueRef LLVMConstVICmp(LLVMIntPredicate Predicate,
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate Predicate,
LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
/* Wraps llvm::IRBuilder::CreateGetResult(). */
LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value,
unsigned index, const char *name);
/* missing instructions */
/* Wraps llvm::Intrinsic::getDeclaration(). */
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef builder, int id,
LLVMTypeRef *types, unsigned n_types);
LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef, LLVMIntPredicate Op,
LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef, LLVMRealPredicate Op,
LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
#endif
/* Wraps llvm::Module::getPointerSize(). */
unsigned LLVMModuleGetPointerSize(LLVMModuleRef module);
LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef, LLVMValueRef *Values,
unsigned NumValues);
LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef, LLVMValueRef V,
unsigned Index, const char *Name);
/* Wraps llvm::Module::getOrInsertFunction(). */
LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module,
const char *name, LLVMTypeRef function_type);
/* intrinsics */
/* The following functions wrap various llvm::Instruction::isXXX() functions.
* All of them take an instruction and return 0 (isXXX returned false) or 1
* (isXXX returned false). */
unsigned LLVMInstIsTerminator (LLVMValueRef inst);
unsigned LLVMInstIsBinaryOp (LLVMValueRef inst);
unsigned LLVMInstIsShift (LLVMValueRef inst);
unsigned LLVMInstIsCast (LLVMValueRef inst);
unsigned LLVMInstIsLogicalShift (LLVMValueRef inst);
unsigned LLVMInstIsArithmeticShift (LLVMValueRef inst);
unsigned LLVMInstIsAssociative (LLVMValueRef inst);
unsigned LLVMInstIsCommutative (LLVMValueRef inst);
unsigned LLVMInstIsTrapping (LLVMValueRef inst);
LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef B, int ID,
LLVMTypeRef *Types, unsigned Count);
/* Wraps llvm::Instruction::getOpcodeName(). */
const char *LLVMInstGetOpcodeName(LLVMValueRef inst);
/* module */
/* Wraps llvm::Instruction::getOpcode(). */
unsigned LLVMInstGetOpcode(LLVMValueRef inst);
unsigned LLVMModuleGetPointerSize(LLVMModuleRef M);
LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef M,
const char *Name, LLVMTypeRef FunctionTy);
/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with
* `out' pointing to an error message). Dispose error message after use, via
* LLVMDisposeMessage(). */
LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, unsigned txten,
char **out);
/* instruction */
/* Wraps llvm::ParseBitcodeFile(). Returns a module reference or NULL (with
* `out' pointing to an error message). Dispose error message after use, via
* LLVMDisposeMessage(). */
LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen,
char **out);
unsigned LLVMInstIsTerminator(LLVMValueRef I);
unsigned LLVMInstIsBinaryOp(LLVMValueRef I);
unsigned LLVMInstIsShift(LLVMValueRef I);
unsigned LLVMInstIsCast(LLVMValueRef I);
unsigned LLVMInstIsLogicalShift(LLVMValueRef I);
unsigned LLVMInstIsArithmeticShift(LLVMValueRef I);
unsigned LLVMInstIsAssociative(LLVMValueRef I);
unsigned LLVMInstIsCommutative(LLVMValueRef I);
unsigned LLVMInstIsTrapping(LLVMValueRef I);
/* Returns pointer to a heap-allocated block of `*len' bytes containing bit code
* for the given module. NULL on error. */
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *len);
const char *LLVMInstGetOpcodeName(LLVMValueRef I);
unsigned LLVMInstGetOpcode(LLVMValueRef I);
/* Wraps llvm::sys::DynamicLibrary::LoadLibraryPermanently(). Returns 0 on
* failure (with errmsg filled in) and 1 on success. Dispose error message after
* use, via LLVMDisposeMessage(). */
unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg);
/* reading llvm "assembly" */
LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len,
char **OutMessage);
/* bitcode related */
LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len,
char **OutMessage);
unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len);
unsigned LLVMLoadLibraryPermanently(const char* filename, char **ErrMsg);
/* passes */
/* Passes. A few passes (listed below) are used directly from LLVM-C,
* rest are declared here.
*
* ConstantPropagation
* GVN
* InstructionCombining
* PromoteMemoryToRegister
* Reassociate
* CFGSimplification
*/
#define declare_pass(P) \
void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM);
@ -97,7 +138,6 @@ declare_pass( BreakCriticalEdges )
declare_pass( CodeGenPrepare )
declare_pass( CondPropagation )
declare_pass( ConstantMerge )
//LLVM-C declare_pass( ConstantPropagation )
declare_pass( DeadCodeElimination )
declare_pass( DeadArgElimination )
declare_pass( DeadTypeElimination )
@ -106,7 +146,6 @@ declare_pass( DeadStoreElimination )
declare_pass( GCSE )
declare_pass( GlobalDCE )
declare_pass( GlobalOptimizer )
//LLVM-C declare_pass( GVN )
declare_pass( GVNPRE )
declare_pass( IndMemRem )
declare_pass( IndVarSimplify )
@ -116,7 +155,6 @@ declare_pass( EdgeProfiler )
declare_pass( FunctionProfiler )
declare_pass( NullProfilerRS )
declare_pass( RSProfiling )
//LLVM-C declare_pass( InstructionCombining )
declare_pass( Internalize )
declare_pass( IPConstantPropagation )
declare_pass( IPSCCP )
@ -136,18 +174,15 @@ declare_pass( LowerAllocations )
declare_pass( LowerInvoke )
declare_pass( LowerSetJmp )
declare_pass( LowerSwitch )
//LLVM-C declare_pass( PromoteMemoryToRegister )
declare_pass( MemCpyOpt )
declare_pass( UnifyFunctionExitNodes )
declare_pass( PredicateSimplifier )
declare_pass( PruneEH )
declare_pass( RaiseAllocations )
//LLVM-C declare_pass( Reassociate )
declare_pass( DemoteRegisterToMemory )
declare_pass( ScalarReplAggregates )
declare_pass( SCCP )
declare_pass( SimplifyLibCalls )
//LLVM-C declare_pass( CFGSimplification )
declare_pass( StripSymbols )
declare_pass( StripDeadPrototypes )
declare_pass( StructRetPromotion )

View file

@ -1,3 +1,33 @@
#
# Copyright (c) 2008, Mahadevan R All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# 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
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Pass managers and passes.
This module provides the LLVM pass managers and the passes themselves.

View file

@ -1,3 +1,33 @@
/*
* Copyright (c) 2008, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* 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
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wrap.h"

View file

@ -1,3 +1,33 @@
/*
* Copyright (c) 2008, Mahadevan R All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* 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
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* Functions and macros to aid in wrapping.
*/