[llvm] r299899 - Reland "[IR] Make AttributeSetNode public, avoid temporary AttributeList copies"
Richard Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 11 14:12:41 PDT 2017
This is breaking the modules buildbots by introducing a cyclic dependency
between IR/Attributes.h (which is in the set of prerequisites for building
tablegen) and IR/AttributeSetNode.h (which is listed as being in the IR
module and thus potentially including tablegen-generated headers).
Should the new header be in the intrinsics_gen module in the module map?
On 10 April 2017 at 16:31, Reid Kleckner via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: rnk
> Date: Mon Apr 10 18:31:05 2017
> New Revision: 299899
>
> URL: http://llvm.org/viewvc/llvm-project?rev=299899&view=rev
> Log:
> Reland "[IR] Make AttributeSetNode public, avoid temporary AttributeList
> copies"
>
> This re-lands r299875.
>
> I introduced a bug in Clang code responsible for replacing K&R, no
> prototype declarations with a real function definition with a prototype.
> The bug was here:
>
> // Collect any return attributes from the call.
> - if (oldAttrs.hasAttributes(llvm::AttributeList::ReturnIndex))
> - newAttrs.push_back(llvm::AttributeList::get(newFn->getContext(),
> -
> oldAttrs.getRetAttributes()));
> + newAttrs.push_back(oldAttrs.getRetAttributes());
>
> Previously getRetAttributes() carried AttributeList::ReturnIndex in its
> AttributeList. Now that we return the AttributeSetNode* directly, it no
> longer carries that index, and we call this overload with a single node:
> AttributeList::get(LLVMContext&, ArrayRef<AttributeSetNode*>)
>
> That aborted with an assertion on x86_32 targets. I added an explicit
> triple to the test and added CHECKs to help find issues like this in the
> future sooner.
>
> Added:
> llvm/trunk/include/llvm/IR/AttributeSetNode.h
> Removed:
> llvm/trunk/lib/IR/AttributeSetNode.h
> Modified:
> llvm/trunk/include/llvm/IR/Attributes.h
> llvm/trunk/lib/AsmParser/LLParser.cpp
> llvm/trunk/lib/AsmParser/LLParser.h
> llvm/trunk/lib/IR/AsmWriter.cpp
> llvm/trunk/lib/IR/AttributeImpl.h
> llvm/trunk/lib/IR/Attributes.cpp
> llvm/trunk/lib/IR/Core.cpp
> llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
> llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
> llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp
> llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
> llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
> llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
> llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp
>
> Added: llvm/trunk/include/llvm/IR/AttributeSetNode.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/IR/AttributeSetNode.h?rev=299899&view=auto
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/IR/AttributeSetNode.h (added)
> +++ llvm/trunk/include/llvm/IR/AttributeSetNode.h Mon Apr 10 18:31:05 2017
> @@ -0,0 +1,109 @@
> +//===-- 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)
> + : NumAttrs(Attrs.size()), AvailableAttrs(0) {
> + static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) *
> CHAR_BIT,
> + "Too many attributes for AvailableAttrs");
> + // There's memory after the node where we can store the entries in.
> + std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>(
> ));
> +
> + for (Attribute I : *this) {
> + if (!I.isStringAttribute()) {
> + AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
> + }
> + }
> + }
> +
> +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);
> +
> + static AttributeSetNode *get(AttributeList AS, unsigned Index) {
> + return AS.getAttributes(Index);
> + }
> +
> + /// \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
>
> Modified: llvm/trunk/include/llvm/IR/Attributes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
> llvm/IR/Attributes.h?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/include/llvm/IR/Attributes.h (original)
> +++ llvm/trunk/include/llvm/IR/Attributes.h Mon Apr 10 18:31:05 2017
> @@ -221,19 +221,26 @@ private:
> /// the empty attributes list.
> AttributeListImpl *pImpl = nullptr;
>
> - /// \brief The attributes for the specified index are returned.
> - AttributeSetNode *getAttributes(unsigned Index) const;
> -
> +public:
> /// \brief Create an AttributeList with the specified parameters in it.
> static AttributeList get(LLVMContext &C,
> ArrayRef<std::pair<unsigned, Attribute>>
> Attrs);
> static AttributeList
> get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>>
> Attrs);
>
> + /// \brief Create an AttributeList from a vector of AttributeSetNodes.
> The
> + /// index of each set is implied by its position in the array \p Attrs:
> + /// 0 : Return attributes
> + /// 1 to n-1 : Argument attributes
> + /// n : Function attributes
> + /// Any element that has no entries should be left null.
> + static AttributeList get(LLVMContext &C, ArrayRef<AttributeSetNode *>
> Attrs);
> +
> static AttributeList
> getImpl(LLVMContext &C,
> ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs);
>
> +private:
> explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
>
> public:
> @@ -272,6 +279,12 @@ public:
> AttributeList addAttributes(LLVMContext &C, unsigned Index,
> AttributeList Attrs) const;
>
> + AttributeList addAttributes(LLVMContext &C, unsigned Index,
> + AttributeSetNode *AS) const;
> +
> + AttributeList addAttributes(LLVMContext &C, unsigned Index,
> + const AttrBuilder &B) const;
> +
> /// \brief Remove the specified attribute at the specified index from
> this
> /// attribute list. Because attribute lists are immutable, this returns
> the
> /// new list.
> @@ -296,6 +309,11 @@ public:
> AttributeList removeAttributes(LLVMContext &C, unsigned Index,
> const AttrBuilder &Attrs) const;
>
> + /// \brief Remove all attributes at the specified index from this
> + /// attribute list. Because attribute lists are immutable, this returns
> the
> + /// new list.
> + AttributeList removeAttributes(LLVMContext &C, unsigned Index) const;
> +
> /// \brief Add the dereferenceable attribute to the attribute set at
> the given
> /// index. Because attribute sets are immutable, this returns a new set.
> AttributeList addDereferenceableAttr(LLVMContext &C, unsigned Index,
> @@ -321,13 +339,16 @@ public:
> LLVMContext &getContext() const;
>
> /// \brief The attributes for the specified index are returned.
> - AttributeList getParamAttributes(unsigned Index) const;
> + AttributeSetNode *getAttributes(unsigned Index) const;
> +
> + /// \brief The attributes for the specified index are returned.
> + AttributeSetNode *getParamAttributes(unsigned Index) const;
>
> /// \brief The attributes for the ret value are returned.
> - AttributeList getRetAttributes() const;
> + AttributeSetNode *getRetAttributes() const;
>
> /// \brief The function attributes are returned.
> - AttributeList getFnAttributes() const;
> + AttributeSetNode *getFnAttributes() const;
>
> /// \brief Return true if the attribute exists at the given index.
> bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
> @@ -462,6 +483,7 @@ public:
> addAttribute(A);
> }
> AttrBuilder(AttributeList AS, unsigned Idx);
> + AttrBuilder(AttributeSetNode *AS);
>
> void clear();
>
> @@ -478,7 +500,7 @@ public:
> AttrBuilder &removeAttribute(Attribute::AttrKind Val);
>
> /// \brief Remove the attributes from the builder.
> - AttrBuilder &removeAttributes(AttributeList A, uint64_t Index);
> + AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex);
>
> /// \brief Remove the target-dependent attribute to the builder.
> AttrBuilder &removeAttribute(StringRef A);
>
> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> AsmParser/LLParser.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Apr 10 18:31:05 2017
> @@ -19,6 +19,7 @@
> #include "llvm/ADT/STLExtras.h"
> #include "llvm/AsmParser/SlotMapping.h"
> #include "llvm/IR/Argument.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/AutoUpgrade.h"
> #include "llvm/IR/BasicBlock.h"
> #include "llvm/IR/CallingConv.h"
> @@ -131,9 +132,8 @@ bool LLParser::ValidateEndOfModule() {
>
> if (Function *Fn = dyn_cast<Function>(V)) {
> AttributeList AS = Fn->getAttributes();
> - AttrBuilder FnAttrs(AS.getFnAttributes(),
> AttributeList::FunctionIndex);
> - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex,
> - AS.getFnAttributes());
> + AttrBuilder FnAttrs(AS.getFnAttributes());
> + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
>
> FnAttrs.merge(B);
>
> @@ -150,9 +150,8 @@ bool LLParser::ValidateEndOfModule() {
> Fn->setAttributes(AS);
> } else if (CallInst *CI = dyn_cast<CallInst>(V)) {
> AttributeList AS = CI->getAttributes();
> - AttrBuilder FnAttrs(AS.getFnAttributes(),
> AttributeList::FunctionIndex);
> - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex,
> - AS.getFnAttributes());
> + AttrBuilder FnAttrs(AS.getFnAttributes());
> + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
> FnAttrs.merge(B);
> AS = AS.addAttributes(
> Context, AttributeList::FunctionIndex,
> @@ -160,9 +159,8 @@ bool LLParser::ValidateEndOfModule() {
> CI->setAttributes(AS);
> } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) {
> AttributeList AS = II->getAttributes();
> - AttrBuilder FnAttrs(AS.getFnAttributes(),
> AttributeList::FunctionIndex);
> - AS = AS.removeAttributes(Context, AttributeList::FunctionIndex,
> - AS.getFnAttributes());
> + AttrBuilder FnAttrs(AS.getFnAttributes());
> + AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
> FnAttrs.merge(B);
> AS = AS.addAttributes(
> Context, AttributeList::FunctionIndex,
> @@ -2123,7 +2121,6 @@ bool LLParser::ParseParameterList(SmallV
> if (ParseToken(lltok::lparen, "expected '(' in call"))
> return true;
>
> - unsigned AttrIndex = 1;
> while (Lex.getKind() != lltok::rparen) {
> // If this isn't the first argument, we need a comma.
> if (!ArgList.empty() &&
> @@ -2158,7 +2155,7 @@ bool LLParser::ParseParameterList(SmallV
> return true;
> }
> ArgList.push_back(ParamInfo(
> - ArgLoc, V, AttributeList::get(V->getContext(), AttrIndex++,
> ArgAttrs)));
> + ArgLoc, V, AttributeSetNode::get(V->getContext(), ArgAttrs)));
> }
>
> if (IsMustTailCall && InVarArgsFunc)
> @@ -2263,9 +2260,8 @@ bool LLParser::ParseArgumentList(SmallVe
> if (!FunctionType::isValidArgumentType(ArgTy))
> return Error(TypeLoc, "invalid type for function argument");
>
> - unsigned AttrIndex = 1;
> - ArgList.emplace_back(TypeLoc, ArgTy, AttributeList::get(ArgTy->
> getContext(),
> - AttrIndex++,
> Attrs),
> + ArgList.emplace_back(TypeLoc, ArgTy,
> + AttributeSetNode::get(ArgTy->getContext(),
> Attrs),
> std::move(Name));
>
> while (EatIfPresent(lltok::comma)) {
> @@ -2292,10 +2288,9 @@ bool LLParser::ParseArgumentList(SmallVe
> if (!ArgTy->isFirstClassType())
> return Error(TypeLoc, "invalid type for function argument");
>
> - ArgList.emplace_back(
> - TypeLoc, ArgTy,
> - AttributeList::get(ArgTy->getContext(), AttrIndex++, Attrs),
> - std::move(Name));
> + ArgList.emplace_back(TypeLoc, ArgTy,
> + AttributeSetNode::get(ArgTy->getContext(),
> Attrs),
> + std::move(Name));
> }
> }
>
> @@ -2319,7 +2314,7 @@ bool LLParser::ParseFunctionType(Type *&
> for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
> if (!ArgList[i].Name.empty())
> return Error(ArgList[i].Loc, "argument name invalid in function
> type");
> - if (ArgList[i].Attrs.hasAttributes(i + 1))
> + if (ArgList[i].Attrs)
> return Error(ArgList[i].Loc,
> "argument attributes invalid in function type");
> }
> @@ -4768,23 +4763,16 @@ bool LLParser::ParseFunctionHeader(Funct
> // Okay, if we got here, the function is syntactically valid. Convert
> types
> // and do semantic checks.
> std::vector<Type*> ParamTypeList;
> - SmallVector<AttributeList, 8> Attrs;
> + SmallVector<AttributeSetNode *, 8> Attrs;
>
> - if (RetAttrs.hasAttributes())
> - Attrs.push_back(AttributeList::get(RetType->getContext(),
> - AttributeList::ReturnIndex,
> RetAttrs));
> + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
>
> for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
> ParamTypeList.push_back(ArgList[i].Ty);
> - if (ArgList[i].Attrs.hasAttributes(i + 1)) {
> - AttrBuilder B(ArgList[i].Attrs, i + 1);
> - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1,
> B));
> - }
> + Attrs.push_back(ArgList[i].Attrs);
> }
>
> - if (FuncAttrs.hasAttributes())
> - Attrs.push_back(AttributeList::get(
> - RetType->getContext(), AttributeList::FunctionIndex, FuncAttrs));
> + Attrs.push_back(AttributeSetNode::get(Context, FuncAttrs));
>
> AttributeList PAL = AttributeList::get(Context, Attrs);
>
> @@ -5396,10 +5384,8 @@ bool LLParser::ParseInvoke(Instruction *
> return true;
>
> // Set up the Attribute for the function.
> - SmallVector<AttributeList, 8> Attrs;
> - if (RetAttrs.hasAttributes())
> - Attrs.push_back(AttributeList::get(RetType->getContext(),
> - AttributeList::ReturnIndex,
> RetAttrs));
> + SmallVector<AttributeSetNode *, 8> Attrs;
> + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
>
> SmallVector<Value*, 8> Args;
>
> @@ -5419,22 +5405,16 @@ bool LLParser::ParseInvoke(Instruction *
> return Error(ArgList[i].Loc, "argument is not of expected type '" +
> getTypeString(ExpectedTy) + "'");
> Args.push_back(ArgList[i].V);
> - if (ArgList[i].Attrs.hasAttributes(i + 1)) {
> - AttrBuilder B(ArgList[i].Attrs, i + 1);
> - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1,
> B));
> - }
> + Attrs.push_back(ArgList[i].Attrs);
> }
>
> if (I != E)
> return Error(CallLoc, "not enough parameters specified for call");
>
> - if (FnAttrs.hasAttributes()) {
> - if (FnAttrs.hasAlignmentAttr())
> - return Error(CallLoc, "invoke instructions may not have an
> alignment");
> + if (FnAttrs.hasAlignmentAttr())
> + return Error(CallLoc, "invoke instructions may not have an
> alignment");
>
> - Attrs.push_back(AttributeList::get(RetType->getContext(),
> - AttributeList::FunctionIndex,
> FnAttrs));
> - }
> + Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
>
> // Finish off the Attribute and check them
> AttributeList PAL = AttributeList::get(Context, Attrs);
> @@ -5998,10 +5978,8 @@ bool LLParser::ParseCall(Instruction *&I
> return true;
>
> // Set up the Attribute for the function.
> - SmallVector<AttributeList, 8> Attrs;
> - if (RetAttrs.hasAttributes())
> - Attrs.push_back(AttributeList::get(RetType->getContext(),
> - AttributeList::ReturnIndex,
> RetAttrs));
> + SmallVector<AttributeSetNode *, 8> Attrs;
> + Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
>
> SmallVector<Value*, 8> Args;
>
> @@ -6021,22 +5999,16 @@ bool LLParser::ParseCall(Instruction *&I
> return Error(ArgList[i].Loc, "argument is not of expected type '" +
> getTypeString(ExpectedTy) + "'");
> Args.push_back(ArgList[i].V);
> - if (ArgList[i].Attrs.hasAttributes(i + 1)) {
> - AttrBuilder B(ArgList[i].Attrs, i + 1);
> - Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1,
> B));
> - }
> + Attrs.push_back(ArgList[i].Attrs);
> }
>
> if (I != E)
> return Error(CallLoc, "not enough parameters specified for call");
>
> - if (FnAttrs.hasAttributes()) {
> - if (FnAttrs.hasAlignmentAttr())
> - return Error(CallLoc, "call instructions may not have an
> alignment");
> + if (FnAttrs.hasAlignmentAttr())
> + return Error(CallLoc, "call instructions may not have an alignment");
>
> - Attrs.push_back(AttributeList::get(RetType->getContext(),
> - AttributeList::FunctionIndex,
> FnAttrs));
> - }
> + Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
>
> // Finish off the Attribute and check them
> AttributeList PAL = AttributeList::get(Context, Attrs);
>
> Modified: llvm/trunk/lib/AsmParser/LLParser.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> AsmParser/LLParser.h?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/AsmParser/LLParser.h (original)
> +++ llvm/trunk/lib/AsmParser/LLParser.h Mon Apr 10 18:31:05 2017
> @@ -397,8 +397,8 @@ namespace llvm {
> struct ParamInfo {
> LocTy Loc;
> Value *V;
> - AttributeList Attrs;
> - ParamInfo(LocTy loc, Value *v, AttributeList attrs)
> + AttributeSetNode *Attrs;
> + ParamInfo(LocTy loc, Value *v, AttributeSetNode *attrs)
> : Loc(loc), V(v), Attrs(attrs) {}
> };
> bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
> @@ -450,9 +450,9 @@ namespace llvm {
> struct ArgInfo {
> LocTy Loc;
> Type *Ty;
> - AttributeList Attrs;
> + AttributeSetNode *Attrs;
> std::string Name;
> - ArgInfo(LocTy L, Type *ty, AttributeList Attr, const std::string &N)
> + ArgInfo(LocTy L, Type *ty, AttributeSetNode *Attr, const
> std::string &N)
> : Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
> };
> bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool
> &isVarArg);
>
> Modified: llvm/trunk/lib/IR/AsmWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/
> AsmWriter.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/IR/AsmWriter.cpp (original)
> +++ llvm/trunk/lib/IR/AsmWriter.cpp Mon Apr 10 18:31:05 2017
> @@ -21,6 +21,8 @@
> #include "llvm/ADT/SmallString.h"
> #include "llvm/ADT/StringExtras.h"
> #include "llvm/IR/AssemblyAnnotationWriter.h"
> +#include "llvm/IR/AttributeSetNode.h"
> +#include "llvm/IR/Attributes.h"
> #include "llvm/IR/CFG.h"
> #include "llvm/IR/CallingConv.h"
> #include "llvm/IR/Constants.h"
> @@ -604,7 +606,7 @@ private:
> unsigned mdnNext;
>
> /// asMap - The slot map for attribute sets.
> - DenseMap<AttributeList, unsigned> asMap;
> + DenseMap<AttributeSetNode *, unsigned> asMap;
> unsigned asNext;
> public:
> /// Construct from a module.
> @@ -627,7 +629,7 @@ public:
> int getLocalSlot(const Value *V);
> int getGlobalSlot(const GlobalValue *V);
> int getMetadataSlot(const MDNode *N);
> - int getAttributeGroupSlot(AttributeList AS);
> + int getAttributeGroupSlot(AttributeSetNode *AS);
>
> /// If you'd like to deal with a function instead of just a module, use
> /// this method to get its data into the SlotTracker.
> @@ -650,8 +652,8 @@ public:
> unsigned mdn_size() const { return mdnMap.size(); }
> bool mdn_empty() const { return mdnMap.empty(); }
>
> - /// AttributeList map iterators.
> - typedef DenseMap<AttributeList, unsigned>::iterator as_iterator;
> + /// AttributeSetNode map iterators.
> + typedef DenseMap<AttributeSetNode *, unsigned>::iterator as_iterator;
> as_iterator as_begin() { return asMap.begin(); }
> as_iterator as_end() { return asMap.end(); }
> unsigned as_size() const { return asMap.size(); }
> @@ -671,8 +673,8 @@ private:
> /// CreateFunctionSlot - Insert the specified Value* into the slot
> table.
> void CreateFunctionSlot(const Value *V);
>
> - /// \brief Insert the specified AttributeList into the slot table.
> - void CreateAttributeSetSlot(AttributeList AS);
> + /// \brief Insert the specified AttributeSetNode into the slot table.
> + void CreateAttributeSetSlot(AttributeSetNode *AS);
>
> /// Add all of the module level global variables (and their
> initializers)
> /// and function declarations, but not the contents of those functions.
> @@ -831,8 +833,8 @@ void SlotTracker::processModule() {
>
> // Add all the function attributes to the table.
> // FIXME: Add attributes of other objects?
> - AttributeList FnAttrs = F.getAttributes().getFnAttributes();
> - if (FnAttrs.hasAttributes(AttributeList::FunctionIndex))
> + AttributeSetNode *FnAttrs = F.getAttributes().getFnAttributes();
> + if (FnAttrs)
> CreateAttributeSetSlot(FnAttrs);
> }
>
> @@ -869,13 +871,13 @@ void SlotTracker::processFunction() {
> // target may not be linked into the optimizer.
> if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
> // Add all the call attributes to the table.
> - AttributeList Attrs = CI->getAttributes().getFnAttributes();
> - if (Attrs.hasAttributes(AttributeList::FunctionIndex))
> + AttributeSetNode *Attrs = CI->getAttributes().getFnAttributes();
> + if (Attrs)
> CreateAttributeSetSlot(Attrs);
> } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
> // Add all the call attributes to the table.
> - AttributeList Attrs = II->getAttributes().getFnAttributes();
> - if (Attrs.hasAttributes(AttributeList::FunctionIndex))
> + AttributeSetNode *Attrs = II->getAttributes().getFnAttributes();
> + if (Attrs)
> CreateAttributeSetSlot(Attrs);
> }
> }
> @@ -961,11 +963,11 @@ int SlotTracker::getLocalSlot(const Valu
> return FI == fMap.end() ? -1 : (int)FI->second;
> }
>
> -int SlotTracker::getAttributeGroupSlot(AttributeList AS) {
> +int SlotTracker::getAttributeGroupSlot(AttributeSetNode *AS) {
> // Check for uninitialized state and do lazy initialization.
> initialize();
>
> - // Find the AttributeList in the module map.
> + // Find the AttributeSetNode in the module map.
> as_iterator AI = asMap.find(AS);
> return AI == asMap.end() ? -1 : (int)AI->second;
> }
> @@ -1015,9 +1017,8 @@ void SlotTracker::CreateMetadataSlot(con
> CreateMetadataSlot(Op);
> }
>
> -void SlotTracker::CreateAttributeSetSlot(AttributeList AS) {
> - assert(AS.hasAttributes(AttributeList::FunctionIndex) &&
> - "Doesn't need a slot!");
> +void SlotTracker::CreateAttributeSetSlot(AttributeSetNode *AS) {
> + assert(AS && "Doesn't need a slot!");
>
> as_iterator I = asMap.find(AS);
> if (I != asMap.end())
> @@ -2606,17 +2607,10 @@ void AssemblyWriter::printFunction(const
>
> const AttributeList &Attrs = F->getAttributes();
> if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
> - AttributeList AS = Attrs.getFnAttributes();
> + AttributeSetNode *AS = Attrs.getFnAttributes();
> std::string AttrStr;
>
> - unsigned Idx = 0;
> - for (unsigned E = AS.getNumSlots(); Idx != E; ++Idx)
> - if (AS.getSlotIndex(Idx) == AttributeList::FunctionIndex)
> - break;
> -
> - for (AttributeList::iterator I = AS.begin(Idx), E = AS.end(Idx); I !=
> E;
> - ++I) {
> - Attribute Attr = *I;
> + for (const Attribute &Attr : *AS) {
> if (!Attr.isStringAttribute()) {
> if (!AttrStr.empty()) AttrStr += ' ';
> AttrStr += Attr.getAsString();
> @@ -3256,7 +3250,7 @@ void AssemblyWriter::printMDNodeBody(con
> }
>
> void AssemblyWriter::writeAllAttributeGroups() {
> - std::vector<std::pair<AttributeList, unsigned>> asVec;
> + std::vector<std::pair<AttributeSetNode *, unsigned>> asVec;
> asVec.resize(Machine.as_size());
>
> for (SlotTracker::as_iterator I = Machine.as_begin(), E =
> Machine.as_end();
> @@ -3265,7 +3259,7 @@ void AssemblyWriter::writeAllAttributeGr
>
> for (const auto &I : asVec)
> Out << "attributes #" << I.second << " = { "
> - << I.first.getAsString(AttributeList::FunctionIndex, true) << "
> }\n";
> + << I.first->getAsString(true) << " }\n";
> }
>
> void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
>
> Modified: llvm/trunk/lib/IR/AttributeImpl.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/
> AttributeImpl.h?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/IR/AttributeImpl.h (original)
> +++ llvm/trunk/lib/IR/AttributeImpl.h Mon Apr 10 18:31:05 2017
> @@ -16,10 +16,10 @@
> #ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H
> #define LLVM_LIB_IR_ATTRIBUTEIMPL_H
>
> -#include "AttributeSetNode.h"
> #include "llvm/ADT/ArrayRef.h"
> #include "llvm/ADT/FoldingSet.h"
> #include "llvm/ADT/StringRef.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/Attributes.h"
> #include "llvm/Support/TrailingObjects.h"
> #include <algorithm>
>
> Removed: llvm/trunk/lib/IR/AttributeSetNode.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/
> AttributeSetNode.h?rev=299898&view=auto
> ============================================================
> ==================
> --- llvm/trunk/lib/IR/AttributeSetNode.h (original)
> +++ llvm/trunk/lib/IR/AttributeSetNode.h (removed)
> @@ -1,107 +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 node class used internally by
> AttributeList.
> -///
> -//===------------------------------------------------------
> ----------------===//
> -
> -#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)
> - : NumAttrs(Attrs.size()), AvailableAttrs(0) {
> - static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) *
> CHAR_BIT,
> - "Too many attributes for AvailableAttrs");
> - // There's memory after the node where we can store the entries in.
> - std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>(
> ));
> -
> - for (Attribute I : *this) {
> - if (!I.isStringAttribute()) {
> - AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
> - }
> - }
> - }
> -
> -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, ArrayRef<Attribute> Attrs);
> -
> - static AttributeSetNode *get(AttributeList AS, unsigned Index) {
> - return AS.getAttributes(Index);
> - }
> -
> - /// \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
>
> Modified: llvm/trunk/lib/IR/Attributes.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/
> Attributes.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/IR/Attributes.cpp (original)
> +++ llvm/trunk/lib/IR/Attributes.cpp Mon Apr 10 18:31:05 2017
> @@ -14,7 +14,6 @@
> //===-------------------------------------------------------
> ---------------===//
>
> #include "AttributeImpl.h"
> -#include "AttributeSetNode.h"
> #include "LLVMContextImpl.h"
> #include "llvm/ADT/ArrayRef.h"
> #include "llvm/ADT/FoldingSet.h"
> @@ -24,6 +23,7 @@
> #include "llvm/ADT/StringExtras.h"
> #include "llvm/ADT/StringRef.h"
> #include "llvm/ADT/Twine.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/Attributes.h"
> #include "llvm/IR/Function.h"
> #include "llvm/IR/LLVMContext.h"
> @@ -527,6 +527,48 @@ AttributeSetNode *AttributeSetNode::get(
> return PA;
> }
>
> +AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const
> AttrBuilder &B) {
> + // Add target-independent attributes.
> + SmallVector<Attribute, 8> Attrs;
> + for (Attribute::AttrKind Kind = Attribute::None;
> + Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind +
> 1)) {
> + if (!B.contains(Kind))
> + continue;
> +
> + Attribute Attr;
> + switch (Kind) {
> + case Attribute::Alignment:
> + Attr = Attribute::getWithAlignment(C, B.getAlignment());
> + break;
> + case Attribute::StackAlignment:
> + Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
> + break;
> + case Attribute::Dereferenceable:
> + Attr = Attribute::getWithDereferenceableBytes(
> + C, B.getDereferenceableBytes());
> + break;
> + case Attribute::DereferenceableOrNull:
> + Attr = Attribute::getWithDereferenceableOrNullBytes(
> + C, B.getDereferenceableOrNullBytes());
> + break;
> + case Attribute::AllocSize: {
> + auto A = B.getAllocSizeArgs();
> + Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
> + break;
> + }
> + default:
> + Attr = Attribute::get(C, Kind);
> + }
> + Attrs.push_back(Attr);
> + }
> +
> + // Add target-dependent (string) attributes.
> + for (const auto &TDA : B.td_attrs())
> + Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
> +
> + return get(C, Attrs);
> +}
> +
> bool AttributeSetNode::hasAttribute(StringRef Kind) const {
> for (Attribute I : *this)
> if (I.hasAttribute(Kind))
> @@ -612,6 +654,19 @@ LLVM_DUMP_METHOD void AttributeListImpl:
>
> AttributeList AttributeList::getImpl(
> LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>>
> Attrs) {
> + assert(!Attrs.empty() && "creating pointless AttributeList");
> +#ifndef NDEBUG
> + unsigned LastIndex = 0;
> + bool IsFirst = true;
> + for (const auto &AttrPair : Attrs) {
> + assert((IsFirst || LastIndex < AttrPair.first) &&
> + "unsorted or duplicate AttributeList indices");
> + assert(AttrPair.second && "pointless AttributeList slot");
> + LastIndex = AttrPair.first;
> + IsFirst = false;
> + }
> +#endif
> +
> LLVMContextImpl *pImpl = C.pImpl;
> FoldingSetNodeID ID;
> AttributeListImpl::Profile(ID, Attrs);
> @@ -680,50 +735,32 @@ AttributeList::get(LLVMContext &C,
> return getImpl(C, Attrs);
> }
>
> +AttributeList AttributeList::get(LLVMContext &C,
> ArrayRef<AttributeSetNode*> Attrs) {
> + assert(Attrs.size() >= 2 &&
> + "should always have function and return attr slots");
> + SmallVector<std::pair<unsigned, AttributeSetNode *>, 8> AttrPairs;
> + size_t Index = 0;
> + for (AttributeSetNode *AS : Attrs) {
> + if (AS) {
> + // If this is the last AttributeSetNode, it's for the function.
> + if (Index == Attrs.size() - 1)
> + Index = AttributeList::FunctionIndex;
> + AttrPairs.emplace_back(Index, AS);
> + }
> + ++Index;
> + }
> + if (AttrPairs.empty())
> + return AttributeList();
> + return getImpl(C, AttrPairs);
> +}
> +
> AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
> const AttrBuilder &B) {
> if (!B.hasAttributes())
> return AttributeList();
> -
> - // Add target-independent attributes.
> - SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
> - for (Attribute::AttrKind Kind = Attribute::None;
> - Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind +
> 1)) {
> - if (!B.contains(Kind))
> - continue;
> -
> - Attribute Attr;
> - switch (Kind) {
> - case Attribute::Alignment:
> - Attr = Attribute::getWithAlignment(C, B.getAlignment());
> - break;
> - case Attribute::StackAlignment:
> - Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
> - break;
> - case Attribute::Dereferenceable:
> - Attr = Attribute::getWithDereferenceableBytes(
> - C, B.getDereferenceableBytes());
> - break;
> - case Attribute::DereferenceableOrNull:
> - Attr = Attribute::getWithDereferenceableOrNullBytes(
> - C, B.getDereferenceableOrNullBytes());
> - break;
> - case Attribute::AllocSize: {
> - auto A = B.getAllocSizeArgs();
> - Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
> - break;
> - }
> - default:
> - Attr = Attribute::get(C, Kind);
> - }
> - Attrs.emplace_back(Index, Attr);
> - }
> -
> - // Add target-dependent (string) attributes.
> - for (const auto &TDA : B.td_attrs())
> - Attrs.emplace_back(Index, Attribute::get(C, TDA.first, TDA.second));
> -
> - return get(C, Attrs);
> + AttributeSetNode *ASN = AttributeSetNode::get(C, B);
> + std::pair<unsigned, AttributeSetNode *> Arr[1] = {{Index, ASN}};
> + return getImpl(C, Arr);
> }
>
> AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
> @@ -791,31 +828,31 @@ AttributeList AttributeList::addAttribut
> AttributeList AttributeList::addAttribute(LLVMContext &C,
> ArrayRef<unsigned> Indices,
> Attribute A) const {
> - unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0;
> - auto IdxI = Indices.begin(), IdxE = Indices.end();
> - SmallVector<AttributeList, 4> AttrSet;
> + assert(std::is_sorted(Indices.begin(), Indices.end()));
>
> - while (I != E && IdxI != IdxE) {
> - if (getSlotIndex(I) < *IdxI)
> - AttrSet.emplace_back(getSlotAttributes(I++));
> - else if (getSlotIndex(I) > *IdxI)
> - AttrSet.emplace_back(AttributeList::get(C, std::make_pair(*IdxI++,
> A)));
> - else {
> - AttrBuilder B(getSlotAttributes(I), *IdxI);
> - B.addAttribute(A);
> - AttrSet.emplace_back(AttributeList::get(C, *IdxI, B));
> + unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0;
> + SmallVector<IndexAttrPair, 4> AttrVec;
> + for (unsigned Index : Indices) {
> + // Add all attribute slots before the current index.
> + for (; I < E && getSlotIndex(I) < Index; ++I)
> + AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
> +
> + // Add the attribute at this index. If we already have attributes at
> this
> + // index, merge them into a new set.
> + AttrBuilder B;
> + if (I < E && getSlotIndex(I) == Index) {
> + B.merge(AttrBuilder(pImpl->getSlotNode(I)));
> ++I;
> - ++IdxI;
> }
> + B.addAttribute(A);
> + AttrVec.emplace_back(Index, AttributeSetNode::get(C, B));
> }
>
> - while (I != E)
> - AttrSet.emplace_back(getSlotAttributes(I++));
> + // Add remaining attributes.
> + for (; I < E; ++I)
> + AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
>
> - while (IdxI != IdxE)
> - AttrSet.emplace_back(AttributeList::get(C, std::make_pair(*IdxI++,
> A)));
> -
> - return get(C, AttrSet);
> + return get(C, AttrVec);
> }
>
> AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned
> Index,
> @@ -823,51 +860,58 @@ AttributeList AttributeList::addAttribut
> if (!pImpl) return Attrs;
> if (!Attrs.pImpl) return *this;
>
> + return addAttributes(C, Index, Attrs.getAttributes(Index));
> +}
> +
> +AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned
> Index,
> + AttributeSetNode *AS) const {
> + if (!AS)
> + return *this;
> +
> #ifndef NDEBUG
> // FIXME it is not obvious how this should work for alignment. For now,
> say
> // we can't change a known alignment.
> unsigned OldAlign = getParamAlignment(Index);
> - unsigned NewAlign = Attrs.getParamAlignment(Index);
> + unsigned NewAlign = AS->getAlignment();
> assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
> "Attempt to change alignment!");
> #endif
>
> - // Add the attribute slots before the one we're trying to add.
> - SmallVector<AttributeList, 4> AttrSet;
> + SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
> uint64_t NumAttrs = pImpl->getNumSlots();
> - AttributeList AS;
> - uint64_t LastIndex = 0;
> - for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
> - if (getSlotIndex(I) >= Index) {
> - if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
> - break;
> - }
> - LastIndex = I + 1;
> - AttrSet.push_back(getSlotAttributes(I));
> - }
> + unsigned I;
>
> - // Now add the attribute into the correct slot. There may already be an
> - // AttributeList there.
> - AttrBuilder B(AS, Index);
> -
> - for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
> - if (Attrs.getSlotIndex(I) == Index) {
> - for (AttributeListImpl::iterator II = Attrs.pImpl->begin(I),
> - IE = Attrs.pImpl->end(I);
> - II != IE; ++II)
> - B.addAttribute(*II);
> + // Add all the attribute slots before the one we need to merge.
> + for (I = 0; I < NumAttrs; ++I) {
> + if (getSlotIndex(I) >= Index)
> break;
> - }
> + AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
> + }
>
> - AttrSet.push_back(AttributeList::get(C, Index, B));
> + if (I < NumAttrs && getSlotIndex(I) == Index) {
> + // We need to merge two AttributeSetNodes.
> + AttributeSetNode *Merged = AttributeSetNode::get(
> + C, AttrBuilder(pImpl->getSlotNode(I)).merge(AttrBuilder(AS)));
> + AttrSet.emplace_back(Index, Merged);
> + ++I;
> + } else {
> + // Otherwise, there were no attributes at this position in the
> original
> + // list. Add the set as is.
> + AttrSet.emplace_back(Index, AS);
> + }
>
> - // Add the remaining attribute slots.
> - for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
> - AttrSet.push_back(getSlotAttributes(I));
> + // Add the remaining entries.
> + for (; I < NumAttrs; ++I)
> + AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
>
> return get(C, AttrSet);
> }
>
> +AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned
> Index,
> + const AttrBuilder &B) const {
> + return get(C, Index, AttributeSetNode::get(C, B));
> +}
> +
> AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned
> Index,
> Attribute::AttrKind Kind)
> const {
> if (!hasAttribute(Index, Kind)) return *this;
> @@ -961,6 +1005,20 @@ AttributeList AttributeList::removeAttri
> return get(C, AttrSet);
> }
>
> +AttributeList AttributeList::removeAttributes(LLVMContext &C,
> + unsigned WithoutIndex)
> const {
> + if (!pImpl)
> + return AttributeList();
> +
> + SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
> + for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
> + unsigned Index = getSlotIndex(I);
> + if (Index != WithoutIndex)
> + AttrSet.push_back({Index, pImpl->getSlotNode(I)});
> + }
> + return get(C, AttrSet);
> +}
> +
> AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
> unsigned Index,
> uint64_t Bytes) const
> {
> @@ -992,32 +1050,16 @@ AttributeList::addAllocSizeAttr(LLVMCont
>
> LLVMContext &AttributeList::getContext() const { return
> pImpl->getContext(); }
>
> -AttributeList AttributeList::getParamAttributes(unsigned Index) const {
> - return pImpl && hasAttributes(Index)
> - ? AttributeList::get(
> - pImpl->getContext(),
> - ArrayRef<std::pair<unsigned, AttributeSetNode *>>(
> - std::make_pair(Index, getAttributes(Index))))
> - : AttributeList();
> -}
> -
> -AttributeList AttributeList::getRetAttributes() const {
> - return pImpl && hasAttributes(ReturnIndex)
> - ? AttributeList::get(
> - pImpl->getContext(),
> - ArrayRef<std::pair<unsigned, AttributeSetNode *>>(
> - std::make_pair(ReturnIndex,
> getAttributes(ReturnIndex))))
> - : AttributeList();
> -}
> -
> -AttributeList AttributeList::getFnAttributes() const {
> - return pImpl && hasAttributes(FunctionIndex)
> - ? AttributeList::get(
> - pImpl->getContext(),
> - ArrayRef<std::pair<unsigned, AttributeSetNode *>>(
> - std::make_pair(FunctionIndex,
> - getAttributes(FunctionIndex))))
> - : AttributeList();
> +AttributeSetNode *AttributeList::getParamAttributes(unsigned Index)
> const {
> + return getAttributes(Index);
> +}
> +
> +AttributeSetNode *AttributeList::getRetAttributes() const {
> + return getAttributes(ReturnIndex);
> +}
> +
> +AttributeSetNode *AttributeList::getFnAttributes() const {
> + return getAttributes(FunctionIndex);
> }
>
> bool AttributeList::hasAttribute(unsigned Index,
> @@ -1181,6 +1223,13 @@ AttrBuilder::AttrBuilder(AttributeList A
> }
> }
>
> +AttrBuilder::AttrBuilder(AttributeSetNode *AS) {
> + if (AS) {
> + for (const Attribute &A : *AS)
> + addAttribute(A);
> + }
> +}
> +
> void AttrBuilder::clear() {
> Attrs.reset();
> TargetDepAttrs.clear();
>
> Modified: llvm/trunk/lib/IR/Core.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/
> Core.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/IR/Core.cpp (original)
> +++ llvm/trunk/lib/IR/Core.cpp Mon Apr 10 18:31:05 2017
> @@ -16,7 +16,7 @@
> #include "llvm/ADT/StringSwitch.h"
> #include "llvm/Bitcode/BitcodeReader.h"
> #include "llvm/IR/Attributes.h"
> -#include "AttributeSetNode.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/CallSite.h"
> #include "llvm/IR/Constants.h"
> #include "llvm/IR/DerivedTypes.h"
>
> Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/
> ArgumentPromotion.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Mon Apr 10
> 18:31:05 2017
> @@ -42,6 +42,7 @@
> #include "llvm/Analysis/LazyCallGraph.h"
> #include "llvm/Analysis/Loads.h"
> #include "llvm/Analysis/TargetLibraryInfo.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/CFG.h"
> #include "llvm/IR/CallSite.h"
> #include "llvm/IR/Constants.h"
> @@ -102,13 +103,11 @@ doPromotion(Function *F, SmallPtrSetImpl
> // Attribute - Keep track of the parameter attributes for the arguments
> // that we are *not* promoting. For the ones that we do promote, the
> parameter
> // attributes are lost
> - SmallVector<AttributeList, 8> AttributesVec;
> + SmallVector<AttributeSetNode *, 8> AttributesVec;
> const AttributeList &PAL = F->getAttributes();
>
> // Add any return attributes.
> - if (PAL.hasAttributes(AttributeList::ReturnIndex))
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), PAL.getRetAttributes()));
> + AttributesVec.push_back(PAL.getRetAttributes());
>
> // First, determine the new argument list
> unsigned ArgIndex = 1;
> @@ -119,16 +118,12 @@ doPromotion(Function *F, SmallPtrSetImpl
> Type *AgTy = cast<PointerType>(I->getType())->getElementType();
> StructType *STy = cast<StructType>(AgTy);
> Params.insert(Params.end(), STy->element_begin(),
> STy->element_end());
> + AttributesVec.insert(AttributesVec.end(), STy->getNumElements(),
> nullptr);
> ++NumByValArgsPromoted;
> } else if (!ArgsToPromote.count(&*I)) {
> // Unchanged argument
> Params.push_back(I->getType());
> - AttributeList attrs = PAL.getParamAttributes(ArgIndex);
> - if (attrs.hasAttributes(ArgIndex)) {
> - AttrBuilder B(attrs, ArgIndex);
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), Params.size(), B));
> - }
> + AttributesVec.push_back(PAL.getParamAttributes(ArgIndex));
> } else if (I->use_empty()) {
> // Dead argument (which are always marked as promotable)
> ++NumArgumentsDead;
> @@ -173,6 +168,7 @@ doPromotion(Function *F, SmallPtrSetImpl
> Params.push_back(GetElementPtrInst::getIndexedType(
> cast<PointerType>(I->getType()->getScalarType())->
> getElementType(),
> ArgIndex.second));
> + AttributesVec.push_back(nullptr);
> assert(Params.back());
> }
>
> @@ -184,9 +180,7 @@ doPromotion(Function *F, SmallPtrSetImpl
> }
>
> // Add any function attributes.
> - if (PAL.hasAttributes(AttributeList::FunctionIndex))
> - AttributesVec.push_back(
> - AttributeList::get(FTy->getContext(), PAL.getFnAttributes()));
> + AttributesVec.push_back(PAL.getFnAttributes());
>
> Type *RetTy = FTy->getReturnType();
>
> @@ -223,9 +217,7 @@ doPromotion(Function *F, SmallPtrSetImpl
> const AttributeList &CallPAL = CS.getAttributes();
>
> // Add any return attributes.
> - if (CallPAL.hasAttributes(AttributeList::ReturnIndex))
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(),
> CallPAL.getRetAttributes()));
> + AttributesVec.push_back(CallPAL.getRetAttributes());
>
> // Loop over the operands, inserting GEP and loads in the caller as
> // appropriate.
> @@ -235,12 +227,7 @@ doPromotion(Function *F, SmallPtrSetImpl
> ++I, ++AI, ++ArgIndex)
> if (!ArgsToPromote.count(&*I) && !ByValArgsToTransform.count(&*I))
> {
> Args.push_back(*AI); // Unmodified argument
> -
> - if (CallPAL.hasAttributes(ArgIndex)) {
> - AttrBuilder B(CallPAL, ArgIndex);
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), Args.size(), B));
> - }
> + AttributesVec.push_back(CallPAL.getAttributes(ArgIndex));
> } else if (ByValArgsToTransform.count(&*I)) {
> // Emit a GEP and load for each element of the struct.
> Type *AgTy = cast<PointerType>(I->getType())->getElementType();
> @@ -253,6 +240,7 @@ doPromotion(Function *F, SmallPtrSetImpl
> STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i), Call);
> // TODO: Tell AA about the new values?
> Args.push_back(new LoadInst(Idx, Idx->getName() + ".val",
> Call));
> + AttributesVec.push_back(nullptr);
> }
> } else if (!I->use_empty()) {
> // Non-dead argument: insert GEPs and loads as appropriate.
> @@ -295,23 +283,18 @@ doPromotion(Function *F, SmallPtrSetImpl
> newLoad->setAAMetadata(AAInfo);
>
> Args.push_back(newLoad);
> + AttributesVec.push_back(nullptr);
> }
> }
>
> // Push any varargs arguments on the list.
> for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
> Args.push_back(*AI);
> - if (CallPAL.hasAttributes(ArgIndex)) {
> - AttrBuilder B(CallPAL, ArgIndex);
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), Args.size(), B));
> - }
> + AttributesVec.push_back(CallPAL.getAttributes(ArgIndex));
> }
>
> // Add any function attributes.
> - if (CallPAL.hasAttributes(AttributeList::FunctionIndex))
> - AttributesVec.push_back(
> - AttributeList::get(Call->getContext(),
> CallPAL.getFnAttributes()));
> + AttributesVec.push_back(CallPAL.getFnAttributes());
>
> SmallVector<OperandBundleDef, 1> OpBundles;
> CS.getOperandBundlesAsDefs(OpBundles);
>
> Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/
> DeadArgumentElimination.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Mon Apr 10
> 18:31:05 2017
> @@ -21,6 +21,7 @@
> #include "llvm/ADT/SmallVector.h"
> #include "llvm/ADT/Statistic.h"
> #include "llvm/ADT/StringExtras.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/CallSite.h"
> #include "llvm/IR/CallingConv.h"
> #include "llvm/IR/Constant.h"
> @@ -172,8 +173,9 @@ bool DeadArgumentEliminationPass::Delete
> for (unsigned i = 0; PAL.getSlotIndex(i) <= NumArgs; ++i)
> AttributesVec.push_back(PAL.getSlotAttributes(i));
> if (PAL.hasAttributes(AttributeList::FunctionIndex))
> - AttributesVec.push_back(
> - AttributeList::get(Fn.getContext(), PAL.getFnAttributes()));
> + AttributesVec.push_back(AttributeList::get(Fn.getContext(),
> +
> AttributeList::FunctionIndex,
> +
> PAL.getFnAttributes()));
> PAL = AttributeList::get(Fn.getContext(), AttributesVec);
> }
>
> @@ -684,9 +686,13 @@ bool DeadArgumentEliminationPass::Remove
> bool HasLiveReturnedArg = false;
>
> // Set up to build a new list of parameter attributes.
> - SmallVector<AttributeList, 8> AttributesVec;
> + SmallVector<AttributeSetNode *, 8> AttributesVec;
> const AttributeList &PAL = F->getAttributes();
>
> + // Reserve an empty slot for the return value attributes, which we will
> + // compute last.
> + AttributesVec.push_back(nullptr);
> +
> // Remember which arguments are still alive.
> SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
> // Construct the new parameter list from non-dead arguments. Also
> construct
> @@ -699,16 +705,8 @@ bool DeadArgumentEliminationPass::Remove
> if (LiveValues.erase(Arg)) {
> Params.push_back(I->getType());
> ArgAlive[i] = true;
> -
> - // Get the original parameter attributes (skipping the first one,
> that is
> - // for the return value.
> - if (PAL.hasAttributes(i + 1)) {
> - AttrBuilder B(PAL, i + 1);
> - if (B.contains(Attribute::Returned))
> - HasLiveReturnedArg = true;
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), Params.size(), B));
> - }
> + AttributesVec.push_back(PAL.getParamAttributes(i + 1));
> + HasLiveReturnedArg |= PAL.hasAttribute(i + 1, Attribute::Returned);
> } else {
> ++NumArgumentsEliminated;
> DEBUG(dbgs() << "DeadArgumentEliminationPass - Removing argument "
> << i
> @@ -782,29 +780,25 @@ bool DeadArgumentEliminationPass::Remove
> assert(NRetTy && "No new return type found?");
>
> // The existing function return attributes.
> - AttributeList RAttrs = PAL.getRetAttributes();
> + AttrBuilder RAttrs(PAL.getRetAttributes());
>
> // Remove any incompatible attributes, but only if we removed all return
> // values. Otherwise, ensure that we don't have any conflicting
> attributes
> // here. Currently, this should not be possible, but special handling
> might be
> // required when new return value attributes are added.
> if (NRetTy->isVoidTy())
> - RAttrs = RAttrs.removeAttributes(NRetTy->getContext(),
> - AttributeList::ReturnIndex,
> - AttributeFuncs::
> typeIncompatible(NRetTy));
> + RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
> else
> - assert(!AttrBuilder(RAttrs, AttributeList::ReturnIndex)
> - .overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
> + assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
> "Return attributes no longer compatible?");
>
> - if (RAttrs.hasAttributes(AttributeList::ReturnIndex))
> - AttributesVec.push_back(AttributeList::get(NRetTy->getContext(),
> RAttrs));
> + AttributesVec[0] = AttributeSetNode::get(F->getContext(), RAttrs);
>
> - if (PAL.hasAttributes(AttributeList::FunctionIndex))
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), PAL.getFnAttributes()));
> + // Transfer the function attributes, if any.
> + AttributesVec.push_back(PAL.getFnAttributes());
>
> // Reconstruct the AttributesList based on the vector we constructed.
> + assert(AttributesVec.size() == Params.size() + 2);
> AttributeList NewPAL = AttributeList::get(F->getContext(),
> AttributesVec);
>
> // Create the new function type based on the recomputed parameters.
> @@ -835,15 +829,11 @@ bool DeadArgumentEliminationPass::Remove
> AttributesVec.clear();
> const AttributeList &CallPAL = CS.getAttributes();
>
> - // The call return attributes.
> - AttributeList RAttrs = CallPAL.getRetAttributes();
> -
> - // Adjust in case the function was changed to return void.
> - RAttrs = RAttrs.removeAttributes(
> - NRetTy->getContext(), AttributeList::ReturnIndex,
> - AttributeFuncs::typeIncompatible(NF->getReturnType()));
> - if (RAttrs.hasAttributes(AttributeList::ReturnIndex))
> - AttributesVec.push_back(AttributeList::get(NF->getContext(),
> RAttrs));
> + // Adjust the call return attributes in case the function was changed
> to
> + // return void.
> + AttrBuilder RAttrs(CallPAL.getRetAttributes());
> + RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
> + AttributesVec.push_back(AttributeSetNode::get(F->getContext(),
> RAttrs));
>
> // Declare these outside of the loops, so we can reuse them for the
> second
> // loop, which loops the varargs.
> @@ -855,33 +845,30 @@ bool DeadArgumentEliminationPass::Remove
> if (ArgAlive[i]) {
> Args.push_back(*I);
> // Get original parameter attributes, but skip return attributes.
> - if (CallPAL.hasAttributes(i + 1)) {
> - AttrBuilder B(CallPAL, i + 1);
> + AttributeSetNode *Attrs = CallPAL.getParamAttributes(i + 1);
> + if (NRetTy != RetTy && Attrs &&
> + Attrs->hasAttribute(Attribute::Returned)) {
> // 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 sites keep the return value alive just like 'returned'
> - // attributes on function declaration but it's less clearly a
> win
> - // and this is not an expected case anyway
> - if (NRetTy != RetTy && B.contains(Attribute::Returned))
> - B.removeAttribute(Attribute::Returned);
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), Args.size(), B));
> + // attributes on function declaration but it's less clearly a
> win and
> + // this is not an expected case anyway
> + AttributesVec.push_back(AttributeSetNode::get(
> + F->getContext(),
> + AttrBuilder(Attrs).removeAttribute(Attribute::Returned)));
> + } else {
> + // Otherwise, use the original attributes.
> + AttributesVec.push_back(Attrs);
> }
> }
>
> // Push any varargs arguments on the list. Don't forget their
> attributes.
> for (CallSite::arg_iterator E = CS.arg_end(); I != E; ++I, ++i) {
> Args.push_back(*I);
> - if (CallPAL.hasAttributes(i + 1)) {
> - AttrBuilder B(CallPAL, i + 1);
> - AttributesVec.push_back(
> - AttributeList::get(F->getContext(), Args.size(), B));
> - }
> + AttributesVec.push_back(CallPAL.getParamAttributes(i + 1));
> }
>
> - if (CallPAL.hasAttributes(AttributeList::FunctionIndex))
> - AttributesVec.push_back(
> - AttributeList::get(Call->getContext(),
> CallPAL.getFnAttributes()));
> + AttributesVec.push_back(CallPAL.getFnAttributes());
>
> // Reconstruct the AttributesList based on the vector we constructed.
> AttributeList NewCallPAL =
>
> Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> Transforms/IPO/MergeFunctions.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Mon Apr 10 18:31:05
> 2017
> @@ -439,8 +439,7 @@ void MergeFunctions::replaceDirectCaller
> Context, AttributeList::ReturnIndex,
> NewFuncAttrs.getRetAttributes());
>
> for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++) {
> - AttributeList Attrs = NewFuncAttrs.getParamAttributes(argIdx);
> - if (Attrs.getNumSlots())
> + if (AttributeSetNode *Attrs = NewFuncAttrs.
> getParamAttributes(argIdx))
> CallSiteAttrs = CallSiteAttrs.addAttributes(Context, argIdx,
> Attrs);
> }
>
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> Transforms/InstCombine/InstCombineCalls.cpp?rev=
> 299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Apr 10
> 18:31:05 2017
> @@ -23,6 +23,7 @@
> #include "llvm/Analysis/InstructionSimplify.h"
> #include "llvm/Analysis/MemoryBuiltins.h"
> #include "llvm/Analysis/ValueTracking.h"
> +#include "llvm/IR/AttributeSetNode.h"
> #include "llvm/IR/BasicBlock.h"
> #include "llvm/IR/CallSite.h"
> #include "llvm/IR/Constant.h"
> @@ -3992,7 +3993,7 @@ bool InstCombiner::transformConstExprCas
> if (!CastInst::isBitOrNoopPointerCastable(ActTy, ParamTy, DL))
> return false; // Cannot transform this parameter value.
>
> - if (AttrBuilder(CallerPAL.getParamAttributes(i + 1), i + 1).
> + if (AttrBuilder(CallerPAL.getParamAttributes(i + 1)).
> overlaps(AttributeFuncs::typeIncompatible(ParamTy)))
> return false; // Attribute not compatible with transformed value.
>
> @@ -4001,9 +4002,7 @@ bool InstCombiner::transformConstExprCas
>
> // If the parameter is passed as a byval argument, then we have to
> have a
> // sized type and the sized type has to have the same size as the old
> type.
> - if (ParamTy != ActTy &&
> - CallerPAL.getParamAttributes(i + 1).hasAttribute(i + 1,
> -
> Attribute::ByVal)) {
> + if (ParamTy != ActTy && CallerPAL.hasAttribute(i + 1,
> Attribute::ByVal)) {
> PointerType *ParamPTy = dyn_cast<PointerType>(ParamTy);
> if (!ParamPTy || !ParamPTy->getElementType()->isSized())
> return false;
> @@ -4084,7 +4083,7 @@ bool InstCombiner::transformConstExprCas
> }
>
> // Add any parameter attributes.
> - AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1), i + 1);
> + AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1));
> if (PAttrs.hasAttributes())
> attrVec.push_back(
> AttributeList::get(Caller->getContext(), i + 1, PAttrs));
> @@ -4112,7 +4111,7 @@ bool InstCombiner::transformConstExprCas
> }
>
> // Add any parameter attributes.
> - AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1), i + 1);
> + AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1));
> if (PAttrs.hasAttributes())
> attrVec.push_back(
> AttributeList::get(FT->getContext(), i + 1, PAttrs));
> @@ -4120,9 +4119,11 @@ bool InstCombiner::transformConstExprCas
> }
> }
>
> - AttributeList FnAttrs = CallerPAL.getFnAttributes();
> + AttributeSetNode *FnAttrs = CallerPAL.getFnAttributes();
> if (CallerPAL.hasAttributes(AttributeList::FunctionIndex))
> - attrVec.push_back(AttributeList::get(Callee->getContext(), FnAttrs));
> + attrVec.push_back(AttributeList::get(Callee->getContext(),
> + AttributeList::FunctionIndex,
> + AttrBuilder(FnAttrs)));
>
> if (NewRetTy->isVoidTy())
> Caller->setName(""); // Void type should not have a name.
> @@ -4200,7 +4201,7 @@ InstCombiner::transformCallThroughTrampo
> Value *Callee = CS.getCalledValue();
> PointerType *PTy = cast<PointerType>(Callee->getType());
> FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
> - const AttributeList &Attrs = CS.getAttributes();
> + AttributeList Attrs = CS.getAttributes();
>
> // If the call already has the 'nest' attribute somewhere then give up -
> // otherwise 'nest' would occur twice after splicing in the chain.
> @@ -4213,11 +4214,11 @@ InstCombiner::transformCallThroughTrampo
> Function *NestF =cast<Function>(Tramp->getArgOperand(1)->
> stripPointerCasts());
> FunctionType *NestFTy = cast<FunctionType>(NestF->getValueType());
>
> - const AttributeList &NestAttrs = NestF->getAttributes();
> + AttributeList NestAttrs = NestF->getAttributes();
> if (!NestAttrs.isEmpty()) {
> unsigned NestIdx = 1;
> Type *NestTy = nullptr;
> - AttributeList NestAttr;
> + AttributeSetNode *NestAttr;
>
> // Look for a parameter marked with the 'nest' attribute.
> for (FunctionType::param_iterator I = NestFTy->param_begin(),
> @@ -4232,18 +4233,15 @@ InstCombiner::transformCallThroughTrampo
> if (NestTy) {
> Instruction *Caller = CS.getInstruction();
> std::vector<Value*> NewArgs;
> + std::vector<AttributeSetNode *> NewAttrs;
> NewArgs.reserve(CS.arg_size() + 1);
> -
> - SmallVector<AttributeList, 8> NewAttrs;
> - NewAttrs.reserve(Attrs.getNumSlots() + 1);
> + NewAttrs.reserve(CS.arg_size() + 2);
>
> // Insert the nest argument into the call argument list, which may
> // mean appending it. Likewise for attributes.
>
> // Add any result attributes.
> - if (Attrs.hasAttributes(AttributeList::ReturnIndex))
> - NewAttrs.push_back(
> - AttributeList::get(Caller->getContext(),
> Attrs.getRetAttributes()));
> + NewAttrs.push_back(Attrs.getRetAttributes());
>
> {
> unsigned Idx = 1;
> @@ -4255,8 +4253,7 @@ InstCombiner::transformCallThroughTrampo
> if (NestVal->getType() != NestTy)
> NestVal = Builder->CreateBitCast(NestVal, NestTy, "nest");
> NewArgs.push_back(NestVal);
> - NewAttrs.push_back(
> - AttributeList::get(Caller->getContext(), NestAttr));
> + NewAttrs.push_back(NestAttr);
> }
>
> if (I == E)
> @@ -4264,12 +4261,7 @@ InstCombiner::transformCallThroughTrampo
>
> // Add the original argument and attributes.
> NewArgs.push_back(*I);
> - AttributeList Attr = Attrs.getParamAttributes(Idx);
> - if (Attr.hasAttributes(Idx)) {
> - AttrBuilder B(Attr, Idx);
> - NewAttrs.push_back(AttributeList::get(Caller->getContext(),
> - Idx + (Idx >= NestIdx),
> B));
> - }
> + NewAttrs.push_back(Attrs.getParamAttributes(Idx));
>
> ++Idx;
> ++I;
> @@ -4277,9 +4269,7 @@ InstCombiner::transformCallThroughTrampo
> }
>
> // Add any function attributes.
> - if (Attrs.hasAttributes(AttributeList::FunctionIndex))
> - NewAttrs.push_back(
> - AttributeList::get(FTy->getContext(),
> Attrs.getFnAttributes()));
> + NewAttrs.push_back(Attrs.getFnAttributes());
>
> // The trampoline may have been bitcast to a bogus type (FTy).
> // Handle this by synthesizing a new function type, equal to FTy
> @@ -4319,8 +4309,7 @@ InstCombiner::transformCallThroughTrampo
> NestF->getType() == PointerType::getUnqual(NewFTy) ?
> NestF : ConstantExpr::getBitCast(NestF,
> PointerType::getUnqual(NewFTy));
> - const AttributeList &NewPAL =
> - AttributeList::get(FTy->getContext(), NewAttrs);
> + AttributeList NewPAL = AttributeList::get(FTy->getContext(),
> NewAttrs);
>
> SmallVector<OperandBundleDef, 1> OpBundles;
> CS.getOperandBundlesAsDefs(OpBundles);
>
> Modified: llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/
> RewriteStatepointsForGC.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
> (original)
> +++ llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp Mon Apr
> 10 18:31:05 2017
> @@ -1392,7 +1392,6 @@ makeStatepointExplicitImpl(const CallSit
>
> // Create the statepoint given all the arguments
> Instruction *Token = nullptr;
> - AttributeList ReturnAttrs;
> if (CS.isCall()) {
> CallInst *ToReplace = cast<CallInst>(CS.getInstruction());
> CallInst *Call = Builder.CreateGCStatepointCall(
> @@ -1407,8 +1406,9 @@ makeStatepointExplicitImpl(const CallSit
> AttributeList NewAttrs = legalizeCallAttributes(
> ToReplace->getAttributes());
> // In case if we can handle this set of attributes - set up function
> attrs
> // directly on statepoint and return attrs later for gc_result
> intrinsic.
> - Call->setAttributes(NewAttrs.getFnAttributes());
> - ReturnAttrs = NewAttrs.getRetAttributes();
> + Call->setAttributes(AttributeList::get(Call->getContext(),
> + AttributeList::FunctionIndex,
> + NewAttrs.getFnAttributes()));
>
> Token = Call;
>
> @@ -1435,8 +1435,9 @@ makeStatepointExplicitImpl(const CallSit
> AttributeList NewAttrs = legalizeCallAttributes(
> ToReplace->getAttributes());
> // In case if we can handle this set of attributes - set up function
> attrs
> // directly on statepoint and return attrs later for gc_result
> intrinsic.
> - Invoke->setAttributes(NewAttrs.getFnAttributes());
> - ReturnAttrs = NewAttrs.getRetAttributes();
> + Invoke->setAttributes(AttributeList::get(Invoke->getContext(),
> + AttributeList::FunctionIndex,
> + NewAttrs.getFnAttributes()));
>
> Token = Invoke;
>
> @@ -1482,7 +1483,9 @@ makeStatepointExplicitImpl(const CallSit
> StringRef Name =
> CS.getInstruction()->hasName() ? CS.getInstruction()->getName()
> : "";
> CallInst *GCResult = Builder.CreateGCResult(Token, CS.getType(),
> Name);
> - GCResult->setAttributes(CS.getAttributes().getRetAttributes());
> + GCResult->setAttributes(
> + AttributeList::get(GCResult->getContext(),
> AttributeList::ReturnIndex,
> + CS.getAttributes().getRetAttributes()));
>
> // We cannot RAUW or delete CS.getInstruction() because it could be
> in the
> // live set of some other safepoint, in which case that safepoint's
>
> Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/
> CloneFunction.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Apr 10 18:31:05
> 2017
> @@ -103,21 +103,25 @@ void llvm::CloneFunctionInto(Function *N
> ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
> TypeMapper, Materializer));
>
> + SmallVector<std::pair<unsigned, AttributeSetNode*>, 4> AttrVec;
> AttributeList OldAttrs = OldFunc->getAttributes();
> +
> + // Copy the return attributes.
> + if (auto *RetAttrs = OldAttrs.getRetAttributes())
> + AttrVec.emplace_back(AttributeList::ReturnIndex, RetAttrs);
> +
> // Clone any argument attributes that are present in the VMap.
> for (const Argument &OldArg : OldFunc->args())
> if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
> - AttributeList attrs = OldAttrs.getParamAttributes(OldArg.getArgNo()
> + 1);
> - if (attrs.getNumSlots() > 0)
> - NewArg->addAttr(attrs);
> + if (auto *ParmAttrs = OldAttrs.getParamAttributes(OldArg.getArgNo()
> + 1))
> + AttrVec.emplace_back(NewArg->getArgNo() + 1, ParmAttrs);
> }
>
> - NewFunc->setAttributes(
> - NewFunc->getAttributes()
> - .addAttributes(NewFunc->getContext(),
> AttributeList::ReturnIndex,
> - OldAttrs.getRetAttributes())
> - .addAttributes(NewFunc->getContext(),
> AttributeList::FunctionIndex,
> - OldAttrs.getFnAttributes()));
> + // Copy any function attributes.
> + if (auto *FnAttrs = OldAttrs.getFnAttributes())
> + AttrVec.emplace_back(AttributeList::FunctionIndex, FnAttrs);
> +
> + NewFunc->setAttributes(AttributeList::get(NewFunc->getContext(),
> AttrVec));
>
> SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
> OldFunc->getAllMetadata(MDs);
>
> Modified: llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/
> CodeExtractor.cpp?rev=299899&r1=299898&r2=299899&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp Mon Apr 10 18:31:05
> 2017
> @@ -362,8 +362,7 @@ Function *CodeExtractor::constructFuncti
> // "target-features" attribute allowing it to be lowered.
> // FIXME: This should be changed to check to see if a specific
> // attribute can not be inherited.
> - AttributeList OldFnAttrs = oldFunction->getAttributes().
> getFnAttributes();
> - AttrBuilder AB(OldFnAttrs, AttributeList::FunctionIndex);
> + AttrBuilder AB(oldFunction->getAttributes().getFnAttributes());
> for (const auto &Attr : AB.td_attrs())
> newFunction->addFnAttr(Attr.first, Attr.second);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170411/b2216593/attachment-0001.html>
More information about the llvm-commits
mailing list