Skip to content

Commit

Permalink
feat(example): parse_ir_assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
Ziqi-Yang committed Aug 4, 2024
1 parent a749220 commit 76cc613
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 19 deletions.
34 changes: 29 additions & 5 deletions example/parse_ir_assmebly.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,38 @@
print(f'Function | name: "{f.name}", type: "{f.type}"')
module = f.parent
assert m == module # point to the same module object
assert f.parent is not module # but python objects are not the same
assert m is not module # but python objects are not the same
assert f.kind == core.ValueKind.Function
for i, a in enumerate(f.args, 1):
print(f'\tArgument | name: "{a.name}", type: "{a.type}"')
attrs = f.get_attributes_at_index(i)
print(f"\t\tattrs: {attrs}")
for b in f.basic_blocks:
print(b)
for bb in f.basic_blocks:
print(f'\tBasicBlock | name: "{bb.name}" | value.type: "{bb.value.type}"')
print("-------- Content of BasicBlock ---------")
print(str(bb))
print("-------- End of BasicBlock ---------")
fn = bb.parent
assert fn == f
assert fn is not f
assert bb.value.kind == core.ValueKind.BasicBlock
for insr in bb.instructions:
print(f'\t\tInstruction | name: "{insr.name}" | opcode: "{insr.opcode}" | type: \
"{insr.type}" | str: "{insr}"')
assert insr.parent == bb
assert insr.parent is not bb
assert insr.kind == core.ValueKind.Instruction
for i in range(insr.operands_num):
operand = insr.get_operand(0)
print(f'\t\t\tOperand | name: "{operand.name}" | type: "{operand.type}"')

print("\n")

print("\n\n")
for g in m.global_variables:
print(g)
print(f'Global | name: "{g.name}" | type: "{g.type}"')
assert g.kind == core.ValueKind.GlobalVariable
print(f'\tvisibility: {g.visibility}')
print()

# print("\n----------------------------\n")

5 changes: 5 additions & 0 deletions src/llvm/Core/iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

#include <nanobind/nanobind.h>

#define BIND_ITERATOR_CLASS(ClassName, PythonClassName) \
nanobind::class_<ClassName>(m, PythonClassName, PythonClassName) \
.def("__iter__", [](ClassName &self) { return self; }) \
.def("__next__", &ClassName::next);


void bindIterators(nanobind::module_ &m);

Expand Down
9 changes: 6 additions & 3 deletions src/llvm/Core/miscClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,11 @@ void bindOtherClasses(nb::module_ &m) {
[](PyBasicBlock &self) {
return "<BasicBlock>";
})
.def("__str__",
[](PyBasicBlock &self) {
auto value = LLVMBasicBlockAsValue(self.get());
return get_value_str(value);
})
.def("__init__",
[](PyBasicBlock *bb, PyContext &c, const char *name) {
new (bb) PyBasicBlock(LLVMCreateBasicBlockInContext(c.get(), name));
Expand Down Expand Up @@ -1391,9 +1396,7 @@ void bindOtherClasses(nb::module_ &m) {
[](PyModule &self) {
return &self;
})
.def("__exit__",

[](PyModule &self, nb::args args, nb::kwargs kwargs) {})
.def("__exit__", [](PyModule &self, nb::args args, nb::kwargs kwargs) {})
.def_prop_ro("first_global_variable",
[](PyModule &m) -> optional<PyGlobalVariable> {
auto res = LLVMGetFirstGlobal(m.get());
Expand Down
4 changes: 3 additions & 1 deletion src/llvm/Core/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1612,7 +1612,9 @@ void bindValueClasses(nb::module_ &m) {
"vector_a"_a, "vector_b"_a, "mask"_a)
.def_static("block_address",
[](PyConstant &value, PyBasicBlock &bb) {
return PyValueAuto(LLVMBlockAddress(value.get(), bb.get()));
// This instruction returns an BlockAddress kind value, which
// isn't used elsewhere in LLVM C API
return PyValue(LLVMBlockAddress(value.get(), bb.get()));
});


Expand Down
13 changes: 3 additions & 10 deletions src/llvm/_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@ DEFINE_DIRECT_SUB_CLASS(PyPassManagerBase, PyPassManager);
DEFINE_DIRECT_SUB_CLASS(PyPassManagerBase, PyFunctionPassManager);



#define DEFINE_ITERATOR_CLASS(TypeName, UnderlyingType, GetNextFn) \
class TypeName { \
public: \
Expand All @@ -330,23 +329,17 @@ DEFINE_DIRECT_SUB_CLASS(PyPassManagerBase, PyFunctionPassManager);
} \
\
UnderlyingType next() { \
auto res = GetNextFn(val.get()); \
if (!res) \
throw nanobind::stop_iteration(); \
if (!val.get()) \
throw nanobind::stop_iteration(); \
auto prev = val; \
val = UnderlyingType(res); \
val = UnderlyingType(GetNextFn(val.get())); \
return prev; \
} \
\
private: \
UnderlyingType val; \
};

#define BIND_ITERATOR_CLASS(ClassName, PythonClassName) \
nanobind::class_<ClassName>(m, PythonClassName, PythonClassName) \
.def("__iter__", [](ClassName &self) { return self; }) \
.def("__next__", &ClassName::next);


DEFINE_ITERATOR_CLASS(PyUseIterator, PyUse, LLVMGetNextUse)
// DEFINE_ITERATOR_CLASS(PyBasicBlockIterator, PyBasicBlock, LLVMGetNextBasicBlock)
Expand Down

0 comments on commit 76cc613

Please sign in to comment.