Skip to content

Commit

Permalink
refactor: function parameter attributes more convenient APIs and bett…
Browse files Browse the repository at this point in the history
…er `repr` in python
  • Loading branch information
Ziqi-Yang committed Aug 31, 2024
1 parent ee86f4d commit cd39209
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 43 deletions.
14 changes: 10 additions & 4 deletions example/parse_ir_assmebly.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
@glob_f = global float 1.5
@glob_struct = global %struct.glob_type {i64 0, [2 x i64] [i64 0, i64 0]}
define i32 @sum(i32 %.1, i32 %.2) {
define i32 @sum(i32 nocapture %.1, i32 %.2) noinline {
%.3 = add i32 %.1, %.2
%.4 = add i32 0, %.3
ret i32 %.4
}
; Function Attrs: noinline nounwind optnone uwtable
define void @foo() {
call void asm sideeffect "nop", ""()
ret void
Expand All @@ -33,10 +34,15 @@
assert m == module # point to the same module object
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):

# TODO it seems we cannot get function attributes (not parameter's)
f_attrs = f.get_attributes_at_index(0)
print(f"attrs: {f_attrs}")

for a in f.args:
print(f'\tArgument | name: "{a.name}", type: "{a.type}"')
attrs = f.get_attributes_at_index(i)
print(f"\t\tattrs: {attrs}")
# attrs = f.get_attributes_at_index(i)
print(f"\t\tattrs: {a.attrs}")
for bb in f.basic_blocks:
print(f'\tBasicBlock | name: "{bb.name}" | value.type: "{bb.value.type}"')
print("-------- Content of BasicBlock ---------")
Expand Down
43 changes: 6 additions & 37 deletions src/llvm/Core/miscClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include "../types_priv.h"
#include "../utils_priv.h"
#include "utils.h"
#include <llvm/IR/Attributes.h>
#include <llvm/IR/Value.h>


namespace nb = nanobind;
using namespace nb::literals;
Expand Down Expand Up @@ -1075,7 +1078,9 @@ void bindOtherClasses(nb::module_ &m) {
AttributeClass
.def("__repr__",
[](PymAttribute &self) {
return "<Attribute>";
using namespace llvm;
Attribute attr = unwrap(self.get());
return fmt::format("<Attribute name='{}'>", attr.getAsString());
})
.def_prop_ro("is_enum",
[](PymAttribute &attr) {
Expand All @@ -1091,21 +1096,11 @@ void bindOtherClasses(nb::module_ &m) {
});

EnumAttributeClass
.def("__repr__",
[](PymEnumAttribute &self) {
return "<EnumAttribute>";
})
.def("__init__",
[](PymEnumAttribute *t, PymContext &c, unsigned kindID, uint64_t val) {
new (t) PymEnumAttribute(LLVMCreateEnumAttribute(c.get(), kindID, val));
},
"context"_a, "kind_id"_a, "val"_a)
.def("__repr__",
[](PymEnumAttribute &self) {
auto kind = LLVMGetEnumAttributeKind(self.get());
auto value = LLVMGetEnumAttributeValue(self.get());
return fmt::format("<EnumAttribute kind={} value={}>", kind, value);
})
.def_prop_ro("kind",
[](PymEnumAttribute &attr) {
return LLVMGetEnumAttributeKind(attr.get());
Expand All @@ -1130,33 +1125,19 @@ void bindOtherClasses(nb::module_ &m) {
.def_static("get_last_enum_attribute_kind", &LLVMGetLastEnumAttributeKind);

TypeAttributeClass
.def("__repr__",
[](PymTypeAttribute &self) {
return "<TypeAttribute>";
})
.def("__init__",
[](PymTypeAttribute *t, PymContext &context, unsigned kind_id, PymType &type) {
new (t) PymTypeAttribute(LLVMCreateTypeAttribute
(context.get(), kind_id, type.get()));
},
"context"_a, "kind_id"_a, "type"_a)
.def("__repr__",
[](PymTypeAttribute &self) {
auto value = LLVMGetTypeAttributeValue(self.get());
auto type_kind = LLVMGetTypeKind(value);
return fmt::format("<TypeAttribute value={}>", get_repr_str(type_kind));
})
.def_prop_ro("value",
[](PymTypeAttribute &ta){
return PymTypeAuto(LLVMGetTypeAttributeValue(ta.get()));
},
"Get the type attribute's value.");

StringAttributeClass
.def("__repr__",
[](PymStringAttribute &self) {
return "<StringAttribute>";
})
.def("__init__",
[](PymStringAttribute *t, PymContext &c, const std::string &kind, const std::string &value) {
auto raw = LLVMCreateStringAttribute(c.get(),
Expand All @@ -1165,18 +1146,6 @@ void bindOtherClasses(nb::module_ &m) {
new (t) PymStringAttribute(raw);
},
"context"_a, "kind"_a, "value"_a)
.def("__repr__",
[](PymStringAttribute &self) {
unsigned kind_length;
const char *raw_kind = LLVMGetStringAttributeKind(self.get(), &kind_length);
auto kind = std::string(raw_kind, kind_length);

unsigned value_length;
const char *raw_value = LLVMGetStringAttributeValue(self.get(), &value_length);
auto value = std::string(raw_value, value_length);

return fmt::format("<TypeAttribute kind={} value={}>", kind, value);
})
.def_prop_ro("kind",
[](PymStringAttribute &ta) {
unsigned length;
Expand Down
15 changes: 15 additions & 0 deletions src/llvm/Core/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../utils_priv.h"
#include "utils.h"
#include <llvm-c/Analysis.h>
#include <llvm/IR/Function.h>

namespace nb = nanobind;
using namespace nb::literals;
Expand Down Expand Up @@ -1214,6 +1215,20 @@ void bindValueClasses(nb::module_ &m) {
auto res = LLVMGetPreviousParam(self.get());
WRAP_OPTIONAL_RETURN(res, PymArgument);
})
.def_prop_ro("attrs", // c++ extension (a little)
[](PymArgument &self) {
using namespace llvm;
Argument *arg = unwrap<Argument>(self.get());
unsigned argno = arg->getArgNo();
const AttributeSet attrs =
arg->getParent()->getAttributes().getParamAttrs(argno);

std::vector<PymAttribute*> pymAttrs;
for (const auto &attr : attrs) {
pymAttrs.emplace_back(PymAttributeAuto(wrap(attr)));
}
return pymAttrs;
})
.def("set_alignment",
[](PymArgument &self, unsigned Align) {
return LLVMSetParamAlignment(self.get(), Align);
Expand Down
4 changes: 2 additions & 2 deletions src/llvm/types_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ DEFINE_DIRECT_SUB_CLASS(PymPassManagerBase, PymFunctionPassManager);
} \
\
UnderlyingType next() { \
if (!val.get()) \
throw nanobind::stop_iteration(); \
if (!val.get()) \
throw nanobind::stop_iteration(); \
auto prev = val; \
val = UnderlyingType(GetNextFn(val.get())); \
return prev; \
Expand Down

0 comments on commit cd39209

Please sign in to comment.