inAttrs.emplace_back(Identifier::get(named.name, &mlirContext),
mlir::Attribute::getFromOpaquePointer(
reinterpret_cast<const void *>(named.value)));
- inputAttrs.emplace_back(&mlirContext, inAttrs);
+ inputAttrs.emplace_back(inAttrs);
}
// Create the function itself.
});
m.def("constant_function", [](PythonFunction func) -> PythonValueHandle {
auto *function = reinterpret_cast<Function *>(func.function);
- auto attr = FunctionAttr::get(function, function->getContext());
+ auto attr = FunctionAttr::get(function);
return ValueHandle::create<ConstantOp>(function->getType(), attr);
});
m.def("appendTo", [](const PythonBlockHandle &handle) {
/// Return the type of this attribute.
Type getType() const;
+ /// Return the context this attribute belongs to.
+ MLIRContext *getContext() const;
+
/// Return true if this field is, or contains, a function attribute.
bool isOrContainsFunction() const;
/// remapping table. Return the original attribute if it (or any of nested
/// attributes) is not present in the table.
Attribute remapFunctionAttrs(
- const llvm::DenseMap<Attribute, FunctionAttr> &remappingTable,
- MLIRContext *context) const;
+ const llvm::DenseMap<Attribute, FunctionAttr> &remappingTable) const;
/// Print the attribute.
void print(raw_ostream &os) const;
using ImplType = detail::TypeAttributeStorage;
using ValueType = Type;
- static TypeAttr get(Type type, MLIRContext *context);
+ static TypeAttr get(Type value);
Type getValue() const;
using ImplType = detail::FunctionAttributeStorage;
using ValueType = Function *;
- static FunctionAttr get(Function *value, MLIRContext *context);
+ static FunctionAttr get(Function *value);
Function *getValue() const;
class NamedAttributeList {
public:
NamedAttributeList() : attrs(nullptr) {}
- NamedAttributeList(MLIRContext *context, ArrayRef<NamedAttribute> attributes);
+ NamedAttributeList(ArrayRef<NamedAttribute> attributes);
/// Return all of the attributes on this operation.
ArrayRef<NamedAttribute> getAttrs() const;
/// Replace the held attributes with ones provided in 'newAttrs'.
- void setAttrs(MLIRContext *context, ArrayRef<NamedAttribute> attributes);
+ void setAttrs(ArrayRef<NamedAttribute> attributes);
/// Return the specified attribute if present, null otherwise.
Attribute get(StringRef name) const;
/// If the an attribute exists with the specified name, change it to the new
/// value. Otherwise, add a new attribute with the specified name/value.
- void set(MLIRContext *context, Identifier name, Attribute value);
+ void set(Identifier name, Attribute value);
enum class RemoveResult { Removed, NotFound };
/// Remove the attribute with the specified name if it exists. The return
/// value indicates whether the attribute was present or not.
- RemoveResult remove(MLIRContext *context, Identifier name);
+ RemoveResult remove(Identifier name);
private:
detail::AttributeListStorage *attrs;
/// Return all of the attributes on this function.
ArrayRef<NamedAttribute> getAttrs() { return attrs.getAttrs(); }
+ /// Return the internal attribute list on this function.
+ NamedAttributeList &getAttrList() { return attrs; }
+
/// Return all of the attributes for the argument at 'index'.
ArrayRef<NamedAttribute> getArgAttrs(unsigned index) {
assert(index < getNumArguments() && "invalid argument number");
/// Set the attributes held by this function.
void setAttrs(ArrayRef<NamedAttribute> attributes) {
- attrs.setAttrs(getContext(), attributes);
+ attrs.setAttrs(attributes);
}
/// Set the attributes held by the argument at 'index'.
void setArgAttrs(unsigned index, ArrayRef<NamedAttribute> attributes) {
assert(index < getNumArguments() && "invalid argument number");
- argAttrs[index].setAttrs(getContext(), attributes);
+ argAttrs[index].setAttrs(attributes);
}
/// Return all argument attributes of this function.
/// If the an attribute exists with the specified name, change it to the new
/// value. Otherwise, add a new attribute with the specified name/value.
- void setAttr(Identifier name, Attribute value) {
- attrs.set(getContext(), name, value);
- }
+ void setAttr(Identifier name, Attribute value) { attrs.set(name, value); }
void setAttr(StringRef name, Attribute value) {
setAttr(Identifier::get(name, getContext()), value);
}
void setArgAttr(unsigned index, Identifier name, Attribute value) {
assert(index < getNumArguments() && "invalid argument number");
- argAttrs[index].set(getContext(), name, value);
+ argAttrs[index].set(name, value);
}
void setArgAttr(unsigned index, StringRef name, Attribute value) {
setArgAttr(index, Identifier::get(name, getContext()), value);
/// Remove the attribute with the specified name if it exists. The return
/// value indicates whether the attribute was present or not.
NamedAttributeList::RemoveResult removeAttr(Identifier name) {
- return attrs.remove(getContext(), name);
+ return attrs.remove(name);
}
NamedAttributeList::RemoveResult removeArgAttr(unsigned index,
Identifier name) {
assert(index < getNumArguments() && "invalid argument number");
- return attrs.remove(getContext(), name);
+ return attrs.remove(name);
}
//===--------------------------------------------------------------------===//
/// Return all of the attributes on this operation.
ArrayRef<NamedAttribute> getAttrs() { return attrs.getAttrs(); }
+ /// Return the internal attribute list on this operation.
+ NamedAttributeList &getAttrList() { return attrs; }
+
/// Return the specified attribute if present, null otherwise.
Attribute getAttr(Identifier name) { return attrs.get(name); }
Attribute getAttr(StringRef name) { return attrs.get(name); }
/// If the an attribute exists with the specified name, change it to the new
/// value. Otherwise, add a new attribute with the specified name/value.
- void setAttr(Identifier name, Attribute value) {
- attrs.set(getContext(), name, value);
- }
+ void setAttr(Identifier name, Attribute value) { attrs.set(name, value); }
void setAttr(StringRef name, Attribute value) {
setAttr(Identifier::get(name, getContext()), value);
}
/// Remove the attribute with the specified name if it exists. The return
/// value indicates whether the attribute was present or not.
NamedAttributeList::RemoveResult removeAttr(Identifier name) {
- return attrs.remove(getContext(), name);
+ return attrs.remove(name);
}
//===--------------------------------------------------------------------===//
/// Given a list of NamedAttribute's, canonicalize the list (sorting
/// by name) and return the unique'd result. Note that the empty list is
/// represented with a null pointer.
- static AttributeListStorage *get(ArrayRef<NamedAttribute> attrs,
- MLIRContext *context);
+ static AttributeListStorage *get(ArrayRef<NamedAttribute> attrs);
/// Return the element constants for this aggregate constant. These are
/// known to all be constants.
/// Return the type of this attribute.
Type Attribute::getType() const { return attr->getType(); }
+/// Return the context this attribute belongs to.
+MLIRContext *Attribute::getContext() const { return getType().getContext(); }
+
bool Attribute::isOrContainsFunction() const {
return attr->isOrContainsFunctionCache();
}
// table, walk it and rewrite it to use the mapped function. If it doesn't
// refer to anything in the table, then it is returned unmodified.
Attribute Attribute::remapFunctionAttrs(
- const llvm::DenseMap<Attribute, FunctionAttr> &remappingTable,
- MLIRContext *context) const {
+ const llvm::DenseMap<Attribute, FunctionAttr> &remappingTable) const {
// Most attributes are trivially unrelated to function attributes, skip them
// rapidly.
if (!isOrContainsFunction())
SmallVector<Attribute, 8> remappedElts;
bool anyChange = false;
for (auto elt : arrayAttr.getValue()) {
- auto newElt = elt.remapFunctionAttrs(remappingTable, context);
+ auto newElt = elt.remapFunctionAttrs(remappingTable);
remappedElts.push_back(newElt);
anyChange |= (elt != newElt);
}
if (!anyChange)
return *this;
- return ArrayAttr::get(remappedElts, context);
+ return ArrayAttr::get(remappedElts, getContext());
}
//===----------------------------------------------------------------------===//
// TypeAttr
//===----------------------------------------------------------------------===//
-TypeAttr TypeAttr::get(Type value, MLIRContext *context) {
- return AttributeUniquer::get<TypeAttr>(context, Attribute::Kind::Type, value);
+TypeAttr TypeAttr::get(Type value) {
+ return AttributeUniquer::get<TypeAttr>(value.getContext(),
+ Attribute::Kind::Type, value);
}
Type TypeAttr::getValue() const { return static_cast<ImplType *>(attr)->value; }
// FunctionAttr
//===----------------------------------------------------------------------===//
-FunctionAttr FunctionAttr::get(Function *value, MLIRContext *context) {
+FunctionAttr FunctionAttr::get(Function *value) {
assert(value && "Cannot get FunctionAttr for a null function");
- return AttributeUniquer::get<FunctionAttr>(context, Attribute::Kind::Function,
- value);
+ return AttributeUniquer::get<FunctionAttr>(value->getContext(),
+ Attribute::Kind::Function, value);
}
/// This function is used by the internals of the Function class to null out
// NamedAttributeList
//===----------------------------------------------------------------------===//
-NamedAttributeList::NamedAttributeList(MLIRContext *context,
- ArrayRef<NamedAttribute> attributes) {
- setAttrs(context, attributes);
+NamedAttributeList::NamedAttributeList(ArrayRef<NamedAttribute> attributes) {
+ setAttrs(attributes);
}
/// Return all of the attributes on this operation.
}
/// Replace the held attributes with ones provided in 'newAttrs'.
-void NamedAttributeList::setAttrs(MLIRContext *context,
- ArrayRef<NamedAttribute> attributes) {
+void NamedAttributeList::setAttrs(ArrayRef<NamedAttribute> attributes) {
// Don't create an attribute list if there are no attributes.
if (attributes.empty()) {
attrs = nullptr;
assert(llvm::all_of(attributes,
[](const NamedAttribute &attr) { return attr.second; }) &&
"attributes cannot have null entries");
- attrs = AttributeListStorage::get(attributes, context);
+ attrs = AttributeListStorage::get(attributes);
}
/// Return the specified attribute if present, null otherwise.
/// If the an attribute exists with the specified name, change it to the new
/// value. Otherwise, add a new attribute with the specified name/value.
-void NamedAttributeList::set(MLIRContext *context, Identifier name,
- Attribute value) {
+void NamedAttributeList::set(Identifier name, Attribute value) {
assert(value && "attributes may never be null");
// If we already have this attribute, replace it.
for (auto &elt : newAttrs)
if (elt.first == name) {
elt.second = value;
- attrs = AttributeListStorage::get(newAttrs, context);
+ attrs = AttributeListStorage::get(newAttrs);
return;
}
// Otherwise, add it.
newAttrs.push_back({name, value});
- attrs = AttributeListStorage::get(newAttrs, context);
+ attrs = AttributeListStorage::get(newAttrs);
}
/// Remove the attribute with the specified name if it exists. The return
/// value indicates whether the attribute was present or not.
-auto NamedAttributeList::remove(MLIRContext *context, Identifier name)
- -> RemoveResult {
+auto NamedAttributeList::remove(Identifier name) -> RemoveResult {
auto origAttrs = getAttrs();
for (unsigned i = 0, e = origAttrs.size(); i != e; ++i) {
if (origAttrs[i].first == name) {
+ // Handle the simple case of removing the only attribute in the list.
+ if (e == 1) {
+ attrs = nullptr;
+ return RemoveResult::Removed;
+ }
+
SmallVector<NamedAttribute, 8> newAttrs;
newAttrs.reserve(origAttrs.size() - 1);
newAttrs.append(origAttrs.begin(), origAttrs.begin() + i);
newAttrs.append(origAttrs.begin() + i + 1, origAttrs.end());
- attrs = AttributeListStorage::get(newAttrs, context);
+ attrs = AttributeListStorage::get(newAttrs);
return RemoveResult::Removed;
}
}
return IntegerSetAttr::get(set);
}
-TypeAttr Builder::getTypeAttr(Type type) {
- return TypeAttr::get(type, context);
-}
+TypeAttr Builder::getTypeAttr(Type type) { return TypeAttr::get(type); }
FunctionAttr Builder::getFunctionAttr(Function *value) {
- return FunctionAttr::get(value, context);
+ return FunctionAttr::get(value);
}
ElementsAttr Builder::getSplatElementsAttr(VectorOrTensorType type,
Function::Function(Location location, StringRef name, FunctionType type,
ArrayRef<NamedAttribute> attrs)
: name(Identifier::get(name, type.getContext())), location(location),
- type(type), attrs(type.getContext(), attrs),
- argAttrs(type.getNumInputs()), body(this) {}
+ type(type), attrs(attrs), argAttrs(type.getNumInputs()), body(this) {}
Function::Function(Location location, StringRef name, FunctionType type,
ArrayRef<NamedAttribute> attrs,
ArrayRef<NamedAttributeList> argAttrs)
: name(Identifier::get(name, type.getContext())), location(location),
- type(type), attrs(type.getContext(), attrs), argAttrs(argAttrs),
- body(this) {}
+ type(type), attrs(attrs), argAttrs(argAttrs), body(this) {}
Function::~Function() {
// Clean up function attributes referring to this function.
/// Given a list of NamedAttribute's, canonicalize the list (sorting
/// by name) and return the unique'd result. Note that the empty list is
/// represented with a null pointer.
-AttributeListStorage *AttributeListStorage::get(ArrayRef<NamedAttribute> attrs,
- MLIRContext *context) {
+AttributeListStorage *
+AttributeListStorage::get(ArrayRef<NamedAttribute> attrs) {
// We need to sort the element list to canonicalize it, but we also don't want
// to do a ton of work in the super common case where the element list is
// already sorted.
}
}
- auto &impl = context->getImpl();
+ auto &impl = attrs[0].second.getContext()->getImpl();
// Safely get or create an attribute instance.
return safeGetOrCreate(impl.attributeLists, attrs, impl.attributeMutex, [&] {
ArrayRef<Block *> successors, unsigned numRegions,
bool resizableOperandList, MLIRContext *context) {
return create(location, name, operands, resultTypes,
- NamedAttributeList(context, attributes), successors, numRegions,
+ NamedAttributeList(attributes), successors, numRegions,
resizableOperandList, context);
}
if (!converted)
return failure();
- auto origFuncAttr = FunctionAttr::get(func, context);
- auto convertedFuncAttr = FunctionAttr::get(converted, context);
+ auto origFuncAttr = FunctionAttr::get(func);
+ auto convertedFuncAttr = FunctionAttr::get(converted);
convertedFuncs.push_back(converted);
functionAttrRemapping.insert({origFuncAttr, convertedFuncAttr});
}
}
}
-void mlir::remapFunctionAttrs(
- Operation &op, const DenseMap<Attribute, FunctionAttr> &remappingTable) {
- for (auto attr : op.getAttrs()) {
+static void
+remapFunctionAttrs(NamedAttributeList &attrs,
+ const DenseMap<Attribute, FunctionAttr> &remappingTable) {
+ for (auto attr : attrs.getAttrs()) {
// Do the remapping, if we got the same thing back, then it must contain
// functions that aren't getting remapped.
- auto newVal =
- attr.second.remapFunctionAttrs(remappingTable, op.getContext());
+ auto newVal = attr.second.remapFunctionAttrs(remappingTable);
if (newVal == attr.second)
continue;
// Otherwise, replace the existing attribute with the new one. It is safe
// to mutate the attribute list while we walk it because underlying
// attribute lists are uniqued and immortal.
- op.setAttr(attr.first, newVal);
+ attrs.set(attr.first, newVal);
}
}
void mlir::remapFunctionAttrs(
+ Operation &op, const DenseMap<Attribute, FunctionAttr> &remappingTable) {
+ ::remapFunctionAttrs(op.getAttrList(), remappingTable);
+}
+
+void mlir::remapFunctionAttrs(
Function &fn, const DenseMap<Attribute, FunctionAttr> &remappingTable) {
+ // Remap the attributes of the function.
+ ::remapFunctionAttrs(fn.getAttrList(), remappingTable);
+
+ // Remap the attributes of the arguments of this function.
+ for (auto &attrList : fn.getAllArgAttrs())
+ ::remapFunctionAttrs(attrList, remappingTable);
+
// Look at all operations in a Function.
fn.walk([&](Operation *op) { remapFunctionAttrs(*op, remappingTable); });
}
void mlir::remapFunctionAttrs(
Module &module, const DenseMap<Attribute, FunctionAttr> &remappingTable) {
- for (auto &fn : module) {
+ for (auto &fn : module)
remapFunctionAttrs(fn, remappingTable);
- }
}
%none_val = "foo.unknown_op"() : () -> none
return
}
+
+// CHECK-LABEL: func @fn_attr_remap
+// CHECK: {some_dialect.arg_attr: @fn_attr_ref : () -> ()}
+func @fn_attr_remap(%arg0: i1 {some_dialect.arg_attr: @fn_attr_ref : () -> ()}) -> ()
+ // CHECK-NEXT: {some_dialect.fn_attr: @fn_attr_ref : () -> ()}
+ attributes {some_dialect.fn_attr: @fn_attr_ref : () -> ()} {
+ return
+}
+
+// CHECK-LABEL: func @fn_attr_ref
+func @fn_attr_ref() -> ()
+