mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-17 11:39:11 +00:00
[IR] Add AttributeSet to hide AttributeSetNode* again, NFC
Summary: For now, it just wraps AttributeSetNode*. Eventually, it will hold AvailableAttrs as an inline bitset, and adding and removing enum attributes will be super cheap. This sinks AttributeSetNode back down to lib/IR/AttributeImpl.h. Reviewers: pete, chandlerc Subscribers: llvm-commits, jfb Differential Revision: https://reviews.llvm.org/D31940 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300014 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
824c3767b3
commit
06090406b0
@ -1,93 +0,0 @@
|
|||||||
//===-- AttributeSetNode.h - AttributeList 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 class that represents a group of attributes
|
|
||||||
/// that apply to one element: function, return type, or parameter.
|
|
||||||
///
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef LLVM_IR_ATTRIBUTESETNODE_H
|
|
||||||
#define LLVM_IR_ATTRIBUTESETNODE_H
|
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
|
||||||
#include "llvm/ADT/Optional.h"
|
|
||||||
#include "llvm/ADT/StringRef.h"
|
|
||||||
#include "llvm/IR/Attributes.h"
|
|
||||||
#include "llvm/Support/TrailingObjects.h"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// AttributesSetNode is uniqued, these should not be available.
|
|
||||||
AttributeSetNode(const AttributeSetNode &) = delete;
|
|
||||||
AttributeSetNode &operator=(const AttributeSetNode &) = delete;
|
|
||||||
|
|
||||||
void operator delete(void *p) { ::operator delete(p); }
|
|
||||||
|
|
||||||
static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);
|
|
||||||
|
|
||||||
static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
|
|
||||||
|
|
||||||
/// \brief Return the number of attributes this AttributeList 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 (const auto &Attr : AttrList)
|
|
||||||
Attr.Profile(ID);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace llvm
|
|
||||||
|
|
||||||
#endif // LLVM_IR_ATTRIBUTESETNODE_H
|
|
@ -195,6 +195,84 @@ inline Attribute unwrap(LLVMAttributeRef Attr) {
|
|||||||
return Attribute::fromRawPointer(Attr);
|
return Attribute::fromRawPointer(Attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
/// \class
|
||||||
|
/// This class holds the attributes for a particular argument, parameter,
|
||||||
|
/// function, or return value. It is an immutable value type that is cheap to
|
||||||
|
/// copy. Adding and removing enum attributes is intended to be fast, but adding
|
||||||
|
/// and removing string or integer attributes involves a FoldingSet lookup.
|
||||||
|
class AttributeSet {
|
||||||
|
// TODO: Extract AvailableAttrs from AttributeSetNode and store them here.
|
||||||
|
// This will allow an efficient implementation of addAttribute and
|
||||||
|
// removeAttribute for enum attrs.
|
||||||
|
|
||||||
|
/// Private implementation pointer.
|
||||||
|
AttributeSetNode *SetNode = nullptr;
|
||||||
|
|
||||||
|
friend AttributeListImpl;
|
||||||
|
template <typename Ty> friend struct DenseMapInfo;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// AttributeSet is a trivially copyable value type.
|
||||||
|
AttributeSet() = default;
|
||||||
|
AttributeSet(const AttributeSet &) = default;
|
||||||
|
~AttributeSet() = default;
|
||||||
|
|
||||||
|
static AttributeSet get(LLVMContext &C, const AttrBuilder &B);
|
||||||
|
static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs);
|
||||||
|
|
||||||
|
bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; }
|
||||||
|
bool operator!=(const AttributeSet &O) { return !(*this == O); }
|
||||||
|
|
||||||
|
unsigned getNumAttributes() const;
|
||||||
|
|
||||||
|
bool hasAttributes() const { return SetNode != nullptr; }
|
||||||
|
|
||||||
|
bool hasAttribute(Attribute::AttrKind Kind) const;
|
||||||
|
bool hasAttribute(StringRef Kind) const;
|
||||||
|
|
||||||
|
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;
|
||||||
|
iterator end() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
/// \class
|
||||||
|
/// \brief Provide DenseMapInfo for AttributeSet.
|
||||||
|
template <> struct DenseMapInfo<AttributeSet> {
|
||||||
|
static inline AttributeSet getEmptyKey() {
|
||||||
|
uintptr_t Val = static_cast<uintptr_t>(-1);
|
||||||
|
Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
|
||||||
|
return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline AttributeSet getTombstoneKey() {
|
||||||
|
uintptr_t Val = static_cast<uintptr_t>(-2);
|
||||||
|
Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
|
||||||
|
return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned getHashValue(AttributeSet AS) {
|
||||||
|
return (unsigned((uintptr_t)AS.SetNode) >> 4) ^
|
||||||
|
(unsigned((uintptr_t)AS.SetNode) >> 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
|
||||||
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// \class
|
/// \class
|
||||||
/// \brief This class holds the attributes for a function, its return value, and
|
/// \brief This class holds the attributes for a function, its return value, and
|
||||||
@ -213,6 +291,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
friend class AttrBuilder;
|
friend class AttrBuilder;
|
||||||
friend class AttributeListImpl;
|
friend class AttributeListImpl;
|
||||||
|
friend class AttributeSet;
|
||||||
friend class AttributeSetNode;
|
friend class AttributeSetNode;
|
||||||
|
|
||||||
template <typename Ty> friend struct DenseMapInfo;
|
template <typename Ty> friend struct DenseMapInfo;
|
||||||
@ -226,7 +305,7 @@ public:
|
|||||||
static AttributeList get(LLVMContext &C,
|
static AttributeList get(LLVMContext &C,
|
||||||
ArrayRef<std::pair<unsigned, Attribute>> Attrs);
|
ArrayRef<std::pair<unsigned, Attribute>> Attrs);
|
||||||
static AttributeList
|
static AttributeList
|
||||||
get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs);
|
get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
|
||||||
|
|
||||||
/// \brief Create an AttributeList from a vector of AttributeSetNodes. The
|
/// \brief Create an AttributeList from a vector of AttributeSetNodes. The
|
||||||
/// index of each set is implied by its position in the array \p Attrs:
|
/// index of each set is implied by its position in the array \p Attrs:
|
||||||
@ -234,11 +313,11 @@ public:
|
|||||||
/// 1 to n-1 : Argument attributes
|
/// 1 to n-1 : Argument attributes
|
||||||
/// n : Function attributes
|
/// n : Function attributes
|
||||||
/// Any element that has no entries should be left null.
|
/// Any element that has no entries should be left null.
|
||||||
static AttributeList get(LLVMContext &C, ArrayRef<AttributeSetNode *> Attrs);
|
static AttributeList get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
|
||||||
|
|
||||||
static AttributeList
|
static AttributeList
|
||||||
getImpl(LLVMContext &C,
|
getImpl(LLVMContext &C,
|
||||||
ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs);
|
ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
|
explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
|
||||||
@ -280,7 +359,7 @@ public:
|
|||||||
AttributeList Attrs) const;
|
AttributeList Attrs) const;
|
||||||
|
|
||||||
AttributeList addAttributes(LLVMContext &C, unsigned Index,
|
AttributeList addAttributes(LLVMContext &C, unsigned Index,
|
||||||
AttributeSetNode *AS) const;
|
AttributeSet AS) const;
|
||||||
|
|
||||||
AttributeList addAttributes(LLVMContext &C, unsigned Index,
|
AttributeList addAttributes(LLVMContext &C, unsigned Index,
|
||||||
const AttrBuilder &B) const;
|
const AttrBuilder &B) const;
|
||||||
@ -339,16 +418,16 @@ public:
|
|||||||
LLVMContext &getContext() const;
|
LLVMContext &getContext() const;
|
||||||
|
|
||||||
/// \brief The attributes for the specified index are returned.
|
/// \brief The attributes for the specified index are returned.
|
||||||
AttributeSetNode *getAttributes(unsigned Index) const;
|
AttributeSet getAttributes(unsigned Index) const;
|
||||||
|
|
||||||
/// \brief The attributes for the specified index are returned.
|
/// \brief The attributes for the specified index are returned.
|
||||||
AttributeSetNode *getParamAttributes(unsigned Index) const;
|
AttributeSet getParamAttributes(unsigned Index) const;
|
||||||
|
|
||||||
/// \brief The attributes for the ret value are returned.
|
/// \brief The attributes for the ret value are returned.
|
||||||
AttributeSetNode *getRetAttributes() const;
|
AttributeSet getRetAttributes() const;
|
||||||
|
|
||||||
/// \brief The function attributes are returned.
|
/// \brief The function attributes are returned.
|
||||||
AttributeSetNode *getFnAttributes() const;
|
AttributeSet getFnAttributes() const;
|
||||||
|
|
||||||
/// \brief Return true if the attribute exists at the given index.
|
/// \brief Return true if the attribute exists at the given index.
|
||||||
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
|
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
|
||||||
@ -483,7 +562,7 @@ public:
|
|||||||
addAttribute(A);
|
addAttribute(A);
|
||||||
}
|
}
|
||||||
AttrBuilder(AttributeList AS, unsigned Idx);
|
AttrBuilder(AttributeList AS, unsigned Idx);
|
||||||
AttrBuilder(AttributeSetNode *AS);
|
AttrBuilder(AttributeSet AS);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/AsmParser/SlotMapping.h"
|
#include "llvm/AsmParser/SlotMapping.h"
|
||||||
#include "llvm/IR/Argument.h"
|
#include "llvm/IR/Argument.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/AutoUpgrade.h"
|
#include "llvm/IR/AutoUpgrade.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/CallingConv.h"
|
#include "llvm/IR/CallingConv.h"
|
||||||
@ -2155,7 +2154,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ArgList.push_back(ParamInfo(
|
ArgList.push_back(ParamInfo(
|
||||||
ArgLoc, V, AttributeSetNode::get(V->getContext(), ArgAttrs)));
|
ArgLoc, V, AttributeSet::get(V->getContext(), ArgAttrs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMustTailCall && InVarArgsFunc)
|
if (IsMustTailCall && InVarArgsFunc)
|
||||||
@ -2261,7 +2260,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
|
|||||||
return Error(TypeLoc, "invalid type for function argument");
|
return Error(TypeLoc, "invalid type for function argument");
|
||||||
|
|
||||||
ArgList.emplace_back(TypeLoc, ArgTy,
|
ArgList.emplace_back(TypeLoc, ArgTy,
|
||||||
AttributeSetNode::get(ArgTy->getContext(), Attrs),
|
AttributeSet::get(ArgTy->getContext(), Attrs),
|
||||||
std::move(Name));
|
std::move(Name));
|
||||||
|
|
||||||
while (EatIfPresent(lltok::comma)) {
|
while (EatIfPresent(lltok::comma)) {
|
||||||
@ -2289,7 +2288,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
|
|||||||
return Error(TypeLoc, "invalid type for function argument");
|
return Error(TypeLoc, "invalid type for function argument");
|
||||||
|
|
||||||
ArgList.emplace_back(TypeLoc, ArgTy,
|
ArgList.emplace_back(TypeLoc, ArgTy,
|
||||||
AttributeSetNode::get(ArgTy->getContext(), Attrs),
|
AttributeSet::get(ArgTy->getContext(), Attrs),
|
||||||
std::move(Name));
|
std::move(Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2314,7 +2313,7 @@ bool LLParser::ParseFunctionType(Type *&Result) {
|
|||||||
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
||||||
if (!ArgList[i].Name.empty())
|
if (!ArgList[i].Name.empty())
|
||||||
return Error(ArgList[i].Loc, "argument name invalid in function type");
|
return Error(ArgList[i].Loc, "argument name invalid in function type");
|
||||||
if (ArgList[i].Attrs)
|
if (ArgList[i].Attrs.hasAttributes())
|
||||||
return Error(ArgList[i].Loc,
|
return Error(ArgList[i].Loc,
|
||||||
"argument attributes invalid in function type");
|
"argument attributes invalid in function type");
|
||||||
}
|
}
|
||||||
@ -4763,16 +4762,16 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
|||||||
// Okay, if we got here, the function is syntactically valid. Convert types
|
// Okay, if we got here, the function is syntactically valid. Convert types
|
||||||
// and do semantic checks.
|
// and do semantic checks.
|
||||||
std::vector<Type*> ParamTypeList;
|
std::vector<Type*> ParamTypeList;
|
||||||
SmallVector<AttributeSetNode *, 8> Attrs;
|
SmallVector<AttributeSet, 8> Attrs;
|
||||||
|
|
||||||
Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
|
Attrs.push_back(AttributeSet::get(Context, RetAttrs));
|
||||||
|
|
||||||
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
||||||
ParamTypeList.push_back(ArgList[i].Ty);
|
ParamTypeList.push_back(ArgList[i].Ty);
|
||||||
Attrs.push_back(ArgList[i].Attrs);
|
Attrs.push_back(ArgList[i].Attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Attrs.push_back(AttributeSetNode::get(Context, FuncAttrs));
|
Attrs.push_back(AttributeSet::get(Context, FuncAttrs));
|
||||||
|
|
||||||
AttributeList PAL = AttributeList::get(Context, Attrs);
|
AttributeList PAL = AttributeList::get(Context, Attrs);
|
||||||
|
|
||||||
@ -5384,8 +5383,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Set up the Attribute for the function.
|
// Set up the Attribute for the function.
|
||||||
SmallVector<AttributeSetNode *, 8> Attrs;
|
SmallVector<AttributeSet, 8> Attrs;
|
||||||
Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
|
Attrs.push_back(AttributeSet::get(Context, RetAttrs));
|
||||||
|
|
||||||
SmallVector<Value*, 8> Args;
|
SmallVector<Value*, 8> Args;
|
||||||
|
|
||||||
@ -5414,7 +5413,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
|||||||
if (FnAttrs.hasAlignmentAttr())
|
if (FnAttrs.hasAlignmentAttr())
|
||||||
return Error(CallLoc, "invoke instructions may not have an alignment");
|
return Error(CallLoc, "invoke instructions may not have an alignment");
|
||||||
|
|
||||||
Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
|
Attrs.push_back(AttributeSet::get(Context, FnAttrs));
|
||||||
|
|
||||||
// Finish off the Attribute and check them
|
// Finish off the Attribute and check them
|
||||||
AttributeList PAL = AttributeList::get(Context, Attrs);
|
AttributeList PAL = AttributeList::get(Context, Attrs);
|
||||||
@ -5978,8 +5977,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Set up the Attribute for the function.
|
// Set up the Attribute for the function.
|
||||||
SmallVector<AttributeSetNode *, 8> Attrs;
|
SmallVector<AttributeSet, 8> Attrs;
|
||||||
Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
|
Attrs.push_back(AttributeSet::get(Context, RetAttrs));
|
||||||
|
|
||||||
SmallVector<Value*, 8> Args;
|
SmallVector<Value*, 8> Args;
|
||||||
|
|
||||||
@ -6008,7 +6007,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
|||||||
if (FnAttrs.hasAlignmentAttr())
|
if (FnAttrs.hasAlignmentAttr())
|
||||||
return Error(CallLoc, "call instructions may not have an alignment");
|
return Error(CallLoc, "call instructions may not have an alignment");
|
||||||
|
|
||||||
Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
|
Attrs.push_back(AttributeSet::get(Context, FnAttrs));
|
||||||
|
|
||||||
// Finish off the Attribute and check them
|
// Finish off the Attribute and check them
|
||||||
AttributeList PAL = AttributeList::get(Context, Attrs);
|
AttributeList PAL = AttributeList::get(Context, Attrs);
|
||||||
|
@ -397,8 +397,8 @@ namespace llvm {
|
|||||||
struct ParamInfo {
|
struct ParamInfo {
|
||||||
LocTy Loc;
|
LocTy Loc;
|
||||||
Value *V;
|
Value *V;
|
||||||
AttributeSetNode *Attrs;
|
AttributeSet Attrs;
|
||||||
ParamInfo(LocTy loc, Value *v, AttributeSetNode *attrs)
|
ParamInfo(LocTy loc, Value *v, AttributeSet attrs)
|
||||||
: Loc(loc), V(v), Attrs(attrs) {}
|
: Loc(loc), V(v), Attrs(attrs) {}
|
||||||
};
|
};
|
||||||
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
||||||
@ -450,9 +450,9 @@ namespace llvm {
|
|||||||
struct ArgInfo {
|
struct ArgInfo {
|
||||||
LocTy Loc;
|
LocTy Loc;
|
||||||
Type *Ty;
|
Type *Ty;
|
||||||
AttributeSetNode *Attrs;
|
AttributeSet Attrs;
|
||||||
std::string Name;
|
std::string Name;
|
||||||
ArgInfo(LocTy L, Type *ty, AttributeSetNode *Attr, const std::string &N)
|
ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N)
|
||||||
: Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
|
: Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
|
||||||
};
|
};
|
||||||
bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg);
|
bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg);
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/IR/AssemblyAnnotationWriter.h"
|
#include "llvm/IR/AssemblyAnnotationWriter.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/IR/CFG.h"
|
#include "llvm/IR/CFG.h"
|
||||||
#include "llvm/IR/CallingConv.h"
|
#include "llvm/IR/CallingConv.h"
|
||||||
@ -606,7 +605,7 @@ private:
|
|||||||
unsigned mdnNext;
|
unsigned mdnNext;
|
||||||
|
|
||||||
/// asMap - The slot map for attribute sets.
|
/// asMap - The slot map for attribute sets.
|
||||||
DenseMap<AttributeSetNode *, unsigned> asMap;
|
DenseMap<AttributeSet, unsigned> asMap;
|
||||||
unsigned asNext;
|
unsigned asNext;
|
||||||
public:
|
public:
|
||||||
/// Construct from a module.
|
/// Construct from a module.
|
||||||
@ -629,7 +628,7 @@ public:
|
|||||||
int getLocalSlot(const Value *V);
|
int getLocalSlot(const Value *V);
|
||||||
int getGlobalSlot(const GlobalValue *V);
|
int getGlobalSlot(const GlobalValue *V);
|
||||||
int getMetadataSlot(const MDNode *N);
|
int getMetadataSlot(const MDNode *N);
|
||||||
int getAttributeGroupSlot(AttributeSetNode *AS);
|
int getAttributeGroupSlot(AttributeSet AS);
|
||||||
|
|
||||||
/// If you'd like to deal with a function instead of just a module, use
|
/// If you'd like to deal with a function instead of just a module, use
|
||||||
/// this method to get its data into the SlotTracker.
|
/// this method to get its data into the SlotTracker.
|
||||||
@ -652,8 +651,8 @@ public:
|
|||||||
unsigned mdn_size() const { return mdnMap.size(); }
|
unsigned mdn_size() const { return mdnMap.size(); }
|
||||||
bool mdn_empty() const { return mdnMap.empty(); }
|
bool mdn_empty() const { return mdnMap.empty(); }
|
||||||
|
|
||||||
/// AttributeSetNode map iterators.
|
/// AttributeSet map iterators.
|
||||||
typedef DenseMap<AttributeSetNode *, unsigned>::iterator as_iterator;
|
typedef DenseMap<AttributeSet, unsigned>::iterator as_iterator;
|
||||||
as_iterator as_begin() { return asMap.begin(); }
|
as_iterator as_begin() { return asMap.begin(); }
|
||||||
as_iterator as_end() { return asMap.end(); }
|
as_iterator as_end() { return asMap.end(); }
|
||||||
unsigned as_size() const { return asMap.size(); }
|
unsigned as_size() const { return asMap.size(); }
|
||||||
@ -673,8 +672,8 @@ private:
|
|||||||
/// CreateFunctionSlot - Insert the specified Value* into the slot table.
|
/// CreateFunctionSlot - Insert the specified Value* into the slot table.
|
||||||
void CreateFunctionSlot(const Value *V);
|
void CreateFunctionSlot(const Value *V);
|
||||||
|
|
||||||
/// \brief Insert the specified AttributeSetNode into the slot table.
|
/// \brief Insert the specified AttributeSet into the slot table.
|
||||||
void CreateAttributeSetSlot(AttributeSetNode *AS);
|
void CreateAttributeSetSlot(AttributeSet AS);
|
||||||
|
|
||||||
/// Add all of the module level global variables (and their initializers)
|
/// Add all of the module level global variables (and their initializers)
|
||||||
/// and function declarations, but not the contents of those functions.
|
/// and function declarations, but not the contents of those functions.
|
||||||
@ -833,8 +832,8 @@ void SlotTracker::processModule() {
|
|||||||
|
|
||||||
// Add all the function attributes to the table.
|
// Add all the function attributes to the table.
|
||||||
// FIXME: Add attributes of other objects?
|
// FIXME: Add attributes of other objects?
|
||||||
AttributeSetNode *FnAttrs = F.getAttributes().getFnAttributes();
|
AttributeSet FnAttrs = F.getAttributes().getFnAttributes();
|
||||||
if (FnAttrs)
|
if (FnAttrs.hasAttributes())
|
||||||
CreateAttributeSetSlot(FnAttrs);
|
CreateAttributeSetSlot(FnAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,15 +868,10 @@ void SlotTracker::processFunction() {
|
|||||||
|
|
||||||
// We allow direct calls to any llvm.foo function here, because the
|
// We allow direct calls to any llvm.foo function here, because the
|
||||||
// target may not be linked into the optimizer.
|
// target may not be linked into the optimizer.
|
||||||
if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
|
if (auto CS = ImmutableCallSite(&I)) {
|
||||||
// Add all the call attributes to the table.
|
// Add all the call attributes to the table.
|
||||||
AttributeSetNode *Attrs = CI->getAttributes().getFnAttributes();
|
AttributeSet Attrs = CS.getAttributes().getFnAttributes();
|
||||||
if (Attrs)
|
if (Attrs.hasAttributes())
|
||||||
CreateAttributeSetSlot(Attrs);
|
|
||||||
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
|
|
||||||
// Add all the call attributes to the table.
|
|
||||||
AttributeSetNode *Attrs = II->getAttributes().getFnAttributes();
|
|
||||||
if (Attrs)
|
|
||||||
CreateAttributeSetSlot(Attrs);
|
CreateAttributeSetSlot(Attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -963,11 +957,11 @@ int SlotTracker::getLocalSlot(const Value *V) {
|
|||||||
return FI == fMap.end() ? -1 : (int)FI->second;
|
return FI == fMap.end() ? -1 : (int)FI->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SlotTracker::getAttributeGroupSlot(AttributeSetNode *AS) {
|
int SlotTracker::getAttributeGroupSlot(AttributeSet AS) {
|
||||||
// Check for uninitialized state and do lazy initialization.
|
// Check for uninitialized state and do lazy initialization.
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
// Find the AttributeSetNode in the module map.
|
// Find the AttributeSet in the module map.
|
||||||
as_iterator AI = asMap.find(AS);
|
as_iterator AI = asMap.find(AS);
|
||||||
return AI == asMap.end() ? -1 : (int)AI->second;
|
return AI == asMap.end() ? -1 : (int)AI->second;
|
||||||
}
|
}
|
||||||
@ -1017,8 +1011,8 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) {
|
|||||||
CreateMetadataSlot(Op);
|
CreateMetadataSlot(Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlotTracker::CreateAttributeSetSlot(AttributeSetNode *AS) {
|
void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
|
||||||
assert(AS && "Doesn't need a slot!");
|
assert(AS.hasAttributes() && "Doesn't need a slot!");
|
||||||
|
|
||||||
as_iterator I = asMap.find(AS);
|
as_iterator I = asMap.find(AS);
|
||||||
if (I != asMap.end())
|
if (I != asMap.end())
|
||||||
@ -2607,10 +2601,10 @@ void AssemblyWriter::printFunction(const Function *F) {
|
|||||||
|
|
||||||
const AttributeList &Attrs = F->getAttributes();
|
const AttributeList &Attrs = F->getAttributes();
|
||||||
if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
|
if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
|
||||||
AttributeSetNode *AS = Attrs.getFnAttributes();
|
AttributeSet AS = Attrs.getFnAttributes();
|
||||||
std::string AttrStr;
|
std::string AttrStr;
|
||||||
|
|
||||||
for (const Attribute &Attr : *AS) {
|
for (const Attribute &Attr : AS) {
|
||||||
if (!Attr.isStringAttribute()) {
|
if (!Attr.isStringAttribute()) {
|
||||||
if (!AttrStr.empty()) AttrStr += ' ';
|
if (!AttrStr.empty()) AttrStr += ' ';
|
||||||
AttrStr += Attr.getAsString();
|
AttrStr += Attr.getAsString();
|
||||||
@ -3250,7 +3244,7 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyWriter::writeAllAttributeGroups() {
|
void AssemblyWriter::writeAllAttributeGroups() {
|
||||||
std::vector<std::pair<AttributeSetNode *, unsigned>> asVec;
|
std::vector<std::pair<AttributeSet, unsigned>> asVec;
|
||||||
asVec.resize(Machine.as_size());
|
asVec.resize(Machine.as_size());
|
||||||
|
|
||||||
for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end();
|
for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end();
|
||||||
@ -3259,7 +3253,7 @@ void AssemblyWriter::writeAllAttributeGroups() {
|
|||||||
|
|
||||||
for (const auto &I : asVec)
|
for (const auto &I : asVec)
|
||||||
Out << "attributes #" << I.second << " = { "
|
Out << "attributes #" << I.second << " = { "
|
||||||
<< I.first->getAsString(true) << " }\n";
|
<< I.first.getAsString(true) << " }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
|
void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/Support/TrailingObjects.h"
|
#include "llvm/Support/TrailingObjects.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -144,7 +143,65 @@ public:
|
|||||||
StringRef getStringValue() const { return Val; }
|
StringRef getStringValue() const { return Val; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<unsigned, AttributeSetNode *> IndexAttrPair;
|
//===----------------------------------------------------------------------===//
|
||||||
|
/// \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;
|
||||||
|
|
||||||
|
/// Bitset with a bit for each available attribute Attribute::AttrKind.
|
||||||
|
uint64_t AvailableAttrs;
|
||||||
|
unsigned NumAttrs; ///< Number of attributes in this node.
|
||||||
|
|
||||||
|
AttributeSetNode(ArrayRef<Attribute> Attrs);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// AttributesSetNode is uniqued, these should not be available.
|
||||||
|
AttributeSetNode(const AttributeSetNode &) = delete;
|
||||||
|
AttributeSetNode &operator=(const AttributeSetNode &) = delete;
|
||||||
|
|
||||||
|
void operator delete(void *p) { ::operator delete(p); }
|
||||||
|
|
||||||
|
static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);
|
||||||
|
|
||||||
|
static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
|
||||||
|
|
||||||
|
/// \brief Return the number of attributes this AttributeList 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 (const auto &Attr : AttrList)
|
||||||
|
Attr.Profile(ID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::pair<unsigned, AttributeSet> IndexAttrPair;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// \class
|
/// \class
|
||||||
@ -166,13 +223,13 @@ private:
|
|||||||
size_t numTrailingObjects(OverloadToken<IndexAttrPair>) { return NumSlots; }
|
size_t numTrailingObjects(OverloadToken<IndexAttrPair>) { return NumSlots; }
|
||||||
|
|
||||||
/// \brief Return a pointer to the IndexAttrPair for the specified slot.
|
/// \brief Return a pointer to the IndexAttrPair for the specified slot.
|
||||||
const IndexAttrPair *getNode(unsigned Slot) const {
|
const IndexAttrPair *getSlotPair(unsigned Slot) const {
|
||||||
return getTrailingObjects<IndexAttrPair>() + Slot;
|
return getTrailingObjects<IndexAttrPair>() + Slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AttributeListImpl(LLVMContext &C,
|
AttributeListImpl(LLVMContext &C,
|
||||||
ArrayRef<std::pair<unsigned, AttributeSetNode *>> Slots);
|
ArrayRef<std::pair<unsigned, AttributeSet>> Slots);
|
||||||
|
|
||||||
// AttributesSetImpt is uniqued, these should not be available.
|
// AttributesSetImpt is uniqued, these should not be available.
|
||||||
AttributeListImpl(const AttributeListImpl &) = delete;
|
AttributeListImpl(const AttributeListImpl &) = delete;
|
||||||
@ -193,35 +250,35 @@ public:
|
|||||||
/// attributes are applied to, not the index into the AttrNodes list where the
|
/// attributes are applied to, not the index into the AttrNodes list where the
|
||||||
/// attributes reside.
|
/// attributes reside.
|
||||||
unsigned getSlotIndex(unsigned Slot) const {
|
unsigned getSlotIndex(unsigned Slot) const {
|
||||||
return getNode(Slot)->first;
|
return getSlotPair(Slot)->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Retrieve the attribute set node for the given "slot" in the
|
||||||
|
/// AttrNode list.
|
||||||
|
AttributeSet getSlotNode(unsigned Slot) const {
|
||||||
|
return getSlotPair(Slot)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Retrieve the attributes for the given "slot" in the AttrNode list.
|
/// \brief Retrieve the attributes for the given "slot" in the AttrNode list.
|
||||||
/// \p Slot is an index into the AttrNodes list, not the index of the return /
|
/// \p Slot is an index into the AttrNodes list, not the index of the return /
|
||||||
/// parameter/ function which the attributes apply to.
|
/// parameter/ function which the attributes apply to.
|
||||||
AttributeList getSlotAttributes(unsigned Slot) const {
|
AttributeList getSlotAttributes(unsigned Slot) const {
|
||||||
return AttributeList::get(Context, *getNode(Slot));
|
return AttributeList::get(Context, *getSlotPair(Slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Retrieve the attribute set node for the given "slot" in the
|
/// \brief Return true if the AttributeSet or the FunctionIndex has an
|
||||||
/// AttrNode list.
|
|
||||||
AttributeSetNode *getSlotNode(unsigned Slot) const {
|
|
||||||
return getNode(Slot)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Return true if the AttributeSetNode for the FunctionIndex has an
|
|
||||||
/// enum attribute of the given kind.
|
/// enum attribute of the given kind.
|
||||||
bool hasFnAttribute(Attribute::AttrKind Kind) const {
|
bool hasFnAttribute(Attribute::AttrKind Kind) const {
|
||||||
return AvailableFunctionAttrs & ((uint64_t)1) << Kind;
|
return AvailableFunctionAttrs & ((uint64_t)1) << Kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef AttributeSetNode::iterator iterator;
|
typedef AttributeSet::iterator iterator;
|
||||||
iterator begin(unsigned Slot) const { return getSlotNode(Slot)->begin(); }
|
iterator begin(unsigned Slot) const { return getSlotNode(Slot).begin(); }
|
||||||
iterator end(unsigned Slot) const { return getSlotNode(Slot)->end(); }
|
iterator end(unsigned Slot) const { return getSlotNode(Slot).end(); }
|
||||||
|
|
||||||
void Profile(FoldingSetNodeID &ID) const;
|
void Profile(FoldingSetNodeID &ID) const;
|
||||||
static void Profile(FoldingSetNodeID &ID,
|
static void Profile(FoldingSetNodeID &ID,
|
||||||
ArrayRef<std::pair<unsigned, AttributeSetNode*>> Nodes);
|
ArrayRef<std::pair<unsigned, AttributeSet>> Nodes);
|
||||||
|
|
||||||
void dump() const;
|
void dump() const;
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
@ -491,14 +490,76 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const {
|
|||||||
return getKindAsString() < AI.getKindAsString();
|
return getKindAsString() < AI.getKindAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// AttributeSet Definition
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
|
||||||
|
return AttributeSet(AttributeSetNode::get(C, B));
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
|
||||||
|
return AttributeSet(AttributeSetNode::get(C, Attrs));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned AttributeSet::getNumAttributes() const {
|
||||||
|
return SetNode ? SetNode->getNumAttributes() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
|
||||||
|
return SetNode ? SetNode->hasAttribute(Kind) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AttributeSet::hasAttribute(StringRef Kind) const {
|
||||||
|
return SetNode ? SetNode->hasAttribute(Kind) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
|
||||||
|
return SetNode ? SetNode->getAttribute(Kind) : Attribute();
|
||||||
|
}
|
||||||
|
|
||||||
|
Attribute AttributeSet::getAttribute(StringRef Kind) const {
|
||||||
|
return SetNode ? SetNode->getAttribute(Kind) : Attribute();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned AttributeSet::getAlignment() const {
|
||||||
|
return SetNode ? SetNode->getAlignment() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned AttributeSet::getStackAlignment() const {
|
||||||
|
return SetNode ? SetNode->getStackAlignment() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t AttributeSet::getDereferenceableBytes() const {
|
||||||
|
return SetNode ? SetNode->getDereferenceableBytes() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
|
||||||
|
return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
|
||||||
|
return SetNode ? SetNode->getAllocSizeArgs() : std::make_pair(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AttributeSet::getAsString(bool InAttrGrp) const {
|
||||||
|
return SetNode ? SetNode->getAsString(InAttrGrp) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeSet::iterator AttributeSet::begin() const {
|
||||||
|
return SetNode ? SetNode->begin() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeSet::iterator AttributeSet::end() const {
|
||||||
|
return SetNode ? SetNode->end() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// AttributeSetNode Definition
|
// AttributeSetNode Definition
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
|
AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
|
||||||
: NumAttrs(Attrs.size()), AvailableAttrs(0) {
|
: AvailableAttrs(0), NumAttrs(Attrs.size()) {
|
||||||
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.
|
// There's memory after the node where we can store the entries in.
|
||||||
std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
|
std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
|
||||||
|
|
||||||
@ -657,7 +718,7 @@ std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
AttributeListImpl::AttributeListImpl(
|
AttributeListImpl::AttributeListImpl(
|
||||||
LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Slots)
|
LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Slots)
|
||||||
: Context(C), NumSlots(Slots.size()), AvailableFunctionAttrs(0) {
|
: Context(C), NumSlots(Slots.size()), AvailableFunctionAttrs(0) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (Slots.size() >= 2) {
|
if (Slots.size() >= 2) {
|
||||||
@ -678,10 +739,10 @@ AttributeListImpl::AttributeListImpl(
|
|||||||
"Too many attributes");
|
"Too many attributes");
|
||||||
static_assert(AttributeList::FunctionIndex == ~0u,
|
static_assert(AttributeList::FunctionIndex == ~0u,
|
||||||
"FunctionIndex should be biggest possible index");
|
"FunctionIndex should be biggest possible index");
|
||||||
const std::pair<unsigned, AttributeSetNode *> &Last = Slots.back();
|
const auto &Last = Slots.back();
|
||||||
if (Last.first == AttributeList::FunctionIndex) {
|
if (Last.first == AttributeList::FunctionIndex) {
|
||||||
const AttributeSetNode *Node = Last.second;
|
AttributeSet Node = Last.second;
|
||||||
for (Attribute I : *Node) {
|
for (Attribute I : Node) {
|
||||||
if (!I.isStringAttribute())
|
if (!I.isStringAttribute())
|
||||||
AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum();
|
AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum();
|
||||||
}
|
}
|
||||||
@ -690,15 +751,14 @@ AttributeListImpl::AttributeListImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
|
void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
|
||||||
Profile(ID, makeArrayRef(getNode(0), getNumSlots()));
|
Profile(ID, makeArrayRef(getSlotPair(0), getNumSlots()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttributeListImpl::Profile(
|
void AttributeListImpl::Profile(
|
||||||
FoldingSetNodeID &ID,
|
FoldingSetNodeID &ID, ArrayRef<std::pair<unsigned, AttributeSet>> Nodes) {
|
||||||
ArrayRef<std::pair<unsigned, AttributeSetNode *>> Nodes) {
|
|
||||||
for (const auto &Node : Nodes) {
|
for (const auto &Node : Nodes) {
|
||||||
ID.AddInteger(Node.first);
|
ID.AddInteger(Node.first);
|
||||||
ID.AddPointer(Node.second);
|
ID.AddPointer(Node.second.SetNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -713,7 +773,7 @@ LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
AttributeList AttributeList::getImpl(
|
AttributeList AttributeList::getImpl(
|
||||||
LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs) {
|
LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
|
||||||
assert(!Attrs.empty() && "creating pointless AttributeList");
|
assert(!Attrs.empty() && "creating pointless AttributeList");
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
unsigned LastIndex = 0;
|
unsigned LastIndex = 0;
|
||||||
@ -721,7 +781,7 @@ AttributeList AttributeList::getImpl(
|
|||||||
for (const auto &AttrPair : Attrs) {
|
for (const auto &AttrPair : Attrs) {
|
||||||
assert((IsFirst || LastIndex < AttrPair.first) &&
|
assert((IsFirst || LastIndex < AttrPair.first) &&
|
||||||
"unsorted or duplicate AttributeList indices");
|
"unsorted or duplicate AttributeList indices");
|
||||||
assert(AttrPair.second && "pointless AttributeList slot");
|
assert(AttrPair.second.hasAttributes() && "pointless AttributeList slot");
|
||||||
LastIndex = AttrPair.first;
|
LastIndex = AttrPair.first;
|
||||||
IsFirst = false;
|
IsFirst = false;
|
||||||
}
|
}
|
||||||
@ -769,7 +829,7 @@ AttributeList::get(LLVMContext &C,
|
|||||||
|
|
||||||
// Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
|
// Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
|
||||||
// list.
|
// list.
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
|
SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
|
||||||
for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
|
for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
|
||||||
E = Attrs.end(); I != E; ) {
|
E = Attrs.end(); I != E; ) {
|
||||||
unsigned Index = I->first;
|
unsigned Index = I->first;
|
||||||
@ -779,7 +839,7 @@ AttributeList::get(LLVMContext &C,
|
|||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrPairVec.emplace_back(Index, AttributeSetNode::get(C, AttrVec));
|
AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
|
||||||
}
|
}
|
||||||
|
|
||||||
return getImpl(C, AttrPairVec);
|
return getImpl(C, AttrPairVec);
|
||||||
@ -787,7 +847,7 @@ AttributeList::get(LLVMContext &C,
|
|||||||
|
|
||||||
AttributeList
|
AttributeList
|
||||||
AttributeList::get(LLVMContext &C,
|
AttributeList::get(LLVMContext &C,
|
||||||
ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs) {
|
ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
|
||||||
// If there are no attributes then return a null AttributesList pointer.
|
// If there are no attributes then return a null AttributesList pointer.
|
||||||
if (Attrs.empty())
|
if (Attrs.empty())
|
||||||
return AttributeList();
|
return AttributeList();
|
||||||
@ -795,13 +855,13 @@ AttributeList::get(LLVMContext &C,
|
|||||||
return getImpl(C, Attrs);
|
return getImpl(C, Attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList AttributeList::get(LLVMContext &C, ArrayRef<AttributeSetNode*> Attrs) {
|
AttributeList AttributeList::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
|
||||||
assert(Attrs.size() >= 2 &&
|
assert(Attrs.size() >= 2 &&
|
||||||
"should always have function and return attr slots");
|
"should always have function and return attr slots");
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode *>, 8> AttrPairs;
|
SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairs;
|
||||||
size_t Index = 0;
|
size_t Index = 0;
|
||||||
for (AttributeSetNode *AS : Attrs) {
|
for (AttributeSet AS : Attrs) {
|
||||||
if (AS) {
|
if (AS.hasAttributes()) {
|
||||||
// If this is the last AttributeSetNode, it's for the function.
|
// If this is the last AttributeSetNode, it's for the function.
|
||||||
if (Index == Attrs.size() - 1)
|
if (Index == Attrs.size() - 1)
|
||||||
Index = AttributeList::FunctionIndex;
|
Index = AttributeList::FunctionIndex;
|
||||||
@ -818,8 +878,8 @@ AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
|
|||||||
const AttrBuilder &B) {
|
const AttrBuilder &B) {
|
||||||
if (!B.hasAttributes())
|
if (!B.hasAttributes())
|
||||||
return AttributeList();
|
return AttributeList();
|
||||||
AttributeSetNode *ASN = AttributeSetNode::get(C, B);
|
AttributeSet AS = AttributeSet::get(C, B);
|
||||||
std::pair<unsigned, AttributeSetNode *> Arr[1] = {{Index, ASN}};
|
std::pair<unsigned, AttributeSet> Arr[1] = {{Index, AS}};
|
||||||
return getImpl(C, Arr);
|
return getImpl(C, Arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,21 +905,21 @@ AttributeList AttributeList::get(LLVMContext &C,
|
|||||||
return AttributeList();
|
return AttributeList();
|
||||||
if (Attrs.size() == 1) return Attrs[0];
|
if (Attrs.size() == 1) return Attrs[0];
|
||||||
|
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
|
SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrNodeVec;
|
||||||
AttributeListImpl *A0 = Attrs[0].pImpl;
|
AttributeListImpl *A0 = Attrs[0].pImpl;
|
||||||
if (A0)
|
if (A0)
|
||||||
AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumSlots()));
|
AttrNodeVec.append(A0->getSlotPair(0), A0->getSlotPair(A0->getNumSlots()));
|
||||||
// Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
|
// Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
|
||||||
// ordered by index. Because we know that each list in Attrs is ordered by
|
// ordered by index. Because we know that each list in Attrs is ordered by
|
||||||
// index we only need to merge each successive list in rather than doing a
|
// index we only need to merge each successive list in rather than doing a
|
||||||
// full sort.
|
// full sort.
|
||||||
for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
|
for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
|
||||||
AttributeListImpl *AS = Attrs[I].pImpl;
|
AttributeListImpl *ALI = Attrs[I].pImpl;
|
||||||
if (!AS) continue;
|
if (!ALI) continue;
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator
|
SmallVector<std::pair<unsigned, AttributeSet>, 8>::iterator
|
||||||
ANVI = AttrNodeVec.begin(), ANVE;
|
ANVI = AttrNodeVec.begin(), ANVE;
|
||||||
for (const IndexAttrPair *AI = AS->getNode(0),
|
for (const IndexAttrPair *AI = ALI->getSlotPair(0),
|
||||||
*AE = AS->getNode(AS->getNumSlots());
|
*AE = ALI->getSlotPair(ALI->getNumSlots());
|
||||||
AI != AE; ++AI) {
|
AI != AE; ++AI) {
|
||||||
ANVE = AttrNodeVec.end();
|
ANVE = AttrNodeVec.end();
|
||||||
while (ANVI != ANVE && ANVI->first <= AI->first)
|
while (ANVI != ANVE && ANVI->first <= AI->first)
|
||||||
@ -905,7 +965,7 @@ AttributeList AttributeList::addAttribute(LLVMContext &C,
|
|||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
B.addAttribute(A);
|
B.addAttribute(A);
|
||||||
AttrVec.emplace_back(Index, AttributeSetNode::get(C, B));
|
AttrVec.emplace_back(Index, AttributeSet::get(C, B));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add remaining attributes.
|
// Add remaining attributes.
|
||||||
@ -924,20 +984,20 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
||||||
AttributeSetNode *AS) const {
|
AttributeSet AS) const {
|
||||||
if (!AS)
|
if (!AS.hasAttributes())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// FIXME it is not obvious how this should work for alignment. For now, say
|
// FIXME it is not obvious how this should work for alignment. For now, say
|
||||||
// we can't change a known alignment.
|
// we can't change a known alignment.
|
||||||
unsigned OldAlign = getParamAlignment(Index);
|
unsigned OldAlign = getParamAlignment(Index);
|
||||||
unsigned NewAlign = AS->getAlignment();
|
unsigned NewAlign = AS.getAlignment();
|
||||||
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
|
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
|
||||||
"Attempt to change alignment!");
|
"Attempt to change alignment!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
|
SmallVector<std::pair<unsigned, AttributeSet>, 4> AttrSet;
|
||||||
uint64_t NumAttrs = pImpl->getNumSlots();
|
uint64_t NumAttrs = pImpl->getNumSlots();
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
@ -949,8 +1009,8 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (I < NumAttrs && getSlotIndex(I) == Index) {
|
if (I < NumAttrs && getSlotIndex(I) == Index) {
|
||||||
// We need to merge two AttributeSetNodes.
|
// We need to merge two AttributeSets.
|
||||||
AttributeSetNode *Merged = AttributeSetNode::get(
|
AttributeSet Merged = AttributeSet::get(
|
||||||
C, AttrBuilder(pImpl->getSlotNode(I)).merge(AttrBuilder(AS)));
|
C, AttrBuilder(pImpl->getSlotNode(I)).merge(AttrBuilder(AS)));
|
||||||
AttrSet.emplace_back(Index, Merged);
|
AttrSet.emplace_back(Index, Merged);
|
||||||
++I;
|
++I;
|
||||||
@ -969,7 +1029,7 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
|||||||
|
|
||||||
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
|
||||||
const AttrBuilder &B) const {
|
const AttrBuilder &B) const {
|
||||||
return get(C, Index, AttributeSetNode::get(C, B));
|
return get(C, Index, AttributeSet::get(C, B));
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
|
AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
|
||||||
@ -998,11 +1058,11 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
|
|||||||
// Add the attribute slots before the one we're trying to add.
|
// Add the attribute slots before the one we're trying to add.
|
||||||
SmallVector<AttributeList, 4> AttrSet;
|
SmallVector<AttributeList, 4> AttrSet;
|
||||||
uint64_t NumAttrs = pImpl->getNumSlots();
|
uint64_t NumAttrs = pImpl->getNumSlots();
|
||||||
AttributeList AS;
|
AttributeList AL;
|
||||||
uint64_t LastIndex = 0;
|
uint64_t LastIndex = 0;
|
||||||
for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
|
for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
|
||||||
if (getSlotIndex(I) >= Index) {
|
if (getSlotIndex(I) >= Index) {
|
||||||
if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
|
if (getSlotIndex(I) == Index) AL = getSlotAttributes(LastIndex++);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LastIndex = I + 1;
|
LastIndex = I + 1;
|
||||||
@ -1011,7 +1071,7 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
|
|||||||
|
|
||||||
// Now remove the attribute from the correct slot. There may already be an
|
// Now remove the attribute from the correct slot. There may already be an
|
||||||
// AttributeList there.
|
// AttributeList there.
|
||||||
AttrBuilder B(AS, Index);
|
AttrBuilder B(AL, Index);
|
||||||
|
|
||||||
for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
|
for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
|
||||||
if (Attrs.getSlotIndex(I) == Index) {
|
if (Attrs.getSlotIndex(I) == Index) {
|
||||||
@ -1040,11 +1100,11 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
|
|||||||
// Add the attribute slots before the one we're trying to add.
|
// Add the attribute slots before the one we're trying to add.
|
||||||
SmallVector<AttributeList, 4> AttrSet;
|
SmallVector<AttributeList, 4> AttrSet;
|
||||||
uint64_t NumAttrs = pImpl->getNumSlots();
|
uint64_t NumAttrs = pImpl->getNumSlots();
|
||||||
AttributeList AS;
|
AttributeList AL;
|
||||||
uint64_t LastIndex = 0;
|
uint64_t LastIndex = 0;
|
||||||
for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
|
for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
|
||||||
if (getSlotIndex(I) >= Index) {
|
if (getSlotIndex(I) >= Index) {
|
||||||
if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
|
if (getSlotIndex(I) == Index) AL = getSlotAttributes(LastIndex++);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LastIndex = I + 1;
|
LastIndex = I + 1;
|
||||||
@ -1053,7 +1113,7 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
|
|||||||
|
|
||||||
// Now remove the attribute from the correct slot. There may already be an
|
// Now remove the attribute from the correct slot. There may already be an
|
||||||
// AttributeList there.
|
// AttributeList there.
|
||||||
AttrBuilder B(AS, Index);
|
AttrBuilder B(AL, Index);
|
||||||
B.remove(Attrs);
|
B.remove(Attrs);
|
||||||
|
|
||||||
AttrSet.push_back(AttributeList::get(C, Index, B));
|
AttrSet.push_back(AttributeList::get(C, Index, B));
|
||||||
@ -1070,7 +1130,7 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C,
|
|||||||
if (!pImpl)
|
if (!pImpl)
|
||||||
return AttributeList();
|
return AttributeList();
|
||||||
|
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
|
SmallVector<std::pair<unsigned, AttributeSet>, 4> AttrSet;
|
||||||
for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
|
for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
|
||||||
unsigned Index = getSlotIndex(I);
|
unsigned Index = getSlotIndex(I);
|
||||||
if (Index != WithoutIndex)
|
if (Index != WithoutIndex)
|
||||||
@ -1110,32 +1170,29 @@ AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
|
|||||||
|
|
||||||
LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
|
LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
|
||||||
|
|
||||||
AttributeSetNode *AttributeList::getParamAttributes(unsigned Index) const {
|
AttributeSet AttributeList::getParamAttributes(unsigned Index) const {
|
||||||
return getAttributes(Index);
|
return getAttributes(Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeSetNode *AttributeList::getRetAttributes() const {
|
AttributeSet AttributeList::getRetAttributes() const {
|
||||||
return getAttributes(ReturnIndex);
|
return getAttributes(ReturnIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeSetNode *AttributeList::getFnAttributes() const {
|
AttributeSet AttributeList::getFnAttributes() const {
|
||||||
return getAttributes(FunctionIndex);
|
return getAttributes(FunctionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttributeList::hasAttribute(unsigned Index,
|
bool AttributeList::hasAttribute(unsigned Index,
|
||||||
Attribute::AttrKind Kind) const {
|
Attribute::AttrKind Kind) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).hasAttribute(Kind);
|
||||||
return ASN && ASN->hasAttribute(Kind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
|
bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).hasAttribute(Kind);
|
||||||
return ASN && ASN->hasAttribute(Kind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttributeList::hasAttributes(unsigned Index) const {
|
bool AttributeList::hasAttributes(unsigned Index) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).hasAttributes();
|
||||||
return ASN && ASN->hasAttributes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
|
bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
|
||||||
@ -1163,55 +1220,47 @@ bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
|
|||||||
|
|
||||||
Attribute AttributeList::getAttribute(unsigned Index,
|
Attribute AttributeList::getAttribute(unsigned Index,
|
||||||
Attribute::AttrKind Kind) const {
|
Attribute::AttrKind Kind) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getAttribute(Kind);
|
||||||
return ASN ? ASN->getAttribute(Kind) : Attribute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
|
Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getAttribute(Kind);
|
||||||
return ASN ? ASN->getAttribute(Kind) : Attribute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned AttributeList::getParamAlignment(unsigned Index) const {
|
unsigned AttributeList::getParamAlignment(unsigned Index) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getAlignment();
|
||||||
return ASN ? ASN->getAlignment() : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned AttributeList::getStackAlignment(unsigned Index) const {
|
unsigned AttributeList::getStackAlignment(unsigned Index) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getStackAlignment();
|
||||||
return ASN ? ASN->getStackAlignment() : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
|
uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getDereferenceableBytes();
|
||||||
return ASN ? ASN->getDereferenceableBytes() : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
|
uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getDereferenceableOrNullBytes();
|
||||||
return ASN ? ASN->getDereferenceableOrNullBytes() : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<unsigned, Optional<unsigned>>
|
std::pair<unsigned, Optional<unsigned>>
|
||||||
AttributeList::getAllocSizeArgs(unsigned Index) const {
|
AttributeList::getAllocSizeArgs(unsigned Index) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getAllocSizeArgs();
|
||||||
return ASN ? ASN->getAllocSizeArgs() : std::make_pair(0u, Optional<unsigned>(0u));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
|
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
|
||||||
AttributeSetNode *ASN = getAttributes(Index);
|
return getAttributes(Index).getAsString(InAttrGrp);
|
||||||
return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeSetNode *AttributeList::getAttributes(unsigned Index) const {
|
AttributeSet AttributeList::getAttributes(unsigned Index) const {
|
||||||
if (!pImpl) return nullptr;
|
if (!pImpl) return AttributeSet();
|
||||||
|
|
||||||
// Loop through to find the attribute node we want.
|
// Loop through to find the attribute node we want.
|
||||||
for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
|
for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
|
||||||
if (pImpl->getSlotIndex(I) == Index)
|
if (pImpl->getSlotIndex(I) == Index)
|
||||||
return pImpl->getSlotNode(I);
|
return pImpl->getSlotNode(I);
|
||||||
|
|
||||||
return nullptr;
|
return AttributeSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList::iterator AttributeList::begin(unsigned Slot) const {
|
AttributeList::iterator AttributeList::begin(unsigned Slot) const {
|
||||||
@ -1268,8 +1317,8 @@ LLVM_DUMP_METHOD void AttributeList::dump() const {
|
|||||||
// AttrBuilder Method Implementations
|
// AttrBuilder Method Implementations
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
AttrBuilder::AttrBuilder(AttributeList AS, unsigned Index) {
|
AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
|
||||||
AttributeListImpl *pImpl = AS.pImpl;
|
AttributeListImpl *pImpl = AL.pImpl;
|
||||||
if (!pImpl) return;
|
if (!pImpl) return;
|
||||||
|
|
||||||
for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
|
for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
|
||||||
@ -1283,9 +1332,9 @@ AttrBuilder::AttrBuilder(AttributeList AS, unsigned Index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrBuilder::AttrBuilder(AttributeSetNode *AS) {
|
AttrBuilder::AttrBuilder(AttributeSet AS) {
|
||||||
if (AS) {
|
if (AS.hasAttributes()) {
|
||||||
for (const Attribute &A : *AS)
|
for (const Attribute &A : AS)
|
||||||
addAttribute(A);
|
addAttribute(A);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
#include "llvm/Bitcode/BitcodeReader.h"
|
#include "llvm/Bitcode/BitcodeReader.h"
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
@ -1847,18 +1846,14 @@ void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) {
|
unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) {
|
||||||
auto *ASN = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
|
auto AS = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
|
||||||
if (!ASN)
|
return AS.getNumAttributes();
|
||||||
return 0;
|
|
||||||
return ASN->getNumAttributes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
|
||||||
LLVMAttributeRef *Attrs) {
|
LLVMAttributeRef *Attrs) {
|
||||||
auto *ASN = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
|
auto AS = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
|
||||||
if (!ASN)
|
for (auto A : AS)
|
||||||
return;
|
|
||||||
for (auto A: make_range(ASN->begin(), ASN->end()))
|
|
||||||
*Attrs++ = wrap(A);
|
*Attrs++ = wrap(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2178,19 +2173,15 @@ void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
|
|||||||
unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C,
|
unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C,
|
||||||
LLVMAttributeIndex Idx) {
|
LLVMAttributeIndex Idx) {
|
||||||
auto CS = CallSite(unwrap<Instruction>(C));
|
auto CS = CallSite(unwrap<Instruction>(C));
|
||||||
auto *ASN = CS.getAttributes().getAttributes(Idx);
|
auto AS = CS.getAttributes().getAttributes(Idx);
|
||||||
if (!ASN)
|
return AS.getNumAttributes();
|
||||||
return 0;
|
|
||||||
return ASN->getNumAttributes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
|
void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
|
||||||
LLVMAttributeRef *Attrs) {
|
LLVMAttributeRef *Attrs) {
|
||||||
auto CS = CallSite(unwrap<Instruction>(C));
|
auto CS = CallSite(unwrap<Instruction>(C));
|
||||||
auto *ASN = CS.getAttributes().getAttributes(Idx);
|
auto AS = CS.getAttributes().getAttributes(Idx);
|
||||||
if (!ASN)
|
for (auto A : AS)
|
||||||
return;
|
|
||||||
for (auto A: make_range(ASN->begin(), ASN->end()))
|
|
||||||
*Attrs++ = wrap(A);
|
*Attrs++ = wrap(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
#include "llvm/Analysis/LazyCallGraph.h"
|
#include "llvm/Analysis/LazyCallGraph.h"
|
||||||
#include "llvm/Analysis/Loads.h"
|
#include "llvm/Analysis/Loads.h"
|
||||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/CFG.h"
|
#include "llvm/IR/CFG.h"
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
@ -103,7 +102,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||||||
// Attribute - Keep track of the parameter attributes for the arguments
|
// Attribute - Keep track of the parameter attributes for the arguments
|
||||||
// that we are *not* promoting. For the ones that we do promote, the parameter
|
// that we are *not* promoting. For the ones that we do promote, the parameter
|
||||||
// attributes are lost
|
// attributes are lost
|
||||||
SmallVector<AttributeSetNode *, 8> AttributesVec;
|
SmallVector<AttributeSet, 8> AttributesVec;
|
||||||
const AttributeList &PAL = F->getAttributes();
|
const AttributeList &PAL = F->getAttributes();
|
||||||
|
|
||||||
// Add any return attributes.
|
// Add any return attributes.
|
||||||
@ -118,7 +117,8 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||||||
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
||||||
StructType *STy = cast<StructType>(AgTy);
|
StructType *STy = cast<StructType>(AgTy);
|
||||||
Params.insert(Params.end(), STy->element_begin(), STy->element_end());
|
Params.insert(Params.end(), STy->element_begin(), STy->element_end());
|
||||||
AttributesVec.insert(AttributesVec.end(), STy->getNumElements(), nullptr);
|
AttributesVec.insert(AttributesVec.end(), STy->getNumElements(),
|
||||||
|
AttributeSet());
|
||||||
++NumByValArgsPromoted;
|
++NumByValArgsPromoted;
|
||||||
} else if (!ArgsToPromote.count(&*I)) {
|
} else if (!ArgsToPromote.count(&*I)) {
|
||||||
// Unchanged argument
|
// Unchanged argument
|
||||||
@ -168,7 +168,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||||||
Params.push_back(GetElementPtrInst::getIndexedType(
|
Params.push_back(GetElementPtrInst::getIndexedType(
|
||||||
cast<PointerType>(I->getType()->getScalarType())->getElementType(),
|
cast<PointerType>(I->getType()->getScalarType())->getElementType(),
|
||||||
ArgIndex.second));
|
ArgIndex.second));
|
||||||
AttributesVec.push_back(nullptr);
|
AttributesVec.push_back(AttributeSet());
|
||||||
assert(Params.back());
|
assert(Params.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||||||
STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i), Call);
|
STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i), Call);
|
||||||
// TODO: Tell AA about the new values?
|
// TODO: Tell AA about the new values?
|
||||||
Args.push_back(new LoadInst(Idx, Idx->getName() + ".val", Call));
|
Args.push_back(new LoadInst(Idx, Idx->getName() + ".val", Call));
|
||||||
AttributesVec.push_back(nullptr);
|
AttributesVec.push_back(AttributeSet());
|
||||||
}
|
}
|
||||||
} else if (!I->use_empty()) {
|
} else if (!I->use_empty()) {
|
||||||
// Non-dead argument: insert GEPs and loads as appropriate.
|
// Non-dead argument: insert GEPs and loads as appropriate.
|
||||||
@ -283,7 +283,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||||||
newLoad->setAAMetadata(AAInfo);
|
newLoad->setAAMetadata(AAInfo);
|
||||||
|
|
||||||
Args.push_back(newLoad);
|
Args.push_back(newLoad);
|
||||||
AttributesVec.push_back(nullptr);
|
AttributesVec.push_back(AttributeSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/CallingConv.h"
|
#include "llvm/IR/CallingConv.h"
|
||||||
#include "llvm/IR/Constant.h"
|
#include "llvm/IR/Constant.h"
|
||||||
@ -686,12 +685,12 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
bool HasLiveReturnedArg = false;
|
bool HasLiveReturnedArg = false;
|
||||||
|
|
||||||
// Set up to build a new list of parameter attributes.
|
// Set up to build a new list of parameter attributes.
|
||||||
SmallVector<AttributeSetNode *, 8> AttributesVec;
|
SmallVector<AttributeSet, 8> AttributesVec;
|
||||||
const AttributeList &PAL = F->getAttributes();
|
const AttributeList &PAL = F->getAttributes();
|
||||||
|
|
||||||
// Reserve an empty slot for the return value attributes, which we will
|
// Reserve an empty slot for the return value attributes, which we will
|
||||||
// compute last.
|
// compute last.
|
||||||
AttributesVec.push_back(nullptr);
|
AttributesVec.push_back(AttributeSet());
|
||||||
|
|
||||||
// Remember which arguments are still alive.
|
// Remember which arguments are still alive.
|
||||||
SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
|
SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
|
||||||
@ -792,7 +791,7 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
|
assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
|
||||||
"Return attributes no longer compatible?");
|
"Return attributes no longer compatible?");
|
||||||
|
|
||||||
AttributesVec[0] = AttributeSetNode::get(F->getContext(), RAttrs);
|
AttributesVec[0] = AttributeSet::get(F->getContext(), RAttrs);
|
||||||
|
|
||||||
// Transfer the function attributes, if any.
|
// Transfer the function attributes, if any.
|
||||||
AttributesVec.push_back(PAL.getFnAttributes());
|
AttributesVec.push_back(PAL.getFnAttributes());
|
||||||
@ -833,7 +832,7 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
// return void.
|
// return void.
|
||||||
AttrBuilder RAttrs(CallPAL.getRetAttributes());
|
AttrBuilder RAttrs(CallPAL.getRetAttributes());
|
||||||
RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
|
RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
|
||||||
AttributesVec.push_back(AttributeSetNode::get(F->getContext(), RAttrs));
|
AttributesVec.push_back(AttributeSet::get(F->getContext(), RAttrs));
|
||||||
|
|
||||||
// Declare these outside of the loops, so we can reuse them for the second
|
// Declare these outside of the loops, so we can reuse them for the second
|
||||||
// loop, which loops the varargs.
|
// loop, which loops the varargs.
|
||||||
@ -845,15 +844,14 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
if (ArgAlive[i]) {
|
if (ArgAlive[i]) {
|
||||||
Args.push_back(*I);
|
Args.push_back(*I);
|
||||||
// Get original parameter attributes, but skip return attributes.
|
// Get original parameter attributes, but skip return attributes.
|
||||||
AttributeSetNode *Attrs = CallPAL.getParamAttributes(i + 1);
|
AttributeSet Attrs = CallPAL.getParamAttributes(i + 1);
|
||||||
if (NRetTy != RetTy && Attrs &&
|
if (NRetTy != RetTy && Attrs.hasAttribute(Attribute::Returned)) {
|
||||||
Attrs->hasAttribute(Attribute::Returned)) {
|
|
||||||
// If the return type has changed, then get rid of 'returned' on the
|
// If the return type has changed, then get rid of 'returned' on the
|
||||||
// call site. The alternative is to make all 'returned' attributes on
|
// call site. The alternative is to make all 'returned' attributes on
|
||||||
// call sites keep the return value alive just like 'returned'
|
// call sites keep the return value alive just like 'returned'
|
||||||
// attributes on function declaration but it's less clearly a win and
|
// attributes on function declaration but it's less clearly a win and
|
||||||
// this is not an expected case anyway
|
// this is not an expected case anyway
|
||||||
AttributesVec.push_back(AttributeSetNode::get(
|
AttributesVec.push_back(AttributeSet::get(
|
||||||
F->getContext(),
|
F->getContext(),
|
||||||
AttrBuilder(Attrs).removeAttribute(Attribute::Returned)));
|
AttrBuilder(Attrs).removeAttribute(Attribute::Returned)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -439,7 +439,8 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
|
|||||||
Context, AttributeList::ReturnIndex, NewFuncAttrs.getRetAttributes());
|
Context, AttributeList::ReturnIndex, NewFuncAttrs.getRetAttributes());
|
||||||
|
|
||||||
for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++) {
|
for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++) {
|
||||||
if (AttributeSetNode *Attrs = NewFuncAttrs.getParamAttributes(argIdx))
|
AttributeSet Attrs = NewFuncAttrs.getParamAttributes(argIdx);
|
||||||
|
if (Attrs.hasAttributes())
|
||||||
CallSiteAttrs = CallSiteAttrs.addAttributes(Context, argIdx, Attrs);
|
CallSiteAttrs = CallSiteAttrs.addAttributes(Context, argIdx, Attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "llvm/Analysis/InstructionSimplify.h"
|
#include "llvm/Analysis/InstructionSimplify.h"
|
||||||
#include "llvm/Analysis/MemoryBuiltins.h"
|
#include "llvm/Analysis/MemoryBuiltins.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
#include "llvm/IR/AttributeSetNode.h"
|
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/Constant.h"
|
#include "llvm/IR/Constant.h"
|
||||||
@ -4119,7 +4118,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeSetNode *FnAttrs = CallerPAL.getFnAttributes();
|
AttributeSet FnAttrs = CallerPAL.getFnAttributes();
|
||||||
if (CallerPAL.hasAttributes(AttributeList::FunctionIndex))
|
if (CallerPAL.hasAttributes(AttributeList::FunctionIndex))
|
||||||
attrVec.push_back(AttributeList::get(Callee->getContext(),
|
attrVec.push_back(AttributeList::get(Callee->getContext(),
|
||||||
AttributeList::FunctionIndex,
|
AttributeList::FunctionIndex,
|
||||||
@ -4218,7 +4217,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
|
|||||||
if (!NestAttrs.isEmpty()) {
|
if (!NestAttrs.isEmpty()) {
|
||||||
unsigned NestIdx = 1;
|
unsigned NestIdx = 1;
|
||||||
Type *NestTy = nullptr;
|
Type *NestTy = nullptr;
|
||||||
AttributeSetNode *NestAttr;
|
AttributeSet NestAttr;
|
||||||
|
|
||||||
// Look for a parameter marked with the 'nest' attribute.
|
// Look for a parameter marked with the 'nest' attribute.
|
||||||
for (FunctionType::param_iterator I = NestFTy->param_begin(),
|
for (FunctionType::param_iterator I = NestFTy->param_begin(),
|
||||||
@ -4233,7 +4232,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
|
|||||||
if (NestTy) {
|
if (NestTy) {
|
||||||
Instruction *Caller = CS.getInstruction();
|
Instruction *Caller = CS.getInstruction();
|
||||||
std::vector<Value*> NewArgs;
|
std::vector<Value*> NewArgs;
|
||||||
std::vector<AttributeSetNode *> NewAttrs;
|
std::vector<AttributeSet> NewAttrs;
|
||||||
NewArgs.reserve(CS.arg_size() + 1);
|
NewArgs.reserve(CS.arg_size() + 1);
|
||||||
NewAttrs.reserve(CS.arg_size() + 2);
|
NewAttrs.reserve(CS.arg_size() + 2);
|
||||||
|
|
||||||
|
@ -103,23 +103,21 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
|||||||
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
|
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
|
||||||
TypeMapper, Materializer));
|
TypeMapper, Materializer));
|
||||||
|
|
||||||
SmallVector<std::pair<unsigned, AttributeSetNode*>, 4> AttrVec;
|
SmallVector<AttributeSet, 4> AttrVec(NewFunc->arg_size() + 2);
|
||||||
AttributeList OldAttrs = OldFunc->getAttributes();
|
AttributeList OldAttrs = OldFunc->getAttributes();
|
||||||
|
|
||||||
// Copy the return attributes.
|
// Copy the return attributes.
|
||||||
if (auto *RetAttrs = OldAttrs.getRetAttributes())
|
AttrVec[0] = OldAttrs.getRetAttributes();
|
||||||
AttrVec.emplace_back(AttributeList::ReturnIndex, RetAttrs);
|
|
||||||
|
|
||||||
// Clone any argument attributes that are present in the VMap.
|
// Clone any argument attributes that are present in the VMap.
|
||||||
for (const Argument &OldArg : OldFunc->args())
|
for (const Argument &OldArg : OldFunc->args())
|
||||||
if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
|
if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
|
||||||
if (auto *ParmAttrs = OldAttrs.getParamAttributes(OldArg.getArgNo() + 1))
|
AttrVec[NewArg->getArgNo() + 1] =
|
||||||
AttrVec.emplace_back(NewArg->getArgNo() + 1, ParmAttrs);
|
OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy any function attributes.
|
// Copy any function attributes.
|
||||||
if (auto *FnAttrs = OldAttrs.getFnAttributes())
|
AttrVec.back() = OldAttrs.getFnAttributes();
|
||||||
AttrVec.emplace_back(AttributeList::FunctionIndex, FnAttrs);
|
|
||||||
|
|
||||||
NewFunc->setAttributes(AttributeList::get(NewFunc->getContext(), AttrVec));
|
NewFunc->setAttributes(AttributeList::get(NewFunc->getContext(), AttrVec));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user