Skip to content

Commit

Permalink
Make sure we have a Add/Remove/Has function for various thing that ca…
Browse files Browse the repository at this point in the history
…n have attribute.

Summary: This also deprecated the get attribute function familly.

Reviewers: Wallbraker, whitequark, joker.eph, echristo, rafael, jyknight

Subscribers: axw, joker.eph, llvm-commits

Differential Revision: http://reviews.llvm.org/D19181

llvm-svn: 272504
  • Loading branch information
deadalnix committed Jun 12, 2016
1 parent adc7939 commit 5db224e
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 15 deletions.
8 changes: 6 additions & 2 deletions llvm/docs/ReleaseNotes.rst
Expand Up @@ -54,8 +54,12 @@ Non-comprehensive list of changes in this release
* The C API function LLVMGetDataLayout is deprecated
in favor of LLVMGetDataLayoutStr.

* The C API enum LLVMAttribute is deprecated in favor of
LLVMGetAttributeKindForName.
* The C API enum LLVMAttribute and associated API is deprecated in favor of
the new LLVMAttributeRef API. The deprecated functions are
LLVMAddFunctionAttr, LLVMAddTargetDependentFunctionAttr,
LLVMRemoveFunctionAttr, LLVMGetFunctionAttr, LLVMAddAttribute,
LLVMRemoveAttribute, LLVMGetAttribute, LLVMAddInstrAttribute and
LLVMRemoveInstrAttribute.

* ``TargetFrameLowering::eliminateCallFramePseudoInstr`` now returns an
iterator to the next instruction instead of ``void``. Targets that previously
Expand Down
67 changes: 65 additions & 2 deletions llvm/include/llvm-c/Core.h
Expand Up @@ -380,6 +380,20 @@ typedef enum {
LLVMDSNote
} LLVMDiagnosticSeverity;

/**
* Attribute index are either LLVMAttributeReturnIndex,
* LLVMAttributeFunctionIndex or a parameter number from 1 to N.
*/
enum {
LLVMAttributeReturnIndex = 0U,
// ISO C restricts enumerator values to range of 'int'
// (4294967295 is too large)
// LLVMAttributeFunctionIndex = ~0U,
LLVMAttributeFunctionIndex = -1,
};

typedef unsigned LLVMAttributeIndex;

/**
* @}
*/
Expand Down Expand Up @@ -477,7 +491,7 @@ unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char *Name,
unsigned LLVMGetMDKindID(const char *Name, unsigned SLen);

/**
* Return an unique id given the name of a target independent attribute,
* Return an unique id given the name of a enum attribute,
* or 0 if no attribute by that name exists.
*
* See http://llvm.org/docs/LangRef.html#parameter-attributes
Expand All @@ -487,7 +501,48 @@ unsigned LLVMGetMDKindID(const char *Name, unsigned SLen);
* NB: Attribute names and/or id are subject to change without
* going through the C API deprecation cycle.
*/
unsigned LLVMGetAttributeKindForName(const char *Name, size_t SLen);
unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen);
unsigned LLVMGetLastEnumAttributeKind();

/**
* Create an enum attribute.
*/
LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID,
uint64_t Val);

/**
* Get the unique id corresponding to the enum attribute
* passed as argument.
*/
unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A);

/**
* Get the enum attribute's value. 0 is returned if none exists.
*/
uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A);

/**
* Create a string attribute.
*/
LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
const char *K, unsigned KLength,
const char *V, unsigned VLength);

/**
* Get the string attribute's kind.
*/
const char *LLVMGetStringAttributeKind(LLVMAttributeRef A, unsigned *Length);

/**
* Get the string attribute's value.
*/
const char *LLVMGetStringAttributeValue(LLVMAttributeRef A, unsigned *Length);

/**
* Check for the different types of attributes.
*/
LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A);
LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A);

/**
* @}
Expand Down Expand Up @@ -1957,6 +2012,14 @@ void LLVMSetGC(LLVMValueRef Fn, const char *Name);
*/
void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);

void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
LLVMAttributeRef A);
LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F,
LLVMAttributeIndex Idx,
unsigned KindID);
void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
unsigned KindID);

/**
* Add a target-dependent attribute to a function
* @see llvm::AttrBuilder::addAttribute()
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm-c/Types.h
Expand Up @@ -108,6 +108,13 @@ typedef struct LLVMOpaquePassRegistry *LLVMPassRegistryRef;
* @see llvm::Use */
typedef struct LLVMOpaqueUse *LLVMUseRef;

/**
* Used to represent an attributes.
*
* @see llvm::Attribute
*/
typedef struct LLVMOpaqueAttributeRef *LLVMAttributeRef;

/**
* @see llvm::DiagnosticInfo
*/
Expand Down
21 changes: 21 additions & 0 deletions llvm/include/llvm/IR/Attributes.h
Expand Up @@ -21,6 +21,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm-c/Types.h"
#include <bitset>
#include <cassert>
#include <map>
Expand Down Expand Up @@ -169,8 +170,28 @@ class Attribute {
void Profile(FoldingSetNodeID &ID) const {
ID.AddPointer(pImpl);
}

/// \brief Return a raw pointer that uniquely identifies this attribute.
void *getRawPointer() const {
return pImpl;
}

/// \brief Get an attribute from a raw pointer created by getRawPointer.
static Attribute fromRawPointer(void *RawPtr) {
return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr));
}
};

// Specialized opaque value conversions.
inline LLVMAttributeRef wrap(Attribute Attr) {
return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer());
}

// Specialized opaque value conversions.
inline Attribute unwrap(LLVMAttributeRef Attr) {
return Attribute::fromRawPointer(Attr);
}

//===----------------------------------------------------------------------===//
/// \class
/// \brief This class holds the attributes for a function, its return value, and
Expand Down
17 changes: 13 additions & 4 deletions llvm/include/llvm/IR/Function.h
Expand Up @@ -205,12 +205,10 @@ class Function : public GlobalObject, public ilist_node<Function> {

/// @brief Return the attribute for the given attribute kind.
Attribute getFnAttribute(Attribute::AttrKind Kind) const {
if (!hasFnAttribute(Kind))
return Attribute();
return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
return getAttribute(AttributeSet::FunctionIndex, Kind);
}
Attribute getFnAttribute(StringRef Kind) const {
return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
return getAttribute(AttributeSet::FunctionIndex, Kind);
}

/// \brief Return the stack alignment for the function.
Expand All @@ -232,6 +230,9 @@ class Function : public GlobalObject, public ilist_node<Function> {
/// @brief adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute::AttrKind attr);

/// @brief adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attribute Attr);

/// @brief adds the attributes to the list of attributes.
void addAttributes(unsigned i, AttributeSet attrs);

Expand All @@ -246,6 +247,14 @@ class Function : public GlobalObject, public ilist_node<Function> {
return getAttributes().hasAttribute(i, attr);
}

Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
return AttributeSets.getAttribute(i, Kind);
}

Attribute getAttribute(unsigned i, StringRef Kind) const {
return AttributeSets.getAttribute(i, Kind);
}

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

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/IR/AttributeImpl.h
Expand Up @@ -177,6 +177,9 @@ class AttributeSetNode final

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;
}
Expand Down
70 changes: 68 additions & 2 deletions llvm/lib/IR/Core.cpp
Expand Up @@ -124,10 +124,60 @@ unsigned LLVMGetMDKindID(const char *Name, unsigned SLen) {
#define GET_ATTR_KIND_FROM_NAME
#include "AttributesCompatFunc.inc"

unsigned LLVMGetAttributeKindForName(const char *Name, size_t SLen) {
unsigned LLVMGetEnumAttributeKindForName(const char *Name, size_t SLen) {
return getAttrKindFromName(StringRef(Name, SLen));
}

unsigned LLVMGetLastEnumAttributeKind() {
return Attribute::AttrKind::EndAttrKinds;
}

LLVMAttributeRef LLVMCreateEnumAttribute(LLVMContextRef C, unsigned KindID,
uint64_t Val) {
return wrap(Attribute::get(*unwrap(C), (Attribute::AttrKind)KindID, Val));
}

unsigned LLVMGetEnumAttributeKind(LLVMAttributeRef A) {
return unwrap(A).getKindAsEnum();
}

uint64_t LLVMGetEnumAttributeValue(LLVMAttributeRef A) {
auto Attr = unwrap(A);
if (Attr.isEnumAttribute())
return 0;
return Attr.getValueAsInt();
}

LLVMAttributeRef LLVMCreateStringAttribute(LLVMContextRef C,
const char *K, unsigned KLength,
const char *V, unsigned VLength) {
return wrap(Attribute::get(*unwrap(C), StringRef(K, KLength),
StringRef(V, VLength)));
}

const char *LLVMGetStringAttributeKind(LLVMAttributeRef A,
unsigned *Length) {
auto S = unwrap(A).getKindAsString();
*Length = S.size();
return S.data();
}

const char *LLVMGetStringAttributeValue(LLVMAttributeRef A,
unsigned *Length) {
auto S = unwrap(A).getValueAsString();
*Length = S.size();
return S.data();
}

LLVMBool LLVMIsEnumAttribute(LLVMAttributeRef A) {
auto Attr = unwrap(A);
return Attr.isEnumAttribute() || Attr.isIntAttribute();
}

LLVMBool LLVMIsStringAttribute(LLVMAttributeRef A) {
return unwrap(A).isStringAttribute();
}

char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) {
std::string MsgStorage;
raw_string_ostream Stream(MsgStorage);
Expand Down Expand Up @@ -1789,6 +1839,23 @@ void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
Func->setAttributes(PALnew);
}

void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
LLVMAttributeRef A) {
unwrap<Function>(F)->addAttribute(Idx, unwrap(A));
}

LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F,
LLVMAttributeIndex Idx,
unsigned KindID) {
return wrap(unwrap<Function>(F)->getAttribute(Idx,
(Attribute::AttrKind)KindID));
}

void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
unsigned KindID) {
unwrap<Function>(F)->removeAttribute(Idx, (Attribute::AttrKind)KindID);
}

void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A,
const char *V) {
Function *Func = unwrap<Function>(Fn);
Expand Down Expand Up @@ -1894,7 +1961,6 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) {
Raw(A->getArgNo()+1);
}


void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) {
Argument *A = unwrap<Argument>(Arg);
AttrBuilder B;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/IR/Function.cpp
Expand Up @@ -372,6 +372,12 @@ void Function::addAttribute(unsigned i, Attribute::AttrKind attr) {
setAttributes(PAL);
}

void Function::addAttribute(unsigned i, Attribute Attr) {
AttributeSet PAL = getAttributes();
PAL = PAL.addAttribute(getContext(), i, Attr);
setAttributes(PAL);
}

void Function::addAttributes(unsigned i, AttributeSet attrs) {
AttributeSet PAL = getAttributes();
PAL = PAL.addAttributes(getContext(), i, attrs);
Expand Down
9 changes: 5 additions & 4 deletions llvm/test/Bindings/llvm-c/invoke.ll
Expand Up @@ -70,13 +70,14 @@ unwind7: ; preds = %unwind5

declare void @_D6object6Object6__ctorFMC6object6ObjectZv(%C6object6Object*)

declare i8* @_d_allocmemory(i64)
declare noalias i8* @_d_allocmemory(i64)

declare i32 @__sd_eh_personality(i32, i32, i64, i8*, i8*)

declare void @__sd_eh_throw(%C6object9Throwable*)
declare void @__sd_eh_throw(%C6object9Throwable* nonnull) #0

; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) #0
declare i32 @llvm.eh.typeid.for(i8*) #1

attributes #0 = { nounwind readnone }
attributes #0 = { noreturn }
attributes #1 = { nounwind readnone }
17 changes: 16 additions & 1 deletion llvm/tools/llvm-c-test/echo.cpp
Expand Up @@ -782,13 +782,28 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
return;
}

auto Ctx = LLVMGetModuleContext(M);

Cur = Begin;
Next = nullptr;
while (true) {
const char *Name = LLVMGetValueName(Cur);
if (LLVMGetNamedFunction(M, Name))
report_fatal_error("Function already cloned");
LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur)));
auto Ty = LLVMGetElementType(TypeCloner(M).Clone(Cur));
auto F = LLVMAddFunction(M, Name, Ty);

// Copy attributes
for (int i = LLVMAttributeFunctionIndex, c = LLVMCountParams(F);
i <= c; ++i) {
for (unsigned k = 0, e = LLVMGetLastEnumAttributeKind(); k < e; ++k) {
if (auto SrcA = LLVMGetEnumAttributeAtIndex(Cur, i, k)) {
auto Val = LLVMGetEnumAttributeValue(SrcA);
auto DstA = LLVMCreateEnumAttribute(Ctx, k, Val);
LLVMAddAttributeAtIndex(F, i, DstA);
}
}
}

Next = LLVMGetNextFunction(Cur);
if (Next == nullptr) {
Expand Down

0 comments on commit 5db224e

Please sign in to comment.