Skip to content

Commit

Permalink
[IR] Add additional addParamAttr/removeParamAttr to AttributeList API
Browse files Browse the repository at this point in the history
Summary:
Fairly straightforward patch to fill in some of the holes in the
attributes API with respect to accessing parameter/argument attributes.
The patch aims to step further towards encapsulating the
idx+FirstArgIndex pattern to access these attributes to within the
AttributeList.

Patch by Daniel Neilson!

Reviewers: rnk, chandlerc, pete, javed.absar, reames

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D33355

llvm-svn: 304329
  • Loading branch information
rnk committed May 31, 2017
1 parent 23db636 commit 5fbdd17
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 96 deletions.
197 changes: 148 additions & 49 deletions llvm/include/llvm/IR/Attributes.h
Expand Up @@ -228,34 +228,31 @@ class AttributeSet {
bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; }
bool operator!=(const AttributeSet &O) { return !(*this == O); }

/// Add an argument attribute. Because
/// attribute sets are immutable, this returns a new set.
AttributeSet addAttribute(LLVMContext &C,
Attribute::AttrKind Kind) const;
/// Add an argument attribute. Returns a new set because attribute sets are
/// immutable.
AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const;

/// Add a target-dependent attribute. Because
/// attribute sets are immutable, this returns a new set.
/// Add a target-dependent attribute. Returns a new set because attribute sets
/// are immutable.
AttributeSet addAttribute(LLVMContext &C, StringRef Kind,
StringRef Value = StringRef()) const;

/// Add attributes to the attribute set. Because
/// attribute sets are immutable, this returns a new set.
/// Add attributes to the attribute set. Returns a new set because attribute
/// sets are immutable.
AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const;

/// Remove the specified attribute from this set. Because
/// attribute sets are immutable, this returns a new set.
AttributeSet removeAttribute(LLVMContext &C,
Attribute::AttrKind Kind) const;
/// Remove the specified attribute from this set. Returns a new set because
/// attribute sets are immutable.
AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const;

/// Remove the specified attribute from this set. Because
/// attribute sets are immutable, this returns a new set.
AttributeSet removeAttribute(LLVMContext &C,
StringRef Kind) const;
/// Remove the specified attribute from this set. Returns a new set because
/// attribute sets are immutable.
AttributeSet removeAttribute(LLVMContext &C, StringRef Kind) const;

/// Remove the specified attributes from this set. Because
/// attribute sets are immutable, this returns a new set.
/// Remove the specified attributes from this set. Returns a new set because
/// attribute sets are immutable.
AttributeSet removeAttributes(LLVMContext &C,
const AttrBuilder &AttrsToRemove) const;
const AttrBuilder &AttrsToRemove) const;

/// Return the number of attributes in this set.
unsigned getNumAttributes() const;
Expand Down Expand Up @@ -377,73 +374,138 @@ class AttributeList {
static AttributeList get(LLVMContext &C, unsigned Index,
const AttrBuilder &B);

/// Add an argument attribute to the list. Returns a new list because
/// attribute lists are immutable.
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo,
Attribute::AttrKind Kind) const {
return addAttribute(C, ArgNo + FirstArgIndex, Kind);
}

/// \brief Add an attribute to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
/// \brief Add an attribute to the attribute set at the given index.
/// Returns a new list because attribute lists are immutable.
AttributeList addAttribute(LLVMContext &C, unsigned Index,
Attribute::AttrKind Kind) const;

/// \brief Add an attribute to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
/// \brief Add an attribute to the attribute set at the given index.
/// Returns a new list because attribute lists are immutable.
AttributeList addAttribute(LLVMContext &C, unsigned Index, StringRef Kind,
StringRef Value = StringRef()) const;

/// Add an attribute to the attribute set at the given indices. Because
/// attribute sets are immutable, this returns a new set.
AttributeList addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices,
Attribute A) const;
/// Add an attribute to the attribute set at the given index.
/// Returns a new list because attribute lists are immutable.
AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute A) const;

/// \brief Add attributes to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
/// \brief Add attributes to the attribute set at the given index.
/// Returns a new list because attribute lists are immutable.
AttributeList addAttributes(LLVMContext &C, unsigned Index,
const AttrBuilder &B) const;

/// Add an argument attribute to the list. Returns a new list because
/// attribute lists are immutable.
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo,
Attribute::AttrKind Kind) const {
return addAttribute(C, ArgNo + FirstArgIndex, Kind);
}

/// Add an argument attribute to the list. Returns a new list because
/// attribute lists are immutable.
AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo,
StringRef Kind,
StringRef Value = StringRef()) const {
return addAttribute(C, ArgNo + FirstArgIndex, Kind, Value);
}

/// Add an attribute to the attribute list at the given arg indices. Returns a
/// new list because attribute lists are immutable.
AttributeList addParamAttribute(LLVMContext &C, ArrayRef<unsigned> ArgNos,
Attribute A) const;

/// Add an argument attribute to the list. Returns a new list because
/// attribute lists are immutable.
AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo,
const AttrBuilder &B) const {
return addAttributes(C, ArgNo + FirstArgIndex, B);
}

/// \brief Remove the specified attribute at the specified index from this
/// attribute list. Because attribute lists are immutable, this returns the
/// new list.
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeAttribute(LLVMContext &C, unsigned Index,
Attribute::AttrKind Kind) const;

/// \brief Remove the specified attribute at the specified index from this
/// attribute list. Because attribute lists are immutable, this returns the
/// new list.
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeAttribute(LLVMContext &C, unsigned Index,
StringRef Kind) const;

/// \brief Remove the specified attributes at the specified index from this
/// attribute list. Because attribute lists are immutable, this returns the
/// new list.
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeAttributes(LLVMContext &C, unsigned Index,
const AttrBuilder &AttrsToRemove) const;

/// \brief Remove all attributes at the specified index from this
/// attribute list. Because attribute lists are immutable, this returns the
/// new list.
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeAttributes(LLVMContext &C, unsigned Index) const;

/// \brief Add the dereferenceable attribute to the attribute set at the given
/// index. Because attribute sets are immutable, this returns a new set.
/// \brief Remove the specified attribute at the specified arg index from this
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo,
Attribute::AttrKind Kind) const {
return removeAttribute(C, ArgNo + FirstArgIndex, Kind);
}

/// \brief Remove the specified attribute at the specified arg index from this
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeParamAttribute(LLVMContext &C, unsigned ArgNo,
StringRef Kind) const {
return removeAttribute(C, ArgNo + FirstArgIndex, Kind);
}

/// \brief Remove the specified attribute at the specified arg index from this
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo,
const AttrBuilder &AttrsToRemove) const {
return removeAttributes(C, ArgNo + FirstArgIndex, AttrsToRemove);
}

/// \brief Remove all attributes at the specified arg index from this
/// attribute list. Returns a new list because attribute lists are immutable.
AttributeList removeParamAttributes(LLVMContext &C, unsigned ArgNo) const {
return removeAttributes(C, ArgNo + FirstArgIndex);
}

/// \Brief Add the dereferenceable attribute to the attribute set at the given
/// index. Returns a new list because attribute lists are immutable.
AttributeList addDereferenceableAttr(LLVMContext &C, unsigned Index,
uint64_t Bytes) const;

/// \Brief Add the dereferenceable attribute to the attribute set at the given
/// arg index. Returns a new list because attribute lists are immutable.
AttributeList addDereferenceableParamAttr(LLVMContext &C, unsigned ArgNo,
uint64_t Bytes) const {
return addDereferenceableAttr(C, ArgNo + FirstArgIndex, Bytes);
}

/// \brief Add the dereferenceable_or_null attribute to the attribute set at
/// the given index. Because attribute sets are immutable, this returns a new
/// set.
/// the given index. Returns a new list because attribute lists are immutable.
AttributeList addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
uint64_t Bytes) const;

/// \brief Add the dereferenceable_or_null attribute to the attribute set at
/// the given arg index. Returns a new list because attribute lists are
/// immutable.
AttributeList addDereferenceableOrNullParamAttr(LLVMContext &C,
unsigned ArgNo,
uint64_t Bytes) const {
return addDereferenceableOrNullAttr(C, ArgNo + FirstArgIndex, Bytes);
}

/// Add the allocsize attribute to the attribute set at the given index.
/// Because attribute sets are immutable, this returns a new set.
/// Returns a new list because attribute lists are immutable.
AttributeList addAllocSizeAttr(LLVMContext &C, unsigned Index,
unsigned ElemSizeArg,
const Optional<unsigned> &NumElemsArg);

/// Add the allocsize attribute to the attribute set at the given arg index.
/// Returns a new list because attribute lists are immutable.
AttributeList addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo,
unsigned ElemSizeArg,
const Optional<unsigned> &NumElemsArg) {
return addAllocSizeAttr(C, ArgNo + FirstArgIndex, ElemSizeArg, NumElemsArg);
}

//===--------------------------------------------------------------------===//
// AttributeList Accessors
//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -473,6 +535,21 @@ class AttributeList {
/// \brief Return true if attribute exists at the given index.
bool hasAttributes(unsigned Index) const;

/// \brief Return true if the attribute exists for the given argument
bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
return hasAttribute(ArgNo + FirstArgIndex, Kind);
}

/// \brief Return true if the attribute exists for the given argument
bool hasParamAttr(unsigned ArgNo, StringRef Kind) const {
return hasAttribute(ArgNo + FirstArgIndex, Kind);
}

/// \brief Return true if attributes exists for the given argument
bool hasParamAttrs(unsigned ArgNo) const {
return hasAttributes(ArgNo + FirstArgIndex);
}

/// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but
/// may be faster.
bool hasFnAttribute(Attribute::AttrKind Kind) const;
Expand All @@ -496,6 +573,16 @@ class AttributeList {
/// \brief Return the attribute object that exists at the given index.
Attribute getAttribute(unsigned Index, StringRef Kind) const;

/// \brief Return the attribute object that exists at the arg index.
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
return getAttribute(ArgNo + FirstArgIndex, Kind);
}

/// \brief Return the attribute object that exists at the given index.
Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const {
return getAttribute(ArgNo + FirstArgIndex, Kind);
}

/// \brief Return the alignment of the return value.
unsigned getRetAlignment() const;

Expand All @@ -508,10 +595,22 @@ class AttributeList {
/// \brief Get the number of dereferenceable bytes (or zero if unknown).
uint64_t getDereferenceableBytes(unsigned Index) const;

/// \brief Get the number of dereferenceable bytes (or zero if unknown) of an
/// arg.
uint64_t getParamDereferenceableBytes(unsigned ArgNo) const {
return getDereferenceableBytes(ArgNo + FirstArgIndex);
}

/// \brief Get the number of dereferenceable_or_null bytes (or zero if
/// unknown).
uint64_t getDereferenceableOrNullBytes(unsigned Index) const;

/// \brief Get the number of dereferenceable_or_null bytes (or zero if
/// unknown) of an arg.
uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const {
return getDereferenceableOrNullBytes(ArgNo + FirstArgIndex);
}

/// Get the allocsize argument numbers (or pair(0, 0) if unknown).
std::pair<unsigned, Optional<unsigned>>
getAllocSizeArgs(unsigned Index) const;
Expand Down
47 changes: 39 additions & 8 deletions llvm/include/llvm/IR/Function.h
Expand Up @@ -214,10 +214,6 @@ class Function : public GlobalObject, public ilist_node<Function> {
addAttribute(AttributeList::FunctionIndex, Attr);
}

void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
addAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
}

/// @brief Remove function attributes from this function.
void removeFnAttr(Attribute::AttrKind Kind) {
removeAttribute(AttributeList::FunctionIndex, Kind);
Expand All @@ -229,10 +225,6 @@ class Function : public GlobalObject, public ilist_node<Function> {
getContext(), AttributeList::FunctionIndex, Kind));
}

void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
removeAttribute(ArgNo + AttributeList::FirstArgIndex, Kind);
}

/// \brief Set the entry count for this function.
///
/// Entry count is the number of times this function was executed based on
Expand Down Expand Up @@ -299,6 +291,15 @@ class Function : public GlobalObject, public ilist_node<Function> {
/// @brief adds the attributes to the list of attributes.
void addAttributes(unsigned i, const AttrBuilder &Attrs);

/// @brief adds the attribute to the list of attributes for the given arg.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);

/// @brief adds the attribute to the list of attributes for the given arg.
void addParamAttr(unsigned ArgNo, Attribute Attr);

/// @brief adds the attributes to the list of attributes for the given arg.
void addParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs);

/// @brief removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute::AttrKind Kind);

Expand All @@ -308,6 +309,15 @@ class Function : public GlobalObject, public ilist_node<Function> {
/// @brief removes the attributes from the list of attributes.
void removeAttributes(unsigned i, const AttrBuilder &Attrs);

/// @brief removes the attribute from the list of attributes.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);

/// @brief removes the attribute from the list of attributes.
void removeParamAttr(unsigned ArgNo, StringRef Kind);

/// @brief removes the attribute from the list of attributes.
void removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs);

/// @brief check if an attributes is in the list of attributes.
bool hasAttribute(unsigned i, Attribute::AttrKind Kind) const {
return getAttributes().hasAttribute(i, Kind);
Expand All @@ -329,10 +339,18 @@ class Function : public GlobalObject, public ilist_node<Function> {
/// @brief adds the dereferenceable attribute to the list of attributes.
void addDereferenceableAttr(unsigned i, uint64_t Bytes);

/// @brief adds the dereferenceable attribute to the list of attributes for
/// the given arg.
void addDereferenceableParamAttr(unsigned ArgNo, uint64_t Bytes);

/// @brief adds the dereferenceable_or_null attribute to the list of
/// attributes.
void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);

/// @brief adds the dereferenceable_or_null attribute to the list of
/// attributes for the given arg.
void addDereferenceableOrNullParamAttr(unsigned ArgNo, uint64_t Bytes);

/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned ArgNo) const {
return AttributeSets.getParamAlignment(ArgNo);
Expand All @@ -345,13 +363,26 @@ class Function : public GlobalObject, public ilist_node<Function> {
return AttributeSets.getDereferenceableBytes(i);
}

/// @brief Extract the number of dereferenceable bytes for a parameter.
/// @param ArgNo Index of an argument, with 0 being the first function arg.
uint64_t getParamDereferenceableBytes(unsigned ArgNo) const {
return AttributeSets.getParamDereferenceableBytes(ArgNo);
}

/// @brief Extract the number of dereferenceable_or_null bytes for a call or
/// parameter (0=unknown).
/// @param i AttributeList index, referring to a return value or argument.
uint64_t getDereferenceableOrNullBytes(unsigned i) const {
return AttributeSets.getDereferenceableOrNullBytes(i);
}

/// @brief Extract the number of dereferenceable_or_null bytes for a
/// parameter.
/// @param ArgNo AttributeList ArgNo, referring to an argument.
uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const {
return AttributeSets.getParamDereferenceableOrNullBytes(ArgNo);
}

/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
return hasFnAttribute(Attribute::ReadNone);
Expand Down

0 comments on commit 5fbdd17

Please sign in to comment.