From 76cc613b923015904336b7283ec22cb3bde1ee32 Mon Sep 17 00:00:00 2001 From: Meow King Date: Sat, 3 Aug 2024 23:54:39 +0800 Subject: [PATCH] feat(example): parse_ir_assembly --- example/parse_ir_assmebly.py | 34 +++++++++++++++++++++++++++++----- src/llvm/Core/iterator.h | 5 +++++ src/llvm/Core/miscClasses.cpp | 9 ++++++--- src/llvm/Core/value.cpp | 4 +++- src/llvm/_types.h | 13 +++---------- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/example/parse_ir_assmebly.py b/example/parse_ir_assmebly.py index e5a84e2..0edd569 100644 --- a/example/parse_ir_assmebly.py +++ b/example/parse_ir_assmebly.py @@ -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") - diff --git a/src/llvm/Core/iterator.h b/src/llvm/Core/iterator.h index fc0619a..480d1eb 100644 --- a/src/llvm/Core/iterator.h +++ b/src/llvm/Core/iterator.h @@ -3,6 +3,11 @@ #include +#define BIND_ITERATOR_CLASS(ClassName, PythonClassName) \ + nanobind::class_(m, PythonClassName, PythonClassName) \ + .def("__iter__", [](ClassName &self) { return self; }) \ + .def("__next__", &ClassName::next); + void bindIterators(nanobind::module_ &m); diff --git a/src/llvm/Core/miscClasses.cpp b/src/llvm/Core/miscClasses.cpp index 43458b8..3b612aa 100644 --- a/src/llvm/Core/miscClasses.cpp +++ b/src/llvm/Core/miscClasses.cpp @@ -796,6 +796,11 @@ void bindOtherClasses(nb::module_ &m) { [](PyBasicBlock &self) { return ""; }) + .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)); @@ -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 { auto res = LLVMGetFirstGlobal(m.get()); diff --git a/src/llvm/Core/value.cpp b/src/llvm/Core/value.cpp index 5bdcba8..e310afe 100644 --- a/src/llvm/Core/value.cpp +++ b/src/llvm/Core/value.cpp @@ -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())); }); diff --git a/src/llvm/_types.h b/src/llvm/_types.h index f15bf44..8352dab 100644 --- a/src/llvm/_types.h +++ b/src/llvm/_types.h @@ -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: \ @@ -330,11 +329,10 @@ 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; \ } \ \ @@ -342,11 +340,6 @@ DEFINE_DIRECT_SUB_CLASS(PyPassManagerBase, PyFunctionPassManager); UnderlyingType val; \ }; -#define BIND_ITERATOR_CLASS(ClassName, PythonClassName) \ - nanobind::class_(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)