Move the Attributes::Builder outside of the Attributes class and into its own class named AttrBuilder. No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165960 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2012-10-15 20:35:56 +00:00
parent 874c0a6ec7
commit 702cc91aa1
20 changed files with 219 additions and 214 deletions

View File

@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
* Set the alignment for a function parameter.
*
* @see llvm::Argument::addAttr()
* @see llvm::Attributes::Builder::addAlignmentAttr()
* @see llvm::AttrBuilder::addAlignmentAttr()
*/
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);

View File

@ -22,13 +22,11 @@
namespace llvm {
class AttrBuilder;
class AttributesImpl;
class LLVMContext;
class Type;
/// AttributeImpl - The internal representation of the Attributes class. This is
/// uniquified.
class AttributesImpl;
/// Attributes - A bitset of attributes.
class Attributes {
public:
@ -101,100 +99,8 @@ public:
/// get - Return a uniquified Attributes object. This takes the uniquified
/// value from the Builder and wraps it in the Attributes class.
class Builder;
static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals);
static Attributes get(LLVMContext &Context, Builder &B);
//===--------------------------------------------------------------------===//
/// Attributes::Builder - This class is used in conjunction with the
/// Attributes::get method to create an Attributes object. The object itself
/// is uniquified. The Builder's value, however, is not. So this can be used
/// as a quick way to test for equality, presence of attributes, etc.
class Builder {
friend class Attributes;
uint64_t Bits;
public:
Builder() : Bits(0) {}
explicit Builder(uint64_t B) : Bits(B) {}
Builder(const Attributes &A) : Bits(A.Raw()) {}
Builder(const Builder &B) : Bits(B.Bits) {}
void clear() { Bits = 0; }
/// addAttribute - Add an attribute to the builder.
Builder &addAttribute(Attributes::AttrVal Val);
/// removeAttribute - Remove an attribute from the builder.
Builder &removeAttribute(Attributes::AttrVal Val);
/// addAttribute - Add the attributes from A to the builder.
Builder &addAttributes(const Attributes &A);
/// removeAttribute - Remove the attributes from A from the builder.
Builder &removeAttributes(const Attributes &A);
/// hasAttribute - Return true if the builder has the specified attribute.
bool hasAttribute(Attributes::AttrVal A) const;
/// hasAttributes - Return true if the builder has IR-level attributes.
bool hasAttributes() const;
/// hasAttributes - Return true if the builder has any attribute that's in
/// the specified attribute.
bool hasAttributes(const Attributes &A) const;
/// hasAlignmentAttr - Return true if the builder has an alignment
/// attribute.
bool hasAlignmentAttr() const;
/// getAlignment - Retrieve the alignment attribute, if it exists.
uint64_t getAlignment() const;
/// getStackAlignment - Retrieve the stack alignment attribute, if it
/// exists.
uint64_t getStackAlignment() const;
/// addAlignmentAttr - This turns an int alignment (which must be a power of
/// 2) into the form used internally in Attributes.
Builder &addAlignmentAttr(unsigned Align);
/// addStackAlignmentAttr - This turns an int stack alignment (which must be
/// a power of 2) into the form used internally in Attributes.
Builder &addStackAlignmentAttr(unsigned Align);
/// addRawValue - Add the raw value to the internal representation.
/// N.B. This should be used ONLY for decoding LLVM bitcode!
Builder &addRawValue(uint64_t Val);
/// @brief Remove attributes that are used on functions only.
void removeFunctionOnlyAttrs() {
removeAttribute(Attributes::NoReturn)
.removeAttribute(Attributes::NoUnwind)
.removeAttribute(Attributes::ReadNone)
.removeAttribute(Attributes::ReadOnly)
.removeAttribute(Attributes::NoInline)
.removeAttribute(Attributes::AlwaysInline)
.removeAttribute(Attributes::OptimizeForSize)
.removeAttribute(Attributes::StackProtect)
.removeAttribute(Attributes::StackProtectReq)
.removeAttribute(Attributes::NoRedZone)
.removeAttribute(Attributes::NoImplicitFloat)
.removeAttribute(Attributes::Naked)
.removeAttribute(Attributes::InlineHint)
.removeAttribute(Attributes::StackAlignment)
.removeAttribute(Attributes::UWTable)
.removeAttribute(Attributes::NonLazyBind)
.removeAttribute(Attributes::ReturnsTwice)
.removeAttribute(Attributes::AddressSafety);
}
bool operator==(const Builder &B) {
return Bits == B.Bits;
}
bool operator!=(const Builder &B) {
return Bits != B.Bits;
}
};
static Attributes get(LLVMContext &Context, AttrBuilder &B);
/// @brief Return true if the attribute is present.
bool hasAttribute(AttrVal Val) const;
@ -264,42 +170,14 @@ public:
/// encodeLLVMAttributesForBitcode - This returns an integer containing an
/// encoding of all the LLVM attributes found in the given attribute bitset.
/// Any change to this encoding is a breaking change to bitcode compatibility.
static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
// FIXME: It doesn't make sense to store the alignment information as an
// expanded out value, we should store it as a log2 value. However, we
// can't just change that here without breaking bitcode compatibility. If
// this ever becomes a problem in practice, we should introduce new tag
// numbers in the bitcode file and have those tags use a more efficiently
// encoded alignment field.
// Store the alignment in the bitcode as a 16-bit raw value instead of a
// 5-bit log2 encoded value. Shift the bits above the alignment up by 11
// bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
if (Attrs.hasAttribute(Attributes::Alignment))
EncodedAttrs |= Attrs.getAlignment() << 16;
EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
return EncodedAttrs;
}
static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs);
/// decodeLLVMAttributesForBitcode - This returns an attribute bitset
/// containing the LLVM attributes that have been decoded from the given
/// integer. This function must stay in sync with
/// 'encodeLLVMAttributesForBitcode'.
static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C,
uint64_t EncodedAttrs) {
// The alignment is stored as a 16-bit raw value from bits 31--16. We shift
// the bits above 31 down by 11 bits.
unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
assert((!Alignment || isPowerOf2_32(Alignment)) &&
"Alignment must be a power of two.");
Attributes::Builder B(EncodedAttrs & 0xffff);
if (Alignment)
B.addAlignmentAttr(Alignment);
B.addRawValue((EncodedAttrs & (0xfffULL << 32)) >> 11);
return Attributes::get(C, B);
}
uint64_t EncodedAttrs);
/// getAsString - The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out the
@ -308,6 +186,95 @@ public:
std::string getAsString() const;
};
//===----------------------------------------------------------------------===//
/// AttrBuilder - This class is used in conjunction with the Attributes::get
/// method to create an Attributes object. The object itself is uniquified. The
/// Builder's value, however, is not. So this can be used as a quick way to test
/// for equality, presence of attributes, etc.
class AttrBuilder {
friend class Attributes;
uint64_t Bits;
public:
AttrBuilder() : Bits(0) {}
explicit AttrBuilder(uint64_t B) : Bits(B) {}
AttrBuilder(const Attributes &A) : Bits(A.Raw()) {}
AttrBuilder(const AttrBuilder &B) : Bits(B.Bits) {}
void clear() { Bits = 0; }
/// addAttribute - Add an attribute to the builder.
AttrBuilder &addAttribute(Attributes::AttrVal Val);
/// removeAttribute - Remove an attribute from the builder.
AttrBuilder &removeAttribute(Attributes::AttrVal Val);
/// addAttribute - Add the attributes from A to the builder.
AttrBuilder &addAttributes(const Attributes &A);
/// removeAttribute - Remove the attributes from A from the builder.
AttrBuilder &removeAttributes(const Attributes &A);
/// hasAttribute - Return true if the builder has the specified attribute.
bool hasAttribute(Attributes::AttrVal A) const;
/// hasAttributes - Return true if the builder has IR-level attributes.
bool hasAttributes() const;
/// hasAttributes - Return true if the builder has any attribute that's in the
/// specified attribute.
bool hasAttributes(const Attributes &A) const;
/// hasAlignmentAttr - Return true if the builder has an alignment attribute.
bool hasAlignmentAttr() const;
/// getAlignment - Retrieve the alignment attribute, if it exists.
uint64_t getAlignment() const;
/// getStackAlignment - Retrieve the stack alignment attribute, if it exists.
uint64_t getStackAlignment() const;
/// addAlignmentAttr - This turns an int alignment (which must be a power of
/// 2) into the form used internally in Attributes.
AttrBuilder &addAlignmentAttr(unsigned Align);
/// addStackAlignmentAttr - This turns an int stack alignment (which must be a
/// power of 2) into the form used internally in Attributes.
AttrBuilder &addStackAlignmentAttr(unsigned Align);
/// addRawValue - Add the raw value to the internal representation.
/// N.B. This should be used ONLY for decoding LLVM bitcode!
AttrBuilder &addRawValue(uint64_t Val);
/// @brief Remove attributes that are used on functions only.
void removeFunctionOnlyAttrs() {
removeAttribute(Attributes::NoReturn)
.removeAttribute(Attributes::NoUnwind)
.removeAttribute(Attributes::ReadNone)
.removeAttribute(Attributes::ReadOnly)
.removeAttribute(Attributes::NoInline)
.removeAttribute(Attributes::AlwaysInline)
.removeAttribute(Attributes::OptimizeForSize)
.removeAttribute(Attributes::StackProtect)
.removeAttribute(Attributes::StackProtectReq)
.removeAttribute(Attributes::NoRedZone)
.removeAttribute(Attributes::NoImplicitFloat)
.removeAttribute(Attributes::Naked)
.removeAttribute(Attributes::InlineHint)
.removeAttribute(Attributes::StackAlignment)
.removeAttribute(Attributes::UWTable)
.removeAttribute(Attributes::NonLazyBind)
.removeAttribute(Attributes::ReturnsTwice)
.removeAttribute(Attributes::AddressSafety);
}
bool operator==(const AttrBuilder &B) {
return Bits == B.Bits;
}
bool operator!=(const AttrBuilder &B) {
return Bits != B.Bits;
}
};
//===----------------------------------------------------------------------===//
// AttributeWithIndex
//===----------------------------------------------------------------------===//
@ -322,7 +289,7 @@ struct AttributeWithIndex {
static AttributeWithIndex get(LLVMContext &C, unsigned Idx,
ArrayRef<Attributes::AttrVal> Attrs) {
Attributes::Builder B;
AttrBuilder B;
for (ArrayRef<Attributes::AttrVal>::iterator I = Attrs.begin(),
E = Attrs.end(); I != E; ++I)

View File

@ -178,7 +178,7 @@ public:
///
void addFnAttr(Attributes::AttrVal N) {
// Function Attributes are stored at ~0 index
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(N);
addAttribute(~0U, Attributes::get(getContext(), B));
}
@ -278,7 +278,7 @@ public:
return getParamAttributes(n).hasAttribute(Attributes::NoAlias);
}
void setDoesNotAlias(unsigned n) {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoAlias);
addAttribute(n, Attributes::get(getContext(), B));
}
@ -289,7 +289,7 @@ public:
return getParamAttributes(n).hasAttribute(Attributes::NoCapture);
}
void setDoesNotCapture(unsigned n) {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoCapture);
addAttribute(n, Attributes::get(getContext(), B));
}

View File

@ -1281,7 +1281,7 @@ public:
/// @brief Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attributes::NoInline); }
void setIsNoInline() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoInline);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -1291,7 +1291,7 @@ public:
return hasFnAttr(Attributes::ReturnsTwice);
}
void setCanReturnTwice() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::ReturnsTwice);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -1301,7 +1301,7 @@ public:
return hasFnAttr(Attributes::ReadNone);
}
void setDoesNotAccessMemory() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::ReadNone);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -1311,7 +1311,7 @@ public:
return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly);
}
void setOnlyReadsMemory() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::ReadOnly);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -1319,7 +1319,7 @@ public:
/// @brief Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); }
void setDoesNotReturn() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoReturn);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -1327,7 +1327,7 @@ public:
/// @brief Determine if the call cannot unwind.
bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); }
void setDoesNotThrow() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -3036,7 +3036,7 @@ public:
/// @brief Return true if the call should not be inlined.
bool isNoInline() const { return hasFnAttr(Attributes::NoInline); }
void setIsNoInline() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoInline);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -3046,7 +3046,7 @@ public:
return hasFnAttr(Attributes::ReadNone);
}
void setDoesNotAccessMemory() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::ReadNone);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -3056,7 +3056,7 @@ public:
return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly);
}
void setOnlyReadsMemory() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::ReadOnly);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -3064,7 +3064,7 @@ public:
/// @brief Determine if the call cannot return.
bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); }
void setDoesNotReturn() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoReturn);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}
@ -3072,7 +3072,7 @@ public:
/// @brief Determine if the call cannot unwind.
bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); }
void setDoesNotThrow() {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
addAttribute(AttrListPtr::FunctionIndex, Attributes::get(getContext(), B));
}

View File

@ -916,7 +916,7 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
/// 2: function attr.
bool LLParser::ParseOptionalAttrs(Attributes::Builder &B, unsigned AttrKind) {
bool LLParser::ParseOptionalAttrs(AttrBuilder &B, unsigned AttrKind) {
LocTy AttrLoc = Lex.getLoc();
bool HaveError = false;
@ -1435,7 +1435,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = 0;
Attributes::Builder ArgAttrs;
AttrBuilder ArgAttrs;
Value *V;
if (ParseType(ArgTy, ArgLoc))
return true;
@ -1476,7 +1476,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
} else {
LocTy TypeLoc = Lex.getLoc();
Type *ArgTy = 0;
Attributes::Builder Attrs;
AttrBuilder Attrs;
std::string Name;
if (ParseType(ArgTy) ||
@ -2677,7 +2677,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
unsigned Linkage;
unsigned Visibility;
Attributes::Builder RetAttrs;
AttrBuilder RetAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
@ -2741,7 +2741,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
Attributes::Builder FuncAttrs;
AttrBuilder FuncAttrs;
std::string Section;
unsigned Alignment;
std::string GC;
@ -3262,7 +3262,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
Attributes::Builder RetAttrs, FnAttrs;
AttrBuilder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@ -3667,7 +3667,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
/// ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
Attributes::Builder RetAttrs, FnAttrs;
AttrBuilder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;

View File

@ -175,7 +175,7 @@ namespace llvm {
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
bool ParseOptionalAttrs(Attributes::Builder &Attrs, unsigned AttrKind);
bool ParseOptionalAttrs(AttrBuilder &Attrs, unsigned AttrKind);
bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);
bool ParseOptionalLinkage(unsigned &Linkage) {
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);

View File

@ -481,7 +481,7 @@ bool BitcodeReader::ParseAttributeBlock() {
}
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
Attributes::Builder B(Record[i+1]);
AttrBuilder B(Record[i+1]);
if (B.hasAttributes())
Attrs.push_back(AttributeWithIndex::get(Record[i],
Attributes::get(Context, B)));

View File

@ -314,8 +314,8 @@ bool llvm::isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
// the return. Ignore noalias because it doesn't affect the call sequence.
const Function *F = ExitBB->getParent();
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
if (Attributes::Builder(CalleeRetAttr).removeAttribute(Attributes::NoAlias) !=
Attributes::Builder(CallerRetAttr).removeAttribute(Attributes::NoAlias))
if (AttrBuilder(CalleeRetAttr).removeAttribute(Attributes::NoAlias) !=
AttrBuilder(CallerRetAttr).removeAttribute(Attributes::NoAlias))
return false;
// It's not safe to eliminate the sign / zero extension of the return value.
@ -356,7 +356,7 @@ bool llvm::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
// Conservatively require the attributes of the call to match those of
// the return. Ignore noalias because it doesn't affect the call sequence.
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
if (Attributes::Builder(CallerRetAttr)
if (AttrBuilder(CallerRetAttr)
.removeAttribute(Attributes::NoAlias).hasAttributes())
return false;

View File

@ -474,9 +474,9 @@ void CppWriter::printAttributes(const AttrListPtr &PAL,
Out << "AttributeWithIndex PAWI;"; nl(Out);
for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
unsigned index = PAL.getSlot(i).Index;
Attributes::Builder attrs(PAL.getSlot(i).Attrs);
AttrBuilder attrs(PAL.getSlot(i).Attrs);
Out << "PAWI.Index = " << index << "U;\n";
Out << " Attributes::Builder B;\n";
Out << " AttrBuilder B;\n";
#define HANDLE_ATTR(X) \
if (attrs.hasAttribute(Attributes::X)) \

View File

@ -765,10 +765,10 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
// required when new return value attributes are added.
if (NRetTy->isVoidTy())
RAttrs =
Attributes::get(NRetTy->getContext(), Attributes::Builder(RAttrs).
Attributes::get(NRetTy->getContext(), AttrBuilder(RAttrs).
removeAttributes(Attributes::typeIncompatible(NRetTy)));
else
assert(!Attributes::Builder(RAttrs).
assert(!AttrBuilder(RAttrs).
hasAttributes(Attributes::typeIncompatible(NRetTy)) &&
"Return attributes no longer compatible?");
@ -840,7 +840,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
Attributes FnAttrs = CallPAL.getFnAttributes();
// Adjust in case the function was changed to return void.
RAttrs =
Attributes::get(NF->getContext(), Attributes::Builder(RAttrs).
Attributes::get(NF->getContext(), AttrBuilder(RAttrs).
removeAttributes(Attributes::typeIncompatible(NF->getReturnType())));
if (RAttrs.hasAttributes())
AttributesVec.push_back(AttributeWithIndex::get(AttrListPtr::ReturnIndex,

View File

@ -212,7 +212,7 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
MadeChange = true;
// Clear out any existing attributes.
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::ReadOnly)
.addAttribute(Attributes::ReadNone);
F->removeAttribute(AttrListPtr::FunctionIndex,
@ -357,7 +357,7 @@ bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) {
ArgumentGraph AG;
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoCapture);
// Check each function in turn, determining which pointer arguments are not

View File

@ -2062,7 +2062,7 @@ static void ChangeCalleesToFastCall(Function *F) {
}
static AttrListPtr StripNest(LLVMContext &C, const AttrListPtr &Attrs) {
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::Nest);
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {

View File

@ -137,7 +137,7 @@ bool PruneEH::runOnSCC(CallGraphSCC &SCC) {
// If the SCC doesn't unwind or doesn't throw, note this fact.
if (!SCCMightUnwind || !SCCMightReturn)
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Attributes::Builder NewAttributes;
AttrBuilder NewAttributes;
if (!SCCMightUnwind)
NewAttributes.addAttribute(Attributes::NoUnwind);

View File

@ -1007,7 +1007,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
return false; // Cannot transform this return value.
if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
Attributes::Builder RAttrs = CallerPAL.getRetAttributes();
AttrBuilder RAttrs = CallerPAL.getRetAttributes();
if (RAttrs.hasAttributes(Attributes::typeIncompatible(NewRetTy)))
return false; // Attribute not compatible with transformed value.
}
@ -1038,7 +1038,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
return false; // Cannot transform this parameter value.
Attributes Attrs = CallerPAL.getParamAttributes(i + 1);
if (Attributes::Builder(Attrs).
if (AttrBuilder(Attrs).
hasAttributes(Attributes::typeIncompatible(ParamTy)))
return false; // Attribute not compatible with transformed value.
@ -1109,7 +1109,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
attrVec.reserve(NumCommonArgs);
// Get any return attributes.
Attributes::Builder RAttrs = CallerPAL.getRetAttributes();
AttrBuilder RAttrs = CallerPAL.getRetAttributes();
// If the return value is not being used, the type may not be compatible
// with the existing attributes. Wipe out any problematic attributes.

View File

@ -774,9 +774,9 @@ bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) {
// Conservatively require the attributes of the call to match those of the
// return. Ignore noalias because it doesn't affect the call sequence.
Attributes CalleeRetAttr = CS.getAttributes().getRetAttributes();
if (Attributes::Builder(CalleeRetAttr).
if (AttrBuilder(CalleeRetAttr).
removeAttribute(Attributes::NoAlias) !=
Attributes::Builder(CallerRetAttr).
AttrBuilder(CallerRetAttr).
removeAttribute(Attributes::NoAlias))
continue;

View File

@ -1788,7 +1788,7 @@ Constant *ObjCARCOpt::getRetainRVCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -1806,7 +1806,7 @@ Constant *ObjCARCOpt::getAutoreleaseRVCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -1822,7 +1822,7 @@ Constant *ObjCARCOpt::getReleaseCallee(Module *M) {
if (!ReleaseCallee) {
LLVMContext &C = M->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -1840,7 +1840,7 @@ Constant *ObjCARCOpt::getRetainCallee(Module *M) {
if (!RetainCallee) {
LLVMContext &C = M->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -1873,7 +1873,7 @@ Constant *ObjCARCOpt::getAutoreleaseCallee(Module *M) {
if (!AutoreleaseCallee) {
LLVMContext &C = M->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -3850,9 +3850,9 @@ Constant *ObjCARCContract::getStoreStrongCallee(Module *M) {
Type *I8XX = PointerType::getUnqual(I8X);
Type *Params[] = { I8XX, I8X };
Attributes::Builder BNoUnwind;
AttrBuilder BNoUnwind;
BNoUnwind.addAttribute(Attributes::NoUnwind);
Attributes::Builder BNoCapture;
AttrBuilder BNoCapture;
BNoCapture.addAttribute(Attributes::NoCapture);
AttrListPtr Attributes = AttrListPtr()
.addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -3874,7 +3874,7 @@ Constant *ObjCARCContract::getRetainAutoreleaseCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,
@ -3891,7 +3891,7 @@ Constant *ObjCARCContract::getRetainAutoreleaseRVCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoUnwind);
AttrListPtr Attributes =
AttrListPtr().addAttr(M->getContext(), AttrListPtr::FunctionIndex,

View File

@ -348,7 +348,7 @@ struct StrToOpt : public LibCallOptimization {
if (isa<ConstantPointerNull>(EndPtr)) {
// With a null EndPtr, this function won't capture the main argument.
// It would be readonly too, except that it still may write to errno.
Attributes::Builder B;
AttrBuilder B;
B.addAttribute(Attributes::NoCapture);
CI->addAttribute(1, Attributes::get(Callee->getContext(), B));
}

View File

@ -33,14 +33,14 @@ Attributes::Attributes(AttributesImpl *A) : Attrs(A) {}
Attributes::Attributes(const Attributes &A) : Attrs(A.Attrs) {}
Attributes Attributes::get(LLVMContext &Context, ArrayRef<AttrVal> Vals) {
Attributes::Builder B;
AttrBuilder B;
for (ArrayRef<AttrVal>::iterator I = Vals.begin(), E = Vals.end();
I != E; ++I)
B.addAttribute(*I);
return Attributes::get(Context, B);
}
Attributes Attributes::get(LLVMContext &Context, Attributes::Builder &B) {
Attributes Attributes::get(LLVMContext &Context, AttrBuilder &B) {
// If there are no attributes, return an empty Attributes class.
if (B.Bits == 0)
return Attributes();
@ -96,7 +96,7 @@ uint64_t Attributes::Raw() const {
}
Attributes Attributes::typeIncompatible(Type *Ty) {
Attributes::Builder Incompatible;
AttrBuilder Incompatible;
if (!Ty->isIntegerTy())
// Attributes that only apply to integers.
@ -114,6 +114,44 @@ Attributes Attributes::typeIncompatible(Type *Ty) {
return Attributes::get(Ty->getContext(), Incompatible);
}
/// encodeLLVMAttributesForBitcode - This returns an integer containing an
/// encoding of all the LLVM attributes found in the given attribute bitset.
/// Any change to this encoding is a breaking change to bitcode compatibility.
uint64_t Attributes::encodeLLVMAttributesForBitcode(Attributes Attrs) {
// FIXME: It doesn't make sense to store the alignment information as an
// expanded out value, we should store it as a log2 value. However, we can't
// just change that here without breaking bitcode compatibility. If this ever
// becomes a problem in practice, we should introduce new tag numbers in the
// bitcode file and have those tags use a more efficiently encoded alignment
// field.
// Store the alignment in the bitcode as a 16-bit raw value instead of a 5-bit
// log2 encoded value. Shift the bits above the alignment up by 11 bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
if (Attrs.hasAttribute(Attributes::Alignment))
EncodedAttrs |= Attrs.getAlignment() << 16;
EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
return EncodedAttrs;
}
/// decodeLLVMAttributesForBitcode - This returns an attribute bitset containing
/// the LLVM attributes that have been decoded from the given integer. This
/// function must stay in sync with 'encodeLLVMAttributesForBitcode'.
Attributes Attributes::decodeLLVMAttributesForBitcode(LLVMContext &C,
uint64_t EncodedAttrs) {
// The alignment is stored as a 16-bit raw value from bits 31--16. We shift
// the bits above 31 down by 11 bits.
unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
assert((!Alignment || isPowerOf2_32(Alignment)) &&
"Alignment must be a power of two.");
AttrBuilder B(EncodedAttrs & 0xffff);
if (Alignment)
B.addAlignmentAttr(Alignment);
B.addRawValue((EncodedAttrs & (0xfffULL << 32)) >> 11);
return Attributes::get(C, B);
}
std::string Attributes::getAsString() const {
std::string Result;
if (hasAttribute(Attributes::ZExt))
@ -183,27 +221,27 @@ std::string Attributes::getAsString() const {
}
//===----------------------------------------------------------------------===//
// Attributes::Builder Implementation
// AttrBuilder Implementation
//===----------------------------------------------------------------------===//
Attributes::Builder &Attributes::Builder::addAttribute(Attributes::AttrVal Val){
AttrBuilder &AttrBuilder::addAttribute(Attributes::AttrVal Val){
Bits |= AttributesImpl::getAttrMask(Val);
return *this;
}
Attributes::Builder &Attributes::Builder::addRawValue(uint64_t Val) {
AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
Bits |= Val;
return *this;
}
Attributes::Builder &Attributes::Builder::addAlignmentAttr(unsigned Align) {
AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
if (Align == 0) return *this;
assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
assert(Align <= 0x40000000 && "Alignment too large.");
Bits |= (Log2_32(Align) + 1) << 16;
return *this;
}
Attributes::Builder &Attributes::Builder::addStackAlignmentAttr(unsigned Align){
AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align){
// Default alignment, allow the target to define how to align it.
if (Align == 0) return *this;
assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
@ -212,44 +250,44 @@ Attributes::Builder &Attributes::Builder::addStackAlignmentAttr(unsigned Align){
return *this;
}
Attributes::Builder &Attributes::Builder::
AttrBuilder &AttrBuilder::
removeAttribute(Attributes::AttrVal Val) {
Bits &= ~AttributesImpl::getAttrMask(Val);
return *this;
}
Attributes::Builder &Attributes::Builder::addAttributes(const Attributes &A) {
AttrBuilder &AttrBuilder::addAttributes(const Attributes &A) {
Bits |= A.Raw();
return *this;
}
Attributes::Builder &Attributes::Builder::removeAttributes(const Attributes &A){
AttrBuilder &AttrBuilder::removeAttributes(const Attributes &A){
Bits &= ~A.Raw();
return *this;
}
bool Attributes::Builder::hasAttribute(Attributes::AttrVal A) const {
bool AttrBuilder::hasAttribute(Attributes::AttrVal A) const {
return Bits & AttributesImpl::getAttrMask(A);
}
bool Attributes::Builder::hasAttributes() const {
bool AttrBuilder::hasAttributes() const {
return Bits != 0;
}
bool Attributes::Builder::hasAttributes(const Attributes &A) const {
bool AttrBuilder::hasAttributes(const Attributes &A) const {
return Bits & A.Raw();
}
bool Attributes::Builder::hasAlignmentAttr() const {
bool AttrBuilder::hasAlignmentAttr() const {
return Bits & AttributesImpl::getAttrMask(Attributes::Alignment);
}
uint64_t Attributes::Builder::getAlignment() const {
uint64_t AttrBuilder::getAlignment() const {
if (!hasAlignmentAttr())
return 0;
return 1U <<
(((Bits & AttributesImpl::getAttrMask(Attributes::Alignment)) >> 16) - 1);
}
uint64_t Attributes::Builder::getStackAlignment() const {
uint64_t AttrBuilder::getStackAlignment() const {
if (!hasAlignmentAttr())
return 0;
return 1U <<
@ -497,9 +535,9 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx,
"Attempt to change alignment!");
#endif
Attributes::Builder NewAttrs =
Attributes::Builder(OldAttrs).addAttributes(Attrs);
if (NewAttrs == Attributes::Builder(OldAttrs))
AttrBuilder NewAttrs =
AttrBuilder(OldAttrs).addAttributes(Attrs);
if (NewAttrs == AttrBuilder(OldAttrs))
return *this;
SmallVector<AttributeWithIndex, 8> NewAttrList;
@ -515,7 +553,7 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx,
// If there are attributes already at this index, merge them in.
if (i != e && OldAttrList[i].Index == Idx) {
Attrs =
Attributes::get(C, Attributes::Builder(Attrs).
Attributes::get(C, AttrBuilder(Attrs).
addAttributes(OldAttrList[i].Attrs));
++i;
}
@ -541,9 +579,9 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx,
if (AttrList == 0) return AttrListPtr();
Attributes OldAttrs = getAttributes(Idx);
Attributes::Builder NewAttrs =
Attributes::Builder(OldAttrs).removeAttributes(Attrs);
if (NewAttrs == Attributes::Builder(OldAttrs))
AttrBuilder NewAttrs =
AttrBuilder(OldAttrs).removeAttributes(Attrs);
if (NewAttrs == AttrBuilder(OldAttrs))
return *this;
SmallVector<AttributeWithIndex, 8> NewAttrList;
@ -556,7 +594,7 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx,
// If there are attributes already at this index, merge them in.
assert(OldAttrList[i].Index == Idx && "Attribute isn't set?");
Attrs = Attributes::get(C, Attributes::Builder(OldAttrList[i].Attrs).
Attrs = Attributes::get(C, AttrBuilder(OldAttrList[i].Attrs).
removeAttributes(Attrs));
++i;
if (Attrs.hasAttributes()) // If any attributes left for this param, add them.

View File

@ -1381,7 +1381,7 @@ void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
Function *Func = unwrap<Function>(Fn);
const AttrListPtr PAL = Func->getAttributes();
Attributes::Builder B(PA);
AttrBuilder B(PA);
const AttrListPtr PALnew =
PAL.addAttr(Func->getContext(), AttrListPtr::FunctionIndex,
Attributes::get(Func->getContext(), B));
@ -1391,7 +1391,7 @@ void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
Function *Func = unwrap<Function>(Fn);
const AttrListPtr PAL = Func->getAttributes();
Attributes::Builder B(PA);
AttrBuilder B(PA);
const AttrListPtr PALnew =
PAL.removeAttr(Func->getContext(), AttrListPtr::FunctionIndex,
Attributes::get(Func->getContext(), B));
@ -1465,13 +1465,13 @@ LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) {
void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA) {
Argument *A = unwrap<Argument>(Arg);
Attributes::Builder B(PA);
AttrBuilder B(PA);
A->addAttr(Attributes::get(A->getContext(), B));
}
void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA) {
Argument *A = unwrap<Argument>(Arg);
Attributes::Builder B(PA);
AttrBuilder B(PA);
A->removeAttr(Attributes::get(A->getContext(), B));
}
@ -1484,7 +1484,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) {
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) {
Attributes::Builder B;
AttrBuilder B;
B.addAlignmentAttr(align);
unwrap<Argument>(Arg)->addAttr(Attributes::
get(unwrap<Argument>(Arg)->getContext(), B));
@ -1676,7 +1676,7 @@ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) {
void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index,
LLVMAttribute PA) {
CallSite Call = CallSite(unwrap<Instruction>(Instr));
Attributes::Builder B(PA);
AttrBuilder B(PA);
Call.setAttributes(
Call.getAttributes().addAttr(Call->getContext(), index,
Attributes::get(Call->getContext(), B)));
@ -1685,7 +1685,7 @@ void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index,
void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,
LLVMAttribute PA) {
CallSite Call = CallSite(unwrap<Instruction>(Instr));
Attributes::Builder B(PA);
AttrBuilder B(PA);
Call.setAttributes(
Call.getAttributes().removeAttr(Call->getContext(), index,
Attributes::get(Call->getContext(), B)));
@ -1694,7 +1694,7 @@ void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,
void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
unsigned align) {
CallSite Call = CallSite(unwrap<Instruction>(Instr));
Attributes::Builder B;
AttrBuilder B;
B.addAlignmentAttr(align);
Call.setAttributes(Call.getAttributes().addAttr(Call->getContext(), index,
Attributes::get(Call->getContext(), B)));

View File

@ -567,7 +567,7 @@ void Verifier::VerifyParameterAttrs(Attributes Attrs, Type *Ty,
Attrs.hasAttribute(Attributes::AlwaysInline)), "Attributes "
"'noinline and alwaysinline' are incompatible!", V);
Assert1(!Attributes::Builder(Attrs).
Assert1(!AttrBuilder(Attrs).
hasAttributes(Attributes::typeIncompatible(Ty)),
"Wrong types for attribute: " +
Attributes::typeIncompatible(Ty).getAsString(), V);
@ -615,7 +615,7 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
}
Attributes FAttrs = Attrs.getFnAttributes();
Attributes::Builder NotFn(FAttrs);
AttrBuilder NotFn(FAttrs);
NotFn.removeFunctionOnlyAttrs();
Assert1(!NotFn.hasAttributes(), "Attributes '" +
Attributes::get(V->getContext(), NotFn).getAsString() +