Skip to content

Commit

Permalink
Merging r276236 and r276237:
Browse files Browse the repository at this point in the history
------------------------------------------------------------------------
r276236 | deadalnix | 2016-07-20 21:25:06 -0700 (Wed, 20 Jul 2016) | 9 lines

Expose AttributeSetNode, use it to provide aggregate getter for attribute in the C API.

Summary: See D19181 for context.

Reviewers: whitequark, Wallbraker, jyknight, echristo, bkramer, void

Subscribers: mehdi_amini

Differential Revision: http://reviews.llvm.org/D21265
------------------------------------------------------------------------

------------------------------------------------------------------------
r276237 | deadalnix | 2016-07-20 21:31:38 -0700 (Wed, 20 Jul 2016) | 1 line

Add missing import to fix the build
------------------------------------------------------------------------

llvm-svn: 276663
  • Loading branch information
zmodem committed Jul 25, 2016
1 parent aaa653d commit a487e1a
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 68 deletions.
6 changes: 6 additions & 0 deletions llvm/include/llvm-c/Core.h
Expand Up @@ -2014,6 +2014,9 @@ void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);

void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
LLVMAttributeRef A);
unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx);
void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
LLVMAttributeRef *Attrs);
LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F,
LLVMAttributeIndex Idx,
unsigned KindID);
Expand Down Expand Up @@ -2600,6 +2603,9 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,

void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
LLVMAttributeRef A);
unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx);
void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
LLVMAttributeRef *Attrs);
LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C,
LLVMAttributeIndex Idx,
unsigned KindID);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/Attributes.h
Expand Up @@ -210,6 +210,7 @@ class AttributeSet {
private:
friend class AttrBuilder;
friend class AttributeSetImpl;
friend class AttributeSetNode;
template <typename Ty> friend struct DenseMapInfo;

/// \brief The attributes that we are managing. This can be null to represent
Expand Down
69 changes: 1 addition & 68 deletions llvm/lib/IR/AttributeImpl.h
Expand Up @@ -19,8 +19,8 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/IR/Attributes.h"
#include "AttributeSetNode.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TrailingObjects.h"
#include <climits>
#include <string>

Expand Down Expand Up @@ -142,73 +142,6 @@ class StringAttributeImpl : public AttributeImpl {
StringRef getStringValue() const { return Val; }
};

//===----------------------------------------------------------------------===//
/// \class
/// \brief This class represents a group of attributes that apply to one
/// element: function, return type, or parameter.
class AttributeSetNode final
: public FoldingSetNode,
private TrailingObjects<AttributeSetNode, Attribute> {
friend TrailingObjects;

unsigned NumAttrs; ///< Number of attributes in this node.
/// Bitset with a bit for each available attribute Attribute::AttrKind.
uint64_t AvailableAttrs;

AttributeSetNode(ArrayRef<Attribute> Attrs)
: NumAttrs(Attrs.size()), AvailableAttrs(0) {
static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
"Too many attributes for AvailableAttrs");
// There's memory after the node where we can store the entries in.
std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());

for (Attribute I : *this) {
if (!I.isStringAttribute()) {
AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
}
}
}

// AttributesSetNode is uniqued, these should not be publicly available.
void operator=(const AttributeSetNode &) = delete;
AttributeSetNode(const AttributeSetNode &) = delete;
public:
void operator delete(void *p) { ::operator delete(p); }

static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);

/// \brief Return the number of attributes this AttributeSet contains.
unsigned getNumAttributes() const { return NumAttrs; }

bool hasAttribute(Attribute::AttrKind Kind) const {
return AvailableAttrs & ((uint64_t)1) << Kind;
}
bool hasAttribute(StringRef Kind) const;
bool hasAttributes() const { return NumAttrs != 0; }

Attribute getAttribute(Attribute::AttrKind Kind) const;
Attribute getAttribute(StringRef Kind) const;

unsigned getAlignment() const;
unsigned getStackAlignment() const;
uint64_t getDereferenceableBytes() const;
uint64_t getDereferenceableOrNullBytes() const;
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
std::string getAsString(bool InAttrGrp) const;

typedef const Attribute *iterator;
iterator begin() const { return getTrailingObjects<Attribute>(); }
iterator end() const { return begin() + NumAttrs; }

void Profile(FoldingSetNodeID &ID) const {
Profile(ID, makeArrayRef(begin(), end()));
}
static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
for (unsigned I = 0, E = AttrList.size(); I != E; ++I)
AttrList[I].Profile(ID);
}
};

typedef std::pair<unsigned, AttributeSetNode *> IndexAttrPair;

//===----------------------------------------------------------------------===//
Expand Down
98 changes: 98 additions & 0 deletions llvm/lib/IR/AttributeSetNode.h
@@ -0,0 +1,98 @@
//===-- AttributeSetNode.h - AttributeSet Internal Node ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file defines the node class used internally by AttributeSet.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_ATTRIBUTESETNODE_H
#define LLVM_IR_ATTRIBUTESETNODE_H

#include "llvm/ADT/FoldingSet.h"
#include "llvm/IR/Attributes.h"
#include "llvm/Support/TrailingObjects.h"
#include <climits>

namespace llvm {

//===----------------------------------------------------------------------===//
/// \class
/// \brief This class represents a group of attributes that apply to one
/// element: function, return type, or parameter.
class AttributeSetNode final
: public FoldingSetNode,
private TrailingObjects<AttributeSetNode, Attribute> {
friend TrailingObjects;

unsigned NumAttrs; ///< Number of attributes in this node.
/// Bitset with a bit for each available attribute Attribute::AttrKind.
uint64_t AvailableAttrs;

AttributeSetNode(ArrayRef<Attribute> Attrs)
: NumAttrs(Attrs.size()), AvailableAttrs(0) {
static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
"Too many attributes for AvailableAttrs");
// There's memory after the node where we can store the entries in.
std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());

for (Attribute I : *this) {
if (!I.isStringAttribute()) {
AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
}
}
}

// AttributesSetNode is uniqued, these should not be publicly available.
void operator=(const AttributeSetNode &) = delete;
AttributeSetNode(const AttributeSetNode &) = delete;
public:
void operator delete(void *p) { ::operator delete(p); }

static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);

static AttributeSetNode *get(AttributeSet AS, unsigned Index) {
return AS.getAttributes(Index);
}

/// \brief Return the number of attributes this AttributeSet contains.
unsigned getNumAttributes() const { return NumAttrs; }

bool hasAttribute(Attribute::AttrKind Kind) const {
return AvailableAttrs & ((uint64_t)1) << Kind;
}
bool hasAttribute(StringRef Kind) const;
bool hasAttributes() const { return NumAttrs != 0; }

Attribute getAttribute(Attribute::AttrKind Kind) const;
Attribute getAttribute(StringRef Kind) const;

unsigned getAlignment() const;
unsigned getStackAlignment() const;
uint64_t getDereferenceableBytes() const;
uint64_t getDereferenceableOrNullBytes() const;
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
std::string getAsString(bool InAttrGrp) const;

typedef const Attribute *iterator;
iterator begin() const { return getTrailingObjects<Attribute>(); }
iterator end() const { return begin() + NumAttrs; }

void Profile(FoldingSetNodeID &ID) const {
Profile(ID, makeArrayRef(begin(), end()));
}
static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
for (unsigned I = 0, E = AttrList.size(); I != E; ++I)
AttrList[I].Profile(ID);
}
};

} // end llvm namespace

#endif
28 changes: 28 additions & 0 deletions llvm/lib/IR/Core.cpp
Expand Up @@ -16,6 +16,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Attributes.h"
#include "AttributeSetNode.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
Expand Down Expand Up @@ -1844,6 +1845,18 @@ void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
unwrap<Function>(F)->addAttribute(Idx, unwrap(A));
}

unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) {
auto *ASN = AttributeSetNode::get(unwrap<Function>(F)->getAttributes(), Idx);
return ASN->getNumAttributes();
}

void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
LLVMAttributeRef *Attrs) {
auto *ASN = AttributeSetNode::get(unwrap<Function>(F)->getAttributes(), Idx);
for (auto A: make_range(ASN->begin(), ASN->end()))
*Attrs++ = wrap(A);
}

LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F,
LLVMAttributeIndex Idx,
unsigned KindID) {
Expand Down Expand Up @@ -2216,6 +2229,21 @@ void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
CallSite(unwrap<Instruction>(C)).addAttribute(Idx, unwrap(A));
}

unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C,
LLVMAttributeIndex Idx) {
auto CS = CallSite(unwrap<Instruction>(C));
auto *ASN = AttributeSetNode::get(CS.getAttributes(), Idx);
return ASN->getNumAttributes();
}

void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
LLVMAttributeRef *Attrs) {
auto CS = CallSite(unwrap<Instruction>(C));
auto *ASN = AttributeSetNode::get(CS.getAttributes(), Idx);
for (auto A: make_range(ASN->begin(), ASN->end()))
*Attrs++ = wrap(A);
}

LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C,
LLVMAttributeIndex Idx,
unsigned KindID) {
Expand Down

0 comments on commit a487e1a

Please sign in to comment.