Remove some introspection functions.
The 'getSlot' function and its ilk allow introspection into the AttributeSet
class. However, that class should be opaque. Allow access through accessor
methods instead.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173522 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 29246f3..37d487f 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -146,20 +146,6 @@
uint64_t Raw() const;
- /// \brief Which attributes cannot be applied to a type.
- static Attribute typeIncompatible(Type *Ty);
-
- /// \brief 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(Attribute Attrs);
-
- /// \brief 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 Attribute decodeLLVMAttributesForBitcode(LLVMContext &C,
- uint64_t EncodedAttrs);
-
/// \brief The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
std::string getAsString() const;
@@ -236,6 +222,7 @@
/// \brief Return an AttributeSet with the specified parameters in it.
static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
+ static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
static AttributeSet get(LLVMContext &C, unsigned Idx,
Attribute::AttrKind Kind);
static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B);
@@ -296,6 +283,10 @@
/// \brief Return true if attribute exists at the given index.
bool hasAttributes(unsigned Index) const;
+ /// \brief Returns the alignment field of an attribute as a byte alignment
+ /// value.
+ unsigned getAlignment(unsigned Index) const;
+
/// \brief Get the stack alignment.
unsigned getStackAlignment(unsigned Index) const;
@@ -342,6 +333,9 @@
/// \brief Return the index for the given slot.
unsigned getSlotIndex(unsigned Slot) const;
+ /// \brief Return the attributes at the given slot.
+ AttributeSet getSlotAttributes(unsigned Slot) const;
+
/// \brief Return the AttributeWithIndex at the specified slot. This holds a
/// index number plus a set of attributes.
const AttributeWithIndex &getSlot(unsigned Slot) const;
@@ -479,6 +473,24 @@
}
};
+namespace AttributeFuncs {
+
+/// \brief Which attributes cannot be applied to a type.
+Attribute typeIncompatible(Type *Ty);
+
+/// \brief 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 encodeLLVMAttributesForBitcode(AttributeSet Attrs, unsigned Index);
+
+/// \brief 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'.
+Attribute decodeLLVMAttributesForBitcode(LLVMContext &C,
+ uint64_t EncodedAttrs);
+
+} // end AttributeFuncs namespace
+
} // end llvm namespace
#endif
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index f09b93b..4190161 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -465,7 +465,7 @@
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
Attribute ReconstitutedAttr =
- Attribute::decodeLLVMAttributesForBitcode(Context, Record[i+1]);
+ AttributeFuncs::decodeLLVMAttributesForBitcode(Context, Record[i+1]);
Record[i+1] = ReconstitutedAttr.Raw();
}
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index cc6b8b3..b6c2bc0 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -173,9 +173,11 @@
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
const AttributeSet &A = Attrs[i];
for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) {
- const AttributeWithIndex &PAWI = A.getSlot(i);
- Record.push_back(A.getSlotIndex(i));
- Record.push_back(Attribute::encodeLLVMAttributesForBitcode(PAWI.Attrs));
+ unsigned Index = A.getSlotIndex(i);
+ Record.push_back(Index);
+ Record.push_back(AttributeFuncs::
+ encodeLLVMAttributesForBitcode(A.getSlotAttributes(i),
+ Index));
}
Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record);
diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h
index ebd90e2..d7ebec5 100644
--- a/lib/IR/AttributeImpl.h
+++ b/lib/IR/AttributeImpl.h
@@ -104,6 +104,8 @@
/// \brief This class represents a set of attributes that apply to the function,
/// return type, and parameters.
class AttributeSetImpl : public FoldingSetNode {
+ friend class AttributeSet;
+
LLVMContext &Context;
SmallVector<AttributeWithIndex, 4> AttrList;
@@ -126,6 +128,10 @@
// FIXME: This needs to use AttrNodes instead.
return AttrList[Slot].Index;
}
+ AttributeSet getSlotAttributes(unsigned Slot) const {
+ // FIXME: This needs to use AttrNodes instead.
+ return AttributeSet::get(Context, AttrList[Slot]);
+ }
void Profile(FoldingSetNodeID &ID) const {
Profile(ID, AttrList);
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index 538d9fe..f44a0fc 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -103,63 +103,6 @@
return pImpl ? pImpl->Raw() : 0;
}
-Attribute Attribute::typeIncompatible(Type *Ty) {
- AttrBuilder Incompatible;
-
- if (!Ty->isIntegerTy())
- // Attribute that only apply to integers.
- Incompatible.addAttribute(Attribute::SExt)
- .addAttribute(Attribute::ZExt);
-
- if (!Ty->isPointerTy())
- // Attribute that only apply to pointers.
- Incompatible.addAttribute(Attribute::ByVal)
- .addAttribute(Attribute::Nest)
- .addAttribute(Attribute::NoAlias)
- .addAttribute(Attribute::NoCapture)
- .addAttribute(Attribute::StructRet);
-
- return Attribute::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 Attribute::encodeLLVMAttributesForBitcode(Attribute 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(Attribute::Alignment))
- EncodedAttrs |= Attrs.getAlignment() << 16;
- EncodedAttrs |= (Attrs.Raw() & (0xffffULL << 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'.
-Attribute Attribute::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 & (0xffffULL << 32)) >> 11);
- return Attribute::get(C, B);
-}
-
std::string Attribute::getAsString() const {
std::string Result;
if (hasAttribute(Attribute::ZExt))
@@ -666,6 +609,18 @@
return get(C, AttributeWithIndex::get(Idx, Attribute::get(C, Kind)));
}
+AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
+ SmallVector<AttributeWithIndex, 8> AttrList;
+ for (ArrayRef<AttributeSet>::iterator I = Attrs.begin(), E = Attrs.end();
+ I != E; ++I) {
+ AttributeSet AS = *I;
+ if (!AS.AttrList) continue;
+ AttrList.append(AS.AttrList->AttrList.begin(), AS.AttrList->AttrList.end());
+ }
+
+ return get(C, AttrList);
+}
+
//===----------------------------------------------------------------------===//
// AttributeSet Method Implementations
//===----------------------------------------------------------------------===//
@@ -688,6 +643,12 @@
return AttrList->getSlotIndex(Slot);
}
+AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const {
+ assert(AttrList && Slot < AttrList->getNumAttributes() &&
+ "Slot # out of range!");
+ return AttrList->getSlotAttributes(Slot);
+}
+
/// getSlot - Return the AttributeWithIndex at the specified slot. This
/// holds a number plus a set of attributes.
const AttributeWithIndex &AttributeSet::getSlot(unsigned Slot) const {
@@ -859,3 +820,66 @@
dbgs() << "]\n";
}
+
+//===----------------------------------------------------------------------===//
+// AttributeFuncs Function Defintions
+//===----------------------------------------------------------------------===//
+
+Attribute AttributeFuncs::typeIncompatible(Type *Ty) {
+ AttrBuilder Incompatible;
+
+ if (!Ty->isIntegerTy())
+ // Attribute that only apply to integers.
+ Incompatible.addAttribute(Attribute::SExt)
+ .addAttribute(Attribute::ZExt);
+
+ if (!Ty->isPointerTy())
+ // Attribute that only apply to pointers.
+ Incompatible.addAttribute(Attribute::ByVal)
+ .addAttribute(Attribute::Nest)
+ .addAttribute(Attribute::NoAlias)
+ .addAttribute(Attribute::NoCapture)
+ .addAttribute(Attribute::StructRet);
+
+ return Attribute::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 AttributeFuncs::encodeLLVMAttributesForBitcode(AttributeSet Attrs,
+ unsigned Index) {
+ // 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(Index) & 0xffff;
+ if (Attrs.hasAttribute(Index, Attribute::Alignment))
+ EncodedAttrs |= Attrs.getParamAlignment(Index) << 16;
+ EncodedAttrs |= (Attrs.Raw(Index) & (0xffffULL << 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'.
+Attribute AttributeFuncs::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 & (0xffffULL << 32)) >> 11);
+ return Attribute::get(C, B);
+}
+
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 9a482f1..39f95fa 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -693,9 +693,9 @@
"'noinline and alwaysinline' are incompatible!", V);
Assert1(!AttrBuilder(Attrs, Idx).
- hasAttributes(Attribute::typeIncompatible(Ty)),
+ hasAttributes(AttributeFuncs::typeIncompatible(Ty)),
"Wrong types for attribute: " +
- Attribute::typeIncompatible(Ty).getAsString(), V);
+ AttributeFuncs::typeIncompatible(Ty).getAsString(), V);
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) ||
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 2560c6e..1f4bdf8 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -474,7 +474,7 @@
Out << "AttributeWithIndex PAWI;"; nl(Out);
for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
unsigned index = PAL.getSlotIndex(i);
- AttrBuilder attrs(PAL.getSlot(i).Attrs);
+ AttrBuilder attrs(PAL.getSlotAttributes(i), index);
Out << "PAWI.Index = " << index << "U;\n";
Out << " {\n AttrBuilder B;\n";
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 4603146..61b37d8 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -273,13 +273,15 @@
// Drop any attributes that were on the vararg arguments.
AttributeSet PAL = CS.getAttributes();
if (!PAL.isEmpty() && PAL.getSlotIndex(PAL.getNumSlots() - 1) > NumArgs) {
- SmallVector<AttributeWithIndex, 8> AttributesVec;
+ SmallVector<AttributeSet, 8> AttributesVec;
for (unsigned i = 0; PAL.getSlotIndex(i) <= NumArgs; ++i)
- AttributesVec.push_back(PAL.getSlot(i));
+ AttributesVec.push_back(PAL.getSlotAttributes(i));
if (PAL.hasAttributes(AttributeSet::FunctionIndex))
- AttributesVec.push_back(AttributeWithIndex::get(Fn.getContext(),
- AttributeSet::FunctionIndex,
- PAL.getFnAttributes()));
+ AttributesVec.push_back(
+ AttributeSet::get(Fn.getContext(),
+ AttributeWithIndex::get(Fn.getContext(),
+ AttributeSet::FunctionIndex,
+ PAL.getFnAttributes())));
PAL = AttributeSet::get(Fn.getContext(), AttributesVec);
}
@@ -765,10 +767,10 @@
RAttrs =
AttributeSet::get(NRetTy->getContext(), AttributeSet::ReturnIndex,
AttrBuilder(RAttrs, AttributeSet::ReturnIndex).
- removeAttributes(Attribute::typeIncompatible(NRetTy)));
+ removeAttributes(AttributeFuncs::typeIncompatible(NRetTy)));
else
assert(!AttrBuilder(RAttrs, AttributeSet::ReturnIndex).
- hasAttributes(Attribute::typeIncompatible(NRetTy)) &&
+ hasAttributes(AttributeFuncs::typeIncompatible(NRetTy)) &&
"Return attributes no longer compatible?");
if (RAttrs.hasAttributes(AttributeSet::ReturnIndex))
@@ -846,7 +848,7 @@
RAttrs =
AttributeSet::get(NF->getContext(), AttributeSet::ReturnIndex,
AttrBuilder(RAttrs, AttributeSet::ReturnIndex).
- removeAttributes(Attribute::typeIncompatible(NF->getReturnType())));
+ removeAttributes(AttributeFuncs::typeIncompatible(NF->getReturnType())));
if (RAttrs.hasAttributes(AttributeSet::ReturnIndex))
AttributesVec.push_back(AttributeWithIndex::get(NF->getContext(),
AttributeSet::ReturnIndex,
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 52d4e2f..c753e2a 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2068,11 +2068,12 @@
static AttributeSet StripNest(LLVMContext &C, const AttributeSet &Attrs) {
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
- if (!Attrs.getSlot(i).Attrs.hasAttribute(Attribute::Nest))
+ unsigned Index = Attrs.getSlotIndex(i);
+ if (!Attrs.getSlotAttributes(i).hasAttribute(Index, Attribute::Nest))
continue;
// There can be only one.
- return Attrs.removeAttribute(C, Attrs.getSlotIndex(i), Attribute::Nest);
+ return Attrs.removeAttribute(C, Index, Attribute::Nest);
}
return Attrs;
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 8555c2f..19eb965 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1015,7 +1015,7 @@
if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
AttrBuilder RAttrs(CallerPAL, AttributeSet::ReturnIndex);
- if (RAttrs.hasAttributes(Attribute::typeIncompatible(NewRetTy)))
+ if (RAttrs.hasAttributes(AttributeFuncs::typeIncompatible(NewRetTy)))
return false; // Attribute not compatible with transformed value.
}
@@ -1045,7 +1045,7 @@
return false; // Cannot transform this parameter value.
if (AttrBuilder(CallerPAL.getParamAttributes(i + 1), i + 1).
- hasAttributes(Attribute::typeIncompatible(ParamTy)))
+ hasAttributes(AttributeFuncs::typeIncompatible(ParamTy)))
return false; // Attribute not compatible with transformed value.
// If the parameter is passed as a byval argument, then we have to have a
@@ -1101,11 +1101,13 @@
// won't be dropping them. Check that these extra arguments have attributes
// that are compatible with being a vararg call argument.
for (unsigned i = CallerPAL.getNumSlots(); i; --i) {
- if (CallerPAL.getSlotIndex(i - 1) <= FT->getNumParams())
+ unsigned Index = CallerPAL.getSlotIndex(i - 1);
+ if (Index <= FT->getNumParams())
break;
- Attribute PAttrs = CallerPAL.getSlot(i - 1).Attrs;
+
// Check if it has an attribute that's incompatible with varargs.
- if (PAttrs.hasAttribute(Attribute::StructRet))
+ AttributeSet PAttrs = CallerPAL.getSlotAttributes(i - 1);
+ if (PAttrs.hasAttribute(Index, Attribute::StructRet))
return false;
}
@@ -1122,7 +1124,7 @@
// If the return value is not being used, the type may not be compatible
// with the existing attributes. Wipe out any problematic attributes.
- RAttrs.removeAttributes(Attribute::typeIncompatible(NewRetTy));
+ RAttrs.removeAttributes(AttributeFuncs::typeIncompatible(NewRetTy));
// Add the new return attributes.
if (RAttrs.hasAttributes())