Skip to content

Commit

Permalink
[python-bindings] Added support for iterating over a basic blocks ins…
Browse files Browse the repository at this point in the history
…tructions, getting their name/dumping them, f/b iteration.

Tests are included.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190475 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
gottesmm committed Sep 11, 2013
1 parent e23fa98 commit 73c382f
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
75 changes: 75 additions & 0 deletions bindings/python/llvm/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"Value",
"Function",
"BasicBlock",
"Instruction",
"Context",
"PassRegistry"
]
Expand Down Expand Up @@ -253,13 +254,71 @@ 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)

@property
def name(self):
return lib.LLVMGetValueName(Value(lib.LLVMBasicBlockAsValue(self)))

def dump(self):
lib.LLVMDumpValue(Value(lib.LLVMBasicBlockAsValue(self)))

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):
Expand Down Expand Up @@ -402,12 +461,28 @@ def register_library(library):
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():
for name, value in enumerations.OpCodes:
OpCode.register(name, value)
Expand Down
24 changes: 24 additions & 0 deletions bindings/python/llvm/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,27 @@ def test_function_basicblock_iteration(self):
self.assertEqual(bb.name, bb_list[i])
bb.dump()

def test_basicblock_instruction_iteration(self):
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
i = 0

inst_list = [('arg1', OpCode.ExtractValue),
('arg2', OpCode.ExtractValue),
('', OpCode.Call),
('', OpCode.Ret)]

bb = m.first.first

# Forward
for inst in bb:
self.assertEqual(inst.name, inst_list[i][0])
self.assertEqual(inst.opcode, inst_list[i][1])
inst.dump()
i += 1

# Backwards
for inst in reversed(bb):
i -= 1
self.assertEqual(inst.name, inst_list[i][0])
self.assertEqual(inst.opcode, inst_list[i][1])
inst.dump()

0 comments on commit 73c382f

Please sign in to comment.