[llvm] r299878 - Revert "[IR] Make AttributeSetNode public, avoid temporary AttributeList copies"
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 10 13:34:20 PDT 2017
Author: rnk
Date: Mon Apr 10 15:34:19 2017
New Revision: 299878
URL: http://llvm.org/viewvc/llvm-project?rev=299878&view=rev
Log:
Revert "[IR] Make AttributeSetNode public, avoid temporary AttributeList copies"
This reverts r299875. A Linux bot came back with a test failure:
http://bb.pgr.jp/builders/test-clang-i686-linux-RA/builds/741/steps/test_clang/logs/Clang%20%3A%3A%20CodeGen__2006-05-19-SingleEltReturn.c
Added:
llvm/trunk/lib/IR/AttributeSetNode.h
Removed:
llvm/trunk/include/llvm/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
Removed: llvm/trunk/include/llvm/IR/AttributeSetNode.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/AttributeSetNode.h?rev=299877&view=auto
==============================================================================
--- llvm/trunk/include/llvm/IR/AttributeSetNode.h (original)
+++ llvm/trunk/include/llvm/IR/AttributeSetNode.h (removed)
@@ -1,109 +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)
- : 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Attributes.h (original)
+++ llvm/trunk/include/llvm/IR/Attributes.h Mon Apr 10 15:34:19 2017
@@ -221,26 +221,19 @@ private:
/// the empty attributes list.
AttributeListImpl *pImpl = nullptr;
-public:
+ /// \brief The attributes for the specified index are returned.
+ AttributeSetNode *getAttributes(unsigned Index) const;
+
/// \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:
@@ -279,12 +272,6 @@ 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.
@@ -309,11 +296,6 @@ 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,
@@ -339,16 +321,13 @@ public:
LLVMContext &getContext() const;
/// \brief The attributes for the specified index are returned.
- AttributeSetNode *getAttributes(unsigned Index) const;
-
- /// \brief The attributes for the specified index are returned.
- AttributeSetNode *getParamAttributes(unsigned Index) const;
+ AttributeList getParamAttributes(unsigned Index) const;
/// \brief The attributes for the ret value are returned.
- AttributeSetNode *getRetAttributes() const;
+ AttributeList getRetAttributes() const;
/// \brief The function attributes are returned.
- AttributeSetNode *getFnAttributes() const;
+ AttributeList getFnAttributes() const;
/// \brief Return true if the attribute exists at the given index.
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
@@ -483,7 +462,6 @@ public:
addAttribute(A);
}
AttrBuilder(AttributeList AS, unsigned Idx);
- AttrBuilder(AttributeSetNode *AS);
void clear();
@@ -500,7 +478,7 @@ public:
AttrBuilder &removeAttribute(Attribute::AttrKind Val);
/// \brief Remove the attributes from the builder.
- AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex);
+ AttrBuilder &removeAttributes(AttributeList A, uint64_t Index);
/// \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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Apr 10 15:34:19 2017
@@ -19,7 +19,6 @@
#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"
@@ -132,8 +131,9 @@ bool LLParser::ValidateEndOfModule() {
if (Function *Fn = dyn_cast<Function>(V)) {
AttributeList AS = Fn->getAttributes();
- AttrBuilder FnAttrs(AS.getFnAttributes());
- AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
+ AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex);
+ AS = AS.removeAttributes(Context, AttributeList::FunctionIndex,
+ AS.getFnAttributes());
FnAttrs.merge(B);
@@ -150,8 +150,9 @@ bool LLParser::ValidateEndOfModule() {
Fn->setAttributes(AS);
} else if (CallInst *CI = dyn_cast<CallInst>(V)) {
AttributeList AS = CI->getAttributes();
- AttrBuilder FnAttrs(AS.getFnAttributes());
- AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
+ AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex);
+ AS = AS.removeAttributes(Context, AttributeList::FunctionIndex,
+ AS.getFnAttributes());
FnAttrs.merge(B);
AS = AS.addAttributes(
Context, AttributeList::FunctionIndex,
@@ -159,8 +160,9 @@ bool LLParser::ValidateEndOfModule() {
CI->setAttributes(AS);
} else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) {
AttributeList AS = II->getAttributes();
- AttrBuilder FnAttrs(AS.getFnAttributes());
- AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);
+ AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeList::FunctionIndex);
+ AS = AS.removeAttributes(Context, AttributeList::FunctionIndex,
+ AS.getFnAttributes());
FnAttrs.merge(B);
AS = AS.addAttributes(
Context, AttributeList::FunctionIndex,
@@ -2093,6 +2095,7 @@ 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() &&
@@ -2127,7 +2130,7 @@ bool LLParser::ParseParameterList(SmallV
return true;
}
ArgList.push_back(ParamInfo(
- ArgLoc, V, AttributeSetNode::get(V->getContext(), ArgAttrs)));
+ ArgLoc, V, AttributeList::get(V->getContext(), AttrIndex++, ArgAttrs)));
}
if (IsMustTailCall && InVarArgsFunc)
@@ -2232,8 +2235,9 @@ bool LLParser::ParseArgumentList(SmallVe
if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
- ArgList.emplace_back(TypeLoc, ArgTy,
- AttributeSetNode::get(ArgTy->getContext(), Attrs),
+ unsigned AttrIndex = 1;
+ ArgList.emplace_back(TypeLoc, ArgTy, AttributeList::get(ArgTy->getContext(),
+ AttrIndex++, Attrs),
std::move(Name));
while (EatIfPresent(lltok::comma)) {
@@ -2260,9 +2264,10 @@ bool LLParser::ParseArgumentList(SmallVe
if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
- ArgList.emplace_back(TypeLoc, ArgTy,
- AttributeSetNode::get(ArgTy->getContext(), Attrs),
- std::move(Name));
+ ArgList.emplace_back(
+ TypeLoc, ArgTy,
+ AttributeList::get(ArgTy->getContext(), AttrIndex++, Attrs),
+ std::move(Name));
}
}
@@ -2286,7 +2291,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)
+ if (ArgList[i].Attrs.hasAttributes(i + 1))
return Error(ArgList[i].Loc,
"argument attributes invalid in function type");
}
@@ -4735,16 +4740,23 @@ 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<AttributeSetNode *, 8> Attrs;
+ SmallVector<AttributeList, 8> Attrs;
- Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
+ if (RetAttrs.hasAttributes())
+ Attrs.push_back(AttributeList::get(RetType->getContext(),
+ AttributeList::ReturnIndex, RetAttrs));
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
ParamTypeList.push_back(ArgList[i].Ty);
- Attrs.push_back(ArgList[i].Attrs);
+ 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(AttributeSetNode::get(Context, FuncAttrs));
+ if (FuncAttrs.hasAttributes())
+ Attrs.push_back(AttributeList::get(
+ RetType->getContext(), AttributeList::FunctionIndex, FuncAttrs));
AttributeList PAL = AttributeList::get(Context, Attrs);
@@ -5356,8 +5368,10 @@ bool LLParser::ParseInvoke(Instruction *
return true;
// Set up the Attribute for the function.
- SmallVector<AttributeSetNode *, 8> Attrs;
- Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
+ SmallVector<AttributeList, 8> Attrs;
+ if (RetAttrs.hasAttributes())
+ Attrs.push_back(AttributeList::get(RetType->getContext(),
+ AttributeList::ReturnIndex, RetAttrs));
SmallVector<Value*, 8> Args;
@@ -5377,16 +5391,22 @@ bool LLParser::ParseInvoke(Instruction *
return Error(ArgList[i].Loc, "argument is not of expected type '" +
getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
- Attrs.push_back(ArgList[i].Attrs);
+ if (ArgList[i].Attrs.hasAttributes(i + 1)) {
+ AttrBuilder B(ArgList[i].Attrs, i + 1);
+ Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B));
+ }
}
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs.hasAlignmentAttr())
- return Error(CallLoc, "invoke instructions may not have an alignment");
+ if (FnAttrs.hasAttributes()) {
+ if (FnAttrs.hasAlignmentAttr())
+ return Error(CallLoc, "invoke instructions may not have an alignment");
- Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
+ Attrs.push_back(AttributeList::get(RetType->getContext(),
+ AttributeList::FunctionIndex, FnAttrs));
+ }
// Finish off the Attribute and check them
AttributeList PAL = AttributeList::get(Context, Attrs);
@@ -5950,8 +5970,10 @@ bool LLParser::ParseCall(Instruction *&I
return true;
// Set up the Attribute for the function.
- SmallVector<AttributeSetNode *, 8> Attrs;
- Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
+ SmallVector<AttributeList, 8> Attrs;
+ if (RetAttrs.hasAttributes())
+ Attrs.push_back(AttributeList::get(RetType->getContext(),
+ AttributeList::ReturnIndex, RetAttrs));
SmallVector<Value*, 8> Args;
@@ -5971,16 +5993,22 @@ bool LLParser::ParseCall(Instruction *&I
return Error(ArgList[i].Loc, "argument is not of expected type '" +
getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
- Attrs.push_back(ArgList[i].Attrs);
+ if (ArgList[i].Attrs.hasAttributes(i + 1)) {
+ AttrBuilder B(ArgList[i].Attrs, i + 1);
+ Attrs.push_back(AttributeList::get(RetType->getContext(), i + 1, B));
+ }
}
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs.hasAlignmentAttr())
- return Error(CallLoc, "call instructions may not have an alignment");
+ if (FnAttrs.hasAttributes()) {
+ if (FnAttrs.hasAlignmentAttr())
+ return Error(CallLoc, "call instructions may not have an alignment");
- Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
+ Attrs.push_back(AttributeList::get(RetType->getContext(),
+ AttributeList::FunctionIndex, 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Mon Apr 10 15:34:19 2017
@@ -395,8 +395,8 @@ namespace llvm {
struct ParamInfo {
LocTy Loc;
Value *V;
- AttributeSetNode *Attrs;
- ParamInfo(LocTy loc, Value *v, AttributeSetNode *attrs)
+ AttributeList Attrs;
+ ParamInfo(LocTy loc, Value *v, AttributeList attrs)
: Loc(loc), V(v), Attrs(attrs) {}
};
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
@@ -448,9 +448,9 @@ namespace llvm {
struct ArgInfo {
LocTy Loc;
Type *Ty;
- AttributeSetNode *Attrs;
+ AttributeList Attrs;
std::string Name;
- ArgInfo(LocTy L, Type *ty, AttributeSetNode *Attr, const std::string &N)
+ ArgInfo(LocTy L, Type *ty, AttributeList 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Mon Apr 10 15:34:19 2017
@@ -21,8 +21,6 @@
#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"
@@ -606,7 +604,7 @@ private:
unsigned mdnNext;
/// asMap - The slot map for attribute sets.
- DenseMap<AttributeSetNode *, unsigned> asMap;
+ DenseMap<AttributeList, unsigned> asMap;
unsigned asNext;
public:
/// Construct from a module.
@@ -629,7 +627,7 @@ public:
int getLocalSlot(const Value *V);
int getGlobalSlot(const GlobalValue *V);
int getMetadataSlot(const MDNode *N);
- int getAttributeGroupSlot(AttributeSetNode *AS);
+ int getAttributeGroupSlot(AttributeList 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.
@@ -652,8 +650,8 @@ public:
unsigned mdn_size() const { return mdnMap.size(); }
bool mdn_empty() const { return mdnMap.empty(); }
- /// AttributeSetNode map iterators.
- typedef DenseMap<AttributeSetNode *, unsigned>::iterator as_iterator;
+ /// AttributeList map iterators.
+ typedef DenseMap<AttributeList, 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(); }
@@ -673,8 +671,8 @@ private:
/// CreateFunctionSlot - Insert the specified Value* into the slot table.
void CreateFunctionSlot(const Value *V);
- /// \brief Insert the specified AttributeSetNode into the slot table.
- void CreateAttributeSetSlot(AttributeSetNode *AS);
+ /// \brief Insert the specified AttributeList into the slot table.
+ void CreateAttributeSetSlot(AttributeList AS);
/// Add all of the module level global variables (and their initializers)
/// and function declarations, but not the contents of those functions.
@@ -833,8 +831,8 @@ void SlotTracker::processModule() {
// Add all the function attributes to the table.
// FIXME: Add attributes of other objects?
- AttributeSetNode *FnAttrs = F.getAttributes().getFnAttributes();
- if (FnAttrs)
+ AttributeList FnAttrs = F.getAttributes().getFnAttributes();
+ if (FnAttrs.hasAttributes(AttributeList::FunctionIndex))
CreateAttributeSetSlot(FnAttrs);
}
@@ -871,13 +869,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.
- AttributeSetNode *Attrs = CI->getAttributes().getFnAttributes();
- if (Attrs)
+ AttributeList Attrs = CI->getAttributes().getFnAttributes();
+ if (Attrs.hasAttributes(AttributeList::FunctionIndex))
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)
+ AttributeList Attrs = II->getAttributes().getFnAttributes();
+ if (Attrs.hasAttributes(AttributeList::FunctionIndex))
CreateAttributeSetSlot(Attrs);
}
}
@@ -963,11 +961,11 @@ int SlotTracker::getLocalSlot(const Valu
return FI == fMap.end() ? -1 : (int)FI->second;
}
-int SlotTracker::getAttributeGroupSlot(AttributeSetNode *AS) {
+int SlotTracker::getAttributeGroupSlot(AttributeList AS) {
// Check for uninitialized state and do lazy initialization.
initialize();
- // Find the AttributeSetNode in the module map.
+ // Find the AttributeList in the module map.
as_iterator AI = asMap.find(AS);
return AI == asMap.end() ? -1 : (int)AI->second;
}
@@ -1017,8 +1015,9 @@ void SlotTracker::CreateMetadataSlot(con
CreateMetadataSlot(Op);
}
-void SlotTracker::CreateAttributeSetSlot(AttributeSetNode *AS) {
- assert(AS && "Doesn't need a slot!");
+void SlotTracker::CreateAttributeSetSlot(AttributeList AS) {
+ assert(AS.hasAttributes(AttributeList::FunctionIndex) &&
+ "Doesn't need a slot!");
as_iterator I = asMap.find(AS);
if (I != asMap.end())
@@ -2607,10 +2606,17 @@ void AssemblyWriter::printFunction(const
const AttributeList &Attrs = F->getAttributes();
if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
- AttributeSetNode *AS = Attrs.getFnAttributes();
+ AttributeList AS = Attrs.getFnAttributes();
std::string AttrStr;
- for (const Attribute &Attr : *AS) {
+ 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;
if (!Attr.isStringAttribute()) {
if (!AttrStr.empty()) AttrStr += ' ';
AttrStr += Attr.getAsString();
@@ -3244,7 +3250,7 @@ void AssemblyWriter::printMDNodeBody(con
}
void AssemblyWriter::writeAllAttributeGroups() {
- std::vector<std::pair<AttributeSetNode *, unsigned>> asVec;
+ std::vector<std::pair<AttributeList, unsigned>> asVec;
asVec.resize(Machine.as_size());
for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end();
@@ -3253,7 +3259,7 @@ void AssemblyWriter::writeAllAttributeGr
for (const auto &I : asVec)
Out << "attributes #" << I.second << " = { "
- << I.first->getAsString(true) << " }\n";
+ << I.first.getAsString(AttributeList::FunctionIndex, 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AttributeImpl.h (original)
+++ llvm/trunk/lib/IR/AttributeImpl.h Mon Apr 10 15:34:19 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>
Added: llvm/trunk/lib/IR/AttributeSetNode.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AttributeSetNode.h?rev=299878&view=auto
==============================================================================
--- llvm/trunk/lib/IR/AttributeSetNode.h (added)
+++ llvm/trunk/lib/IR/AttributeSetNode.h Mon Apr 10 15:34:19 2017
@@ -0,0 +1,107 @@
+//===-- 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Attributes.cpp (original)
+++ llvm/trunk/lib/IR/Attributes.cpp Mon Apr 10 15:34:19 2017
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "AttributeImpl.h"
+#include "AttributeSetNode.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
@@ -23,7 +24,6 @@
#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,48 +527,6 @@ 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))
@@ -654,19 +612,6 @@ 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);
@@ -735,32 +680,50 @@ 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();
- AttributeSetNode *ASN = AttributeSetNode::get(C, B);
- std::pair<unsigned, AttributeSetNode *> Arr[1] = {{Index, ASN}};
- return getImpl(C, Arr);
+
+ // 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);
}
AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
@@ -828,31 +791,31 @@ AttributeList AttributeList::addAttribut
AttributeList AttributeList::addAttribute(LLVMContext &C,
ArrayRef<unsigned> Indices,
Attribute A) const {
- assert(std::is_sorted(Indices.begin(), Indices.end()));
-
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)));
+ auto IdxI = Indices.begin(), IdxE = Indices.end();
+ SmallVector<AttributeList, 4> AttrSet;
+
+ 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));
++I;
+ ++IdxI;
}
- B.addAttribute(A);
- AttrVec.emplace_back(Index, AttributeSetNode::get(C, B));
}
- // Add remaining attributes.
- for (; I < E; ++I)
- AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
+ while (I != E)
+ AttrSet.emplace_back(getSlotAttributes(I++));
- return get(C, AttrVec);
+ while (IdxI != IdxE)
+ AttrSet.emplace_back(AttributeList::get(C, std::make_pair(*IdxI++, A)));
+
+ return get(C, AttrSet);
}
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
@@ -860,56 +823,49 @@ 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 = AS->getAlignment();
+ unsigned NewAlign = Attrs.getParamAlignment(Index);
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
"Attempt to change alignment!");
#endif
- SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
+ // Add the attribute slots before the one we're trying to add.
+ SmallVector<AttributeList, 4> AttrSet;
uint64_t NumAttrs = pImpl->getNumSlots();
- unsigned I;
-
- // Add all the attribute slots before the one we need to merge.
- for (I = 0; I < NumAttrs; ++I) {
- if (getSlotIndex(I) >= Index)
+ 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;
- AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
+ }
+ LastIndex = I + 1;
+ AttrSet.push_back(getSlotAttributes(I));
}
- 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);
- }
+ // Now add the attribute into the correct slot. There may already be an
+ // AttributeList there.
+ AttrBuilder B(AS, Index);
- // Add the remaining entries.
- for (; I < NumAttrs; ++I)
- AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
+ 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);
+ break;
+ }
- return get(C, AttrSet);
-}
+ AttrSet.push_back(AttributeList::get(C, Index, B));
-AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
- const AttrBuilder &B) const {
- return get(C, Index, AttributeSetNode::get(C, B));
+ // Add the remaining attribute slots.
+ for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
+ AttrSet.push_back(getSlotAttributes(I));
+
+ return get(C, AttrSet);
}
AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
@@ -1005,20 +961,6 @@ 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 {
@@ -1050,16 +992,32 @@ AttributeList::addAllocSizeAttr(LLVMCont
LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
-AttributeSetNode *AttributeList::getParamAttributes(unsigned Index) const {
- return getAttributes(Index);
-}
-
-AttributeSetNode *AttributeList::getRetAttributes() const {
- return getAttributes(ReturnIndex);
-}
-
-AttributeSetNode *AttributeList::getFnAttributes() const {
- return getAttributes(FunctionIndex);
+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();
}
bool AttributeList::hasAttribute(unsigned Index,
@@ -1223,13 +1181,6 @@ 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Core.cpp (original)
+++ llvm/trunk/lib/IR/Core.cpp Mon Apr 10 15:34:19 2017
@@ -16,7 +16,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/IR/Attributes.h"
-#include "llvm/IR/AttributeSetNode.h"
+#include "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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Mon Apr 10 15:34:19 2017
@@ -42,7 +42,6 @@
#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"
@@ -103,11 +102,13 @@ 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<AttributeSetNode *, 8> AttributesVec;
+ SmallVector<AttributeList, 8> AttributesVec;
const AttributeList &PAL = F->getAttributes();
// Add any return attributes.
- AttributesVec.push_back(PAL.getRetAttributes());
+ if (PAL.hasAttributes(AttributeList::ReturnIndex))
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), PAL.getRetAttributes()));
// First, determine the new argument list
unsigned ArgIndex = 1;
@@ -118,12 +119,16 @@ 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());
- AttributesVec.push_back(PAL.getParamAttributes(ArgIndex));
+ AttributeList attrs = PAL.getParamAttributes(ArgIndex);
+ if (attrs.hasAttributes(ArgIndex)) {
+ AttrBuilder B(attrs, ArgIndex);
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), Params.size(), B));
+ }
} else if (I->use_empty()) {
// Dead argument (which are always marked as promotable)
++NumArgumentsDead;
@@ -168,7 +173,6 @@ doPromotion(Function *F, SmallPtrSetImpl
Params.push_back(GetElementPtrInst::getIndexedType(
cast<PointerType>(I->getType()->getScalarType())->getElementType(),
ArgIndex.second));
- AttributesVec.push_back(nullptr);
assert(Params.back());
}
@@ -180,7 +184,9 @@ doPromotion(Function *F, SmallPtrSetImpl
}
// Add any function attributes.
- AttributesVec.push_back(PAL.getFnAttributes());
+ if (PAL.hasAttributes(AttributeList::FunctionIndex))
+ AttributesVec.push_back(
+ AttributeList::get(FTy->getContext(), PAL.getFnAttributes()));
Type *RetTy = FTy->getReturnType();
@@ -217,7 +223,9 @@ doPromotion(Function *F, SmallPtrSetImpl
const AttributeList &CallPAL = CS.getAttributes();
// Add any return attributes.
- AttributesVec.push_back(CallPAL.getRetAttributes());
+ if (CallPAL.hasAttributes(AttributeList::ReturnIndex))
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), CallPAL.getRetAttributes()));
// Loop over the operands, inserting GEP and loads in the caller as
// appropriate.
@@ -227,7 +235,12 @@ doPromotion(Function *F, SmallPtrSetImpl
++I, ++AI, ++ArgIndex)
if (!ArgsToPromote.count(&*I) && !ByValArgsToTransform.count(&*I)) {
Args.push_back(*AI); // Unmodified argument
- AttributesVec.push_back(CallPAL.getAttributes(ArgIndex));
+
+ if (CallPAL.hasAttributes(ArgIndex)) {
+ AttrBuilder B(CallPAL, ArgIndex);
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), Args.size(), B));
+ }
} else if (ByValArgsToTransform.count(&*I)) {
// Emit a GEP and load for each element of the struct.
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
@@ -240,7 +253,6 @@ 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.
@@ -283,18 +295,23 @@ 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);
- AttributesVec.push_back(CallPAL.getAttributes(ArgIndex));
+ if (CallPAL.hasAttributes(ArgIndex)) {
+ AttrBuilder B(CallPAL, ArgIndex);
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), Args.size(), B));
+ }
}
// Add any function attributes.
- AttributesVec.push_back(CallPAL.getFnAttributes());
+ if (CallPAL.hasAttributes(AttributeList::FunctionIndex))
+ AttributesVec.push_back(
+ AttributeList::get(Call->getContext(), 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Mon Apr 10 15:34:19 2017
@@ -21,7 +21,6 @@
#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"
@@ -173,9 +172,8 @@ 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(),
- AttributeList::FunctionIndex,
- PAL.getFnAttributes()));
+ AttributesVec.push_back(
+ AttributeList::get(Fn.getContext(), PAL.getFnAttributes()));
PAL = AttributeList::get(Fn.getContext(), AttributesVec);
}
@@ -686,13 +684,9 @@ bool DeadArgumentEliminationPass::Remove
bool HasLiveReturnedArg = false;
// Set up to build a new list of parameter attributes.
- SmallVector<AttributeSetNode *, 8> AttributesVec;
+ SmallVector<AttributeList, 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
@@ -705,8 +699,16 @@ bool DeadArgumentEliminationPass::Remove
if (LiveValues.erase(Arg)) {
Params.push_back(I->getType());
ArgAlive[i] = true;
- AttributesVec.push_back(PAL.getParamAttributes(i + 1));
- HasLiveReturnedArg |= PAL.hasAttribute(i + 1, Attribute::Returned);
+
+ // 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));
+ }
} else {
++NumArgumentsEliminated;
DEBUG(dbgs() << "DeadArgumentEliminationPass - Removing argument " << i
@@ -780,25 +782,29 @@ bool DeadArgumentEliminationPass::Remove
assert(NRetTy && "No new return type found?");
// The existing function return attributes.
- AttrBuilder RAttrs(PAL.getRetAttributes());
+ AttributeList 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.remove(AttributeFuncs::typeIncompatible(NRetTy));
+ RAttrs = RAttrs.removeAttributes(NRetTy->getContext(),
+ AttributeList::ReturnIndex,
+ AttributeFuncs::typeIncompatible(NRetTy));
else
- assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
+ assert(!AttrBuilder(RAttrs, AttributeList::ReturnIndex)
+ .overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
"Return attributes no longer compatible?");
- AttributesVec[0] = AttributeSetNode::get(F->getContext(), RAttrs);
+ if (RAttrs.hasAttributes(AttributeList::ReturnIndex))
+ AttributesVec.push_back(AttributeList::get(NRetTy->getContext(), RAttrs));
- // Transfer the function attributes, if any.
- AttributesVec.push_back(PAL.getFnAttributes());
+ if (PAL.hasAttributes(AttributeList::FunctionIndex))
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), 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.
@@ -829,11 +835,15 @@ bool DeadArgumentEliminationPass::Remove
AttributesVec.clear();
const AttributeList &CallPAL = CS.getAttributes();
- // 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));
+ // 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));
// Declare these outside of the loops, so we can reuse them for the second
// loop, which loops the varargs.
@@ -845,30 +855,33 @@ bool DeadArgumentEliminationPass::Remove
if (ArgAlive[i]) {
Args.push_back(*I);
// Get original parameter attributes, but skip return attributes.
- AttributeSetNode *Attrs = CallPAL.getParamAttributes(i + 1);
- if (NRetTy != RetTy && Attrs &&
- Attrs->hasAttribute(Attribute::Returned)) {
+ if (CallPAL.hasAttributes(i + 1)) {
+ AttrBuilder B(CallPAL, i + 1);
// 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
- AttributesVec.push_back(AttributeSetNode::get(
- F->getContext(),
- AttrBuilder(Attrs).removeAttribute(Attribute::Returned)));
- } else {
- // Otherwise, use the original attributes.
- AttributesVec.push_back(Attrs);
+ // 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));
}
}
// 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);
- AttributesVec.push_back(CallPAL.getParamAttributes(i + 1));
+ if (CallPAL.hasAttributes(i + 1)) {
+ AttrBuilder B(CallPAL, i + 1);
+ AttributesVec.push_back(
+ AttributeList::get(F->getContext(), Args.size(), B));
+ }
}
- AttributesVec.push_back(CallPAL.getFnAttributes());
+ if (CallPAL.hasAttributes(AttributeList::FunctionIndex))
+ AttributesVec.push_back(
+ AttributeList::get(Call->getContext(), 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Mon Apr 10 15:34:19 2017
@@ -439,7 +439,8 @@ void MergeFunctions::replaceDirectCaller
Context, AttributeList::ReturnIndex, NewFuncAttrs.getRetAttributes());
for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++) {
- if (AttributeSetNode *Attrs = NewFuncAttrs.getParamAttributes(argIdx))
+ AttributeList Attrs = NewFuncAttrs.getParamAttributes(argIdx);
+ if (Attrs.getNumSlots())
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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Apr 10 15:34:19 2017
@@ -23,7 +23,6 @@
#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"
@@ -3993,7 +3992,7 @@ bool InstCombiner::transformConstExprCas
if (!CastInst::isBitOrNoopPointerCastable(ActTy, ParamTy, DL))
return false; // Cannot transform this parameter value.
- if (AttrBuilder(CallerPAL.getParamAttributes(i + 1)).
+ if (AttrBuilder(CallerPAL.getParamAttributes(i + 1), i + 1).
overlaps(AttributeFuncs::typeIncompatible(ParamTy)))
return false; // Attribute not compatible with transformed value.
@@ -4002,7 +4001,9 @@ 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.hasAttribute(i + 1, Attribute::ByVal)) {
+ if (ParamTy != ActTy &&
+ CallerPAL.getParamAttributes(i + 1).hasAttribute(i + 1,
+ Attribute::ByVal)) {
PointerType *ParamPTy = dyn_cast<PointerType>(ParamTy);
if (!ParamPTy || !ParamPTy->getElementType()->isSized())
return false;
@@ -4083,7 +4084,7 @@ bool InstCombiner::transformConstExprCas
}
// Add any parameter attributes.
- AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1));
+ AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1), i + 1);
if (PAttrs.hasAttributes())
attrVec.push_back(
AttributeList::get(Caller->getContext(), i + 1, PAttrs));
@@ -4111,7 +4112,7 @@ bool InstCombiner::transformConstExprCas
}
// Add any parameter attributes.
- AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1));
+ AttrBuilder PAttrs(CallerPAL.getParamAttributes(i + 1), i + 1);
if (PAttrs.hasAttributes())
attrVec.push_back(
AttributeList::get(FT->getContext(), i + 1, PAttrs));
@@ -4119,11 +4120,9 @@ bool InstCombiner::transformConstExprCas
}
}
- AttributeSetNode *FnAttrs = CallerPAL.getFnAttributes();
+ AttributeList FnAttrs = CallerPAL.getFnAttributes();
if (CallerPAL.hasAttributes(AttributeList::FunctionIndex))
- attrVec.push_back(AttributeList::get(Callee->getContext(),
- AttributeList::FunctionIndex,
- AttrBuilder(FnAttrs)));
+ attrVec.push_back(AttributeList::get(Callee->getContext(), FnAttrs));
if (NewRetTy->isVoidTy())
Caller->setName(""); // Void type should not have a name.
@@ -4201,7 +4200,7 @@ InstCombiner::transformCallThroughTrampo
Value *Callee = CS.getCalledValue();
PointerType *PTy = cast<PointerType>(Callee->getType());
FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
- AttributeList Attrs = CS.getAttributes();
+ const 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.
@@ -4214,11 +4213,11 @@ InstCombiner::transformCallThroughTrampo
Function *NestF =cast<Function>(Tramp->getArgOperand(1)->stripPointerCasts());
FunctionType *NestFTy = cast<FunctionType>(NestF->getValueType());
- AttributeList NestAttrs = NestF->getAttributes();
+ const AttributeList &NestAttrs = NestF->getAttributes();
if (!NestAttrs.isEmpty()) {
unsigned NestIdx = 1;
Type *NestTy = nullptr;
- AttributeSetNode *NestAttr;
+ AttributeList NestAttr;
// Look for a parameter marked with the 'nest' attribute.
for (FunctionType::param_iterator I = NestFTy->param_begin(),
@@ -4233,15 +4232,18 @@ InstCombiner::transformCallThroughTrampo
if (NestTy) {
Instruction *Caller = CS.getInstruction();
std::vector<Value*> NewArgs;
- std::vector<AttributeSetNode *> NewAttrs;
NewArgs.reserve(CS.arg_size() + 1);
- NewAttrs.reserve(CS.arg_size() + 2);
+
+ SmallVector<AttributeList, 8> NewAttrs;
+ NewAttrs.reserve(Attrs.getNumSlots() + 1);
// Insert the nest argument into the call argument list, which may
// mean appending it. Likewise for attributes.
// Add any result attributes.
- NewAttrs.push_back(Attrs.getRetAttributes());
+ if (Attrs.hasAttributes(AttributeList::ReturnIndex))
+ NewAttrs.push_back(
+ AttributeList::get(Caller->getContext(), Attrs.getRetAttributes()));
{
unsigned Idx = 1;
@@ -4253,7 +4255,8 @@ InstCombiner::transformCallThroughTrampo
if (NestVal->getType() != NestTy)
NestVal = Builder->CreateBitCast(NestVal, NestTy, "nest");
NewArgs.push_back(NestVal);
- NewAttrs.push_back(NestAttr);
+ NewAttrs.push_back(
+ AttributeList::get(Caller->getContext(), NestAttr));
}
if (I == E)
@@ -4261,7 +4264,12 @@ InstCombiner::transformCallThroughTrampo
// Add the original argument and attributes.
NewArgs.push_back(*I);
- NewAttrs.push_back(Attrs.getParamAttributes(Idx));
+ AttributeList Attr = Attrs.getParamAttributes(Idx);
+ if (Attr.hasAttributes(Idx)) {
+ AttrBuilder B(Attr, Idx);
+ NewAttrs.push_back(AttributeList::get(Caller->getContext(),
+ Idx + (Idx >= NestIdx), B));
+ }
++Idx;
++I;
@@ -4269,7 +4277,9 @@ InstCombiner::transformCallThroughTrampo
}
// Add any function attributes.
- NewAttrs.push_back(Attrs.getFnAttributes());
+ if (Attrs.hasAttributes(AttributeList::FunctionIndex))
+ NewAttrs.push_back(
+ AttributeList::get(FTy->getContext(), Attrs.getFnAttributes()));
// The trampoline may have been bitcast to a bogus type (FTy).
// Handle this by synthesizing a new function type, equal to FTy
@@ -4309,7 +4319,8 @@ InstCombiner::transformCallThroughTrampo
NestF->getType() == PointerType::getUnqual(NewFTy) ?
NestF : ConstantExpr::getBitCast(NestF,
PointerType::getUnqual(NewFTy));
- AttributeList NewPAL = AttributeList::get(FTy->getContext(), NewAttrs);
+ const 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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp Mon Apr 10 15:34:19 2017
@@ -1392,6 +1392,7 @@ 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(
@@ -1406,9 +1407,8 @@ 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(AttributeList::get(Call->getContext(),
- AttributeList::FunctionIndex,
- NewAttrs.getFnAttributes()));
+ Call->setAttributes(NewAttrs.getFnAttributes());
+ ReturnAttrs = NewAttrs.getRetAttributes();
Token = Call;
@@ -1435,9 +1435,8 @@ 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(AttributeList::get(Invoke->getContext(),
- AttributeList::FunctionIndex,
- NewAttrs.getFnAttributes()));
+ Invoke->setAttributes(NewAttrs.getFnAttributes());
+ ReturnAttrs = NewAttrs.getRetAttributes();
Token = Invoke;
@@ -1483,9 +1482,7 @@ makeStatepointExplicitImpl(const CallSit
StringRef Name =
CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : "";
CallInst *GCResult = Builder.CreateGCResult(Token, CS.getType(), Name);
- GCResult->setAttributes(
- AttributeList::get(GCResult->getContext(), AttributeList::ReturnIndex,
- CS.getAttributes().getRetAttributes()));
+ GCResult->setAttributes(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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Apr 10 15:34:19 2017
@@ -103,25 +103,21 @@ 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])) {
- if (auto *ParmAttrs = OldAttrs.getParamAttributes(OldArg.getArgNo() + 1))
- AttrVec.emplace_back(NewArg->getArgNo() + 1, ParmAttrs);
+ AttributeList attrs = OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
+ if (attrs.getNumSlots() > 0)
+ NewArg->addAttr(attrs);
}
- // Copy any function attributes.
- if (auto *FnAttrs = OldAttrs.getFnAttributes())
- AttrVec.emplace_back(AttributeList::FunctionIndex, FnAttrs);
-
- NewFunc->setAttributes(AttributeList::get(NewFunc->getContext(), AttrVec));
+ NewFunc->setAttributes(
+ NewFunc->getAttributes()
+ .addAttributes(NewFunc->getContext(), AttributeList::ReturnIndex,
+ OldAttrs.getRetAttributes())
+ .addAttributes(NewFunc->getContext(), AttributeList::FunctionIndex,
+ OldAttrs.getFnAttributes()));
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=299878&r1=299877&r2=299878&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp Mon Apr 10 15:34:19 2017
@@ -362,7 +362,8 @@ 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.
- AttrBuilder AB(oldFunction->getAttributes().getFnAttributes());
+ AttributeList OldFnAttrs = oldFunction->getAttributes().getFnAttributes();
+ AttrBuilder AB(OldFnAttrs, AttributeList::FunctionIndex);
for (const auto &Attr : AB.td_attrs())
newFunction->addFnAttr(Attr.first, Attr.second);
More information about the llvm-commits
mailing list