Files
clang-p2996/llvm/bindings/python/llvm/core.py
Chandler Carruth 7adc3a2b0e [PM/AA] Remove the last relics of the separate IPA library from LLVM,
folding the code into the main Analysis library.

There already wasn't much of a distinction between Analysis and IPA.
A number of the passes in Analysis are actually IPA passes, and there
doesn't seem to be any advantage to separating them.

Moreover, it makes it hard to have interactions between analyses that
are both local and interprocedural. In trying to make the Alias Analysis
infrastructure work with the new pass manager, it becomes particularly
awkward to navigate this split.

I've tried to find all the places where we referenced this, but I may
have missed some. I have also adjusted the C API to continue to be
equivalently functional after this change.

Differential Revision: http://reviews.llvm.org/D12075

llvm-svn: 245318
2015-08-18 17:51:53 +00:00

627 lines
18 KiB
Python

#===- core.py - Python LLVM Bindings -------------------------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
from .common import LLVMObject
from .common import c_object_p
from .common import get_library
from . import enumerations
from ctypes import POINTER
from ctypes import byref
from ctypes import c_char_p
from ctypes import c_uint
__all__ = [
"lib",
"Enums",
"OpCode",
"MemoryBuffer",
"Module",
"Value",
"Function",
"BasicBlock",
"Instruction",
"Context",
"PassRegistry"
]
lib = get_library()
Enums = []
class LLVMEnumeration(object):
"""Represents an individual LLVM enumeration."""
def __init__(self, name, value):
self.name = name
self.value = value
def __repr__(self):
return '%s.%s' % (self.__class__.__name__,
self.name)
@classmethod
def from_value(cls, value):
"""Obtain an enumeration instance from a numeric value."""
result = cls._value_map.get(value, None)
if result is None:
raise ValueError('Unknown %s: %d' % (cls.__name__,
value))
return result
@classmethod
def register(cls, name, value):
"""Registers a new enumeration.
This is called by this module for each enumeration defined in
enumerations. You should not need to call this outside this module.
"""
if value in cls._value_map:
raise ValueError('%s value already registered: %d' % (cls.__name__,
value))
enum = cls(name, value)
cls._value_map[value] = enum
setattr(cls, name, enum)
class Attribute(LLVMEnumeration):
"""Represents an individual Attribute enumeration."""
_value_map = {}
def __init__(self, name, value):
super(Attribute, self).__init__(name, value)
class OpCode(LLVMEnumeration):
"""Represents an individual OpCode enumeration."""
_value_map = {}
def __init__(self, name, value):
super(OpCode, self).__init__(name, value)
class TypeKind(LLVMEnumeration):
"""Represents an individual TypeKind enumeration."""
_value_map = {}
def __init__(self, name, value):
super(TypeKind, self).__init__(name, value)
class Linkage(LLVMEnumeration):
"""Represents an individual Linkage enumeration."""
_value_map = {}
def __init__(self, name, value):
super(Linkage, self).__init__(name, value)
class Visibility(LLVMEnumeration):
"""Represents an individual visibility enumeration."""
_value_map = {}
def __init__(self, name, value):
super(Visibility, self).__init__(name, value)
class CallConv(LLVMEnumeration):
"""Represents an individual calling convention enumeration."""
_value_map = {}
def __init__(self, name, value):
super(CallConv, self).__init__(name, value)
class IntPredicate(LLVMEnumeration):
"""Represents an individual IntPredicate enumeration."""
_value_map = {}
def __init__(self, name, value):
super(IntPredicate, self).__init__(name, value)
class RealPredicate(LLVMEnumeration):
"""Represents an individual RealPredicate enumeration."""
_value_map = {}
def __init__(self, name, value):
super(RealPredicate, self).__init__(name, value)
class LandingPadClauseTy(LLVMEnumeration):
"""Represents an individual LandingPadClauseTy enumeration."""
_value_map = {}
def __init__(self, name, value):
super(LandingPadClauseTy, self).__init__(name, value)
class MemoryBuffer(LLVMObject):
"""Represents an opaque memory buffer."""
def __init__(self, filename=None):
"""Create a new memory buffer.
Currently, we support creating from the contents of a file at the
specified filename.
"""
if filename is None:
raise Exception("filename argument must be defined")
memory = c_object_p()
out = c_char_p(None)
result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename,
byref(memory), byref(out))
if result:
raise Exception("Could not create memory buffer: %s" % out.value)
LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer)
def __len__(self):
return lib.LLVMGetBufferSize(self)
class Value(LLVMObject):
def __init__(self, value):
LLVMObject.__init__(self, value)
@property
def name(self):
return lib.LLVMGetValueName(self)
def dump(self):
lib.LLVMDumpValue(self)
def get_operand(self, i):
return Value(lib.LLVMGetOperand(self, i))
def set_operand(self, i, v):
return lib.LLVMSetOperand(self, i, v)
def __len__(self):
return lib.LLVMGetNumOperands(self)
class Module(LLVMObject):
"""Represents the top-level structure of an llvm program in an opaque object."""
def __init__(self, module, name=None, context=None):
LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule)
@classmethod
def CreateWithName(cls, module_id):
m = Module(lib.LLVMModuleCreateWithName(module_id))
Context.GetGlobalContext().take_ownership(m)
return m
@property
def datalayout(self):
return lib.LLVMGetDataLayout(self)
@datalayout.setter
def datalayout(self, new_data_layout):
"""new_data_layout is a string."""
lib.LLVMSetDataLayout(self, new_data_layout)
@property
def target(self):
return lib.LLVMGetTarget(self)
@target.setter
def target(self, new_target):
"""new_target is a string."""
lib.LLVMSetTarget(self, new_target)
def dump(self):
lib.LLVMDumpModule(self)
class __function_iterator(object):
def __init__(self, module, reverse=False):
self.module = module
self.reverse = reverse
if self.reverse:
self.function = self.module.last
else:
self.function = self.module.first
def __iter__(self):
return self
def next(self):
if not isinstance(self.function, Function):
raise StopIteration("")
result = self.function
if self.reverse:
self.function = self.function.prev
else:
self.function = self.function.next
return result
def __iter__(self):
return Module.__function_iterator(self)
def __reversed__(self):
return Module.__function_iterator(self, reverse=True)
@property
def first(self):
return Function(lib.LLVMGetFirstFunction(self))
@property
def last(self):
return Function(lib.LLVMGetLastFunction(self))
def print_module_to_file(self, filename):
out = c_char_p(None)
# Result is inverted so 0 means everything was ok.
result = lib.LLVMPrintModuleToFile(self, filename, byref(out))
if result:
raise RuntimeError("LLVM Error: %s" % out.value)
class Function(Value):
def __init__(self, value):
Value.__init__(self, value)
@property
def next(self):
f = lib.LLVMGetNextFunction(self)
return f and Function(f)
@property
def prev(self):
f = lib.LLVMGetPreviousFunction(self)
return f and Function(f)
@property
def first(self):
b = lib.LLVMGetFirstBasicBlock(self)
return b and BasicBlock(b)
@property
def last(self):
b = lib.LLVMGetLastBasicBlock(self)
return b and BasicBlock(b)
class __bb_iterator(object):
def __init__(self, function, reverse=False):
self.function = function
self.reverse = reverse
if self.reverse:
self.bb = function.last
else:
self.bb = function.first
def __iter__(self):
return self
def next(self):
if not isinstance(self.bb, BasicBlock):
raise StopIteration("")
result = self.bb
if self.reverse:
self.bb = self.bb.prev
else:
self.bb = self.bb.next
return result
def __iter__(self):
return Function.__bb_iterator(self)
def __reversed__(self):
return Function.__bb_iterator(self, reverse=True)
def __len__(self):
return lib.LLVMCountBasicBlocks(self)
class BasicBlock(LLVMObject):
def __init__(self, value):
LLVMObject.__init__(self, value)
@property
def next(self):
b = lib.LLVMGetNextBasicBlock(self)
return b and BasicBlock(b)
@property
def prev(self):
b = lib.LLVMGetPreviousBasicBlock(self)
return b and BasicBlock(b)
@property
def first(self):
i = lib.LLVMGetFirstInstruction(self)
return i and Instruction(i)
@property
def last(self):
i = lib.LLVMGetLastInstruction(self)
return i and Instruction(i)
def __as_value(self):
return Value(lib.LLVMBasicBlockAsValue(self))
@property
def name(self):
return lib.LLVMGetValueName(self.__as_value())
def dump(self):
lib.LLVMDumpValue(self.__as_value())
def get_operand(self, i):
return Value(lib.LLVMGetOperand(self.__as_value(),
i))
def set_operand(self, i, v):
return lib.LLVMSetOperand(self.__as_value(),
i, v)
def __len__(self):
return lib.LLVMGetNumOperands(self.__as_value())
class __inst_iterator(object):
def __init__(self, bb, reverse=False):
self.bb = bb
self.reverse = reverse
if self.reverse:
self.inst = self.bb.last
else:
self.inst = self.bb.first
def __iter__(self):
return self
def next(self):
if not isinstance(self.inst, Instruction):
raise StopIteration("")
result = self.inst
if self.reverse:
self.inst = self.inst.prev
else:
self.inst = self.inst.next
return result
def __iter__(self):
return BasicBlock.__inst_iterator(self)
def __reversed__(self):
return BasicBlock.__inst_iterator(self, reverse=True)
class Instruction(Value):
def __init__(self, value):
Value.__init__(self, value)
@property
def next(self):
i = lib.LLVMGetNextInstruction(self)
return i and Instruction(i)
@property
def prev(self):
i = lib.LLVMGetPreviousInstruction(self)
return i and Instruction(i)
@property
def opcode(self):
return OpCode.from_value(lib.LLVMGetInstructionOpcode(self))
class Context(LLVMObject):
def __init__(self, context=None):
if context is None:
context = lib.LLVMContextCreate()
LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose)
else:
LLVMObject.__init__(self, context)
@classmethod
def GetGlobalContext(cls):
return Context(lib.LLVMGetGlobalContext())
class PassRegistry(LLVMObject):
"""Represents an opaque pass registry object."""
def __init__(self):
LLVMObject.__init__(self,
lib.LLVMGetGlobalPassRegistry())
def register_library(library):
# Initialization/Shutdown declarations.
library.LLVMInitializeCore.argtypes = [PassRegistry]
library.LLVMInitializeCore.restype = None
library.LLVMInitializeTransformUtils.argtypes = [PassRegistry]
library.LLVMInitializeTransformUtils.restype = None
library.LLVMInitializeScalarOpts.argtypes = [PassRegistry]
library.LLVMInitializeScalarOpts.restype = None
library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry]
library.LLVMInitializeObjCARCOpts.restype = None
library.LLVMInitializeVectorization.argtypes = [PassRegistry]
library.LLVMInitializeVectorization.restype = None
library.LLVMInitializeInstCombine.argtypes = [PassRegistry]
library.LLVMInitializeInstCombine.restype = None
library.LLVMInitializeIPO.argtypes = [PassRegistry]
library.LLVMInitializeIPO.restype = None
library.LLVMInitializeInstrumentation.argtypes = [PassRegistry]
library.LLVMInitializeInstrumentation.restype = None
library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
library.LLVMInitializeAnalysis.restype = None
library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
library.LLVMInitializeCodeGen.restype = None
library.LLVMInitializeTarget.argtypes = [PassRegistry]
library.LLVMInitializeTarget.restype = None
library.LLVMShutdown.argtypes = []
library.LLVMShutdown.restype = None
# Pass Registry declarations.
library.LLVMGetGlobalPassRegistry.argtypes = []
library.LLVMGetGlobalPassRegistry.restype = c_object_p
# Context declarations.
library.LLVMContextCreate.argtypes = []
library.LLVMContextCreate.restype = c_object_p
library.LLVMContextDispose.argtypes = [Context]
library.LLVMContextDispose.restype = None
library.LLVMGetGlobalContext.argtypes = []
library.LLVMGetGlobalContext.restype = c_object_p
# Memory buffer declarations
library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
POINTER(c_object_p), POINTER(c_char_p)]
library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
library.LLVMGetBufferSize.argtypes = [MemoryBuffer]
library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
# Module declarations
library.LLVMModuleCreateWithName.argtypes = [c_char_p]
library.LLVMModuleCreateWithName.restype = c_object_p
library.LLVMDisposeModule.argtypes = [Module]
library.LLVMDisposeModule.restype = None
library.LLVMGetDataLayout.argtypes = [Module]
library.LLVMGetDataLayout.restype = c_char_p
library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
library.LLVMSetDataLayout.restype = None
library.LLVMGetTarget.argtypes = [Module]
library.LLVMGetTarget.restype = c_char_p
library.LLVMSetTarget.argtypes = [Module, c_char_p]
library.LLVMSetTarget.restype = None
library.LLVMDumpModule.argtypes = [Module]
library.LLVMDumpModule.restype = None
library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
POINTER(c_char_p)]
library.LLVMPrintModuleToFile.restype = bool
library.LLVMGetFirstFunction.argtypes = [Module]
library.LLVMGetFirstFunction.restype = c_object_p
library.LLVMGetLastFunction.argtypes = [Module]
library.LLVMGetLastFunction.restype = c_object_p
library.LLVMGetNextFunction.argtypes = [Function]
library.LLVMGetNextFunction.restype = c_object_p
library.LLVMGetPreviousFunction.argtypes = [Function]
library.LLVMGetPreviousFunction.restype = c_object_p
# Value declarations.
library.LLVMGetValueName.argtypes = [Value]
library.LLVMGetValueName.restype = c_char_p
library.LLVMDumpValue.argtypes = [Value]
library.LLVMDumpValue.restype = None
library.LLVMGetOperand.argtypes = [Value, c_uint]
library.LLVMGetOperand.restype = c_object_p
library.LLVMSetOperand.argtypes = [Value, Value, c_uint]
library.LLVMSetOperand.restype = None
library.LLVMGetNumOperands.argtypes = [Value]
library.LLVMGetNumOperands.restype = c_uint
# Basic Block Declarations.
library.LLVMGetFirstBasicBlock.argtypes = [Function]
library.LLVMGetFirstBasicBlock.restype = c_object_p
library.LLVMGetLastBasicBlock.argtypes = [Function]
library.LLVMGetLastBasicBlock.restype = c_object_p
library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
library.LLVMGetNextBasicBlock.restype = c_object_p
library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
library.LLVMGetPreviousBasicBlock.restype = c_object_p
library.LLVMGetFirstInstruction.argtypes = [BasicBlock]
library.LLVMGetFirstInstruction.restype = c_object_p
library.LLVMGetLastInstruction.argtypes = [BasicBlock]
library.LLVMGetLastInstruction.restype = c_object_p
library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
library.LLVMBasicBlockAsValue.restype = c_object_p
library.LLVMCountBasicBlocks.argtypes = [Function]
library.LLVMCountBasicBlocks.restype = c_uint
# Instruction Declarations.
library.LLVMGetNextInstruction.argtypes = [Instruction]
library.LLVMGetNextInstruction.restype = c_object_p
library.LLVMGetPreviousInstruction.argtypes = [Instruction]
library.LLVMGetPreviousInstruction.restype = c_object_p
library.LLVMGetInstructionOpcode.argtypes = [Instruction]
library.LLVMGetInstructionOpcode.restype = c_uint
def register_enumerations():
if Enums:
return None
enums = [
(Attribute, enumerations.Attributes),
(OpCode, enumerations.OpCodes),
(TypeKind, enumerations.TypeKinds),
(Linkage, enumerations.Linkages),
(Visibility, enumerations.Visibility),
(CallConv, enumerations.CallConv),
(IntPredicate, enumerations.IntPredicate),
(RealPredicate, enumerations.RealPredicate),
(LandingPadClauseTy, enumerations.LandingPadClauseTy),
]
for enum_class, enum_spec in enums:
for name, value in enum_spec:
print name, value
enum_class.register(name, value)
return enums
def initialize_llvm():
Context.GetGlobalContext()
p = PassRegistry()
lib.LLVMInitializeCore(p)
lib.LLVMInitializeTransformUtils(p)
lib.LLVMInitializeScalarOpts(p)
lib.LLVMInitializeObjCARCOpts(p)
lib.LLVMInitializeVectorization(p)
lib.LLVMInitializeInstCombine(p)
lib.LLVMInitializeIPO(p)
lib.LLVMInitializeInstrumentation(p)
lib.LLVMInitializeAnalysis(p)
lib.LLVMInitializeCodeGen(p)
lib.LLVMInitializeTarget(p)
register_library(lib)
Enums = register_enumerations()
initialize_llvm()