/// Returns the alignment field of an attribute as a byte alignment
/// value.
- unsigned getAlignment() const;
+ MaybeAlign getAlignment() const;
/// Returns the stack alignment field of an attribute as a byte
/// alignment value.
- unsigned getStackAlignment() const;
+ MaybeAlign getStackAlignment() const;
/// Returns the number of dereferenceable bytes from the
/// dereferenceable attribute.
/// Return the target-dependent attribute object.
Attribute getAttribute(StringRef Kind) const;
- unsigned getAlignment() const;
- unsigned getStackAlignment() const;
+ MaybeAlign getAlignment() const;
+ MaybeAlign getStackAlignment() const;
uint64_t getDereferenceableBytes() const;
uint64_t getDereferenceableOrNullBytes() const;
Type *getByValType() const;
}
/// Return the alignment of the return value.
- unsigned getRetAlignment() const;
+ MaybeAlign getRetAlignment() const;
/// Return the alignment for the specified function parameter.
- unsigned getParamAlignment(unsigned ArgNo) const;
+ MaybeAlign getParamAlignment(unsigned ArgNo) const;
/// Return the byval type for the specified function parameter.
Type *getParamByValType(unsigned ArgNo) const;
/// Get the stack alignment.
- unsigned getStackAlignment(unsigned Index) const;
+ MaybeAlign getStackAlignment(unsigned Index) const;
/// Get the number of dereferenceable bytes (or zero if unknown).
uint64_t getDereferenceableBytes(unsigned Index) const;
/// doesn't exist, pair(0, 0) is returned.
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
+ /// This turns an alignment into the form used internally in Attribute.
+ /// This call has no effect if Align is not set.
+ AttrBuilder &addAlignmentAttr(MaybeAlign Align);
+
/// This turns an int alignment (which must be a power of 2) into the
/// form used internally in Attribute.
- AttrBuilder &addAlignmentAttr(unsigned Align);
+ /// This call has no effect if Align is 0.
+ /// Deprecated, use the version using a MaybeAlign.
+ inline AttrBuilder &addAlignmentAttr(unsigned Align) {
+ return addAlignmentAttr(MaybeAlign(Align));
+ }
+
+ /// This turns a stack alignment into the form used internally in Attribute.
+ /// This call has no effect if Align is not set.
+ AttrBuilder &addStackAlignmentAttr(MaybeAlign Align);
/// This turns an int stack alignment (which must be a power of 2) into
/// the form used internally in Attribute.
- AttrBuilder &addStackAlignmentAttr(unsigned Align);
+ /// This call has no effect if Align is 0.
+ /// Deprecated, use the version using a MaybeAlign.
+ inline AttrBuilder &addStackAlignmentAttr(unsigned Align) {
+ return addStackAlignmentAttr(MaybeAlign(Align));
+ }
/// This turns the number of dereferenceable bytes into the form used
/// internally in Attribute.
unsigned getFnStackAlignment() const {
if (!hasFnAttribute(Attribute::StackAlignment))
return 0;
- return AttributeSets.getStackAlignment(AttributeList::FunctionIndex);
+ if (const auto MA =
+ AttributeSets.getStackAlignment(AttributeList::FunctionIndex))
+ return MA->value();
+ return 0;
}
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
/// Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned ArgNo) const {
- return AttributeSets.getParamAlignment(ArgNo);
+ if (const auto MA = AttributeSets.getParamAlignment(ArgNo))
+ return MA->value();
+ return 0;
}
/// Extract the byval type for a parameter.
}
/// Extract the alignment of the return value.
- unsigned getRetAlignment() const { return Attrs.getRetAlignment(); }
+ unsigned getRetAlignment() const {
+ if (const auto MA = Attrs.getRetAlignment())
+ return MA->value();
+ return 0;
+ }
/// Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned ArgNo) const {
- return Attrs.getParamAlignment(ArgNo);
+ if (const auto MA = Attrs.getParamAlignment(ArgNo))
+ return MA->value();
+ return 0;
}
/// Extract the byval type for a call or parameter.
Attribute getAttribute(Attribute::AttrKind Kind) const;
Attribute getAttribute(StringRef Kind) const;
- unsigned getAlignment() const;
- unsigned getStackAlignment() const;
+ MaybeAlign getAlignment() const;
+ MaybeAlign getStackAlignment() const;
uint64_t getDereferenceableBytes() const;
uint64_t getDereferenceableOrNullBytes() const;
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
return pImpl && pImpl->hasAttribute(Kind);
}
-unsigned Attribute::getAlignment() const {
+MaybeAlign Attribute::getAlignment() const {
assert(hasAttribute(Attribute::Alignment) &&
"Trying to get alignment from non-alignment attribute!");
- return pImpl->getValueAsInt();
+ return MaybeAlign(pImpl->getValueAsInt());
}
-unsigned Attribute::getStackAlignment() const {
+MaybeAlign Attribute::getStackAlignment() const {
assert(hasAttribute(Attribute::StackAlignment) &&
"Trying to get alignment from non-alignment attribute!");
- return pImpl->getValueAsInt();
+ return MaybeAlign(pImpl->getValueAsInt());
}
uint64_t Attribute::getDereferenceableBytes() const {
return SetNode ? SetNode->getAttribute(Kind) : Attribute();
}
-unsigned AttributeSet::getAlignment() const {
- return SetNode ? SetNode->getAlignment() : 0;
+MaybeAlign AttributeSet::getAlignment() const {
+ return SetNode ? SetNode->getAlignment() : None;
}
-unsigned AttributeSet::getStackAlignment() const {
- return SetNode ? SetNode->getStackAlignment() : 0;
+MaybeAlign AttributeSet::getStackAlignment() const {
+ return SetNode ? SetNode->getStackAlignment() : None;
}
uint64_t AttributeSet::getDereferenceableBytes() const {
return {};
}
-unsigned AttributeSetNode::getAlignment() const {
+MaybeAlign AttributeSetNode::getAlignment() const {
for (const auto I : *this)
if (I.hasAttribute(Attribute::Alignment))
return I.getAlignment();
- return 0;
+ return None;
}
-unsigned AttributeSetNode::getStackAlignment() const {
+MaybeAlign AttributeSetNode::getStackAlignment() const {
for (const auto I : *this)
if (I.hasAttribute(Attribute::StackAlignment))
return I.getStackAlignment();
- return 0;
+ return None;
}
Type *AttributeSetNode::getByValType() const {
#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 = getAttributes(Index).getAlignment();
+ const MaybeAlign OldAlign = getAttributes(Index).getAlignment();
unsigned NewAlign = B.getAlignment();
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
"Attempt to change alignment!");
return getAttributes(Index).getAttribute(Kind);
}
-unsigned AttributeList::getRetAlignment() const {
+MaybeAlign AttributeList::getRetAlignment() const {
return getAttributes(ReturnIndex).getAlignment();
}
-unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
+MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
return getAttributes(ArgNo + FirstArgIndex).getAlignment();
}
return getAttributes(Index+FirstArgIndex).getByValType();
}
-
-unsigned AttributeList::getStackAlignment(unsigned Index) const {
+MaybeAlign AttributeList::getStackAlignment(unsigned Index) const {
return getAttributes(Index).getStackAlignment();
}
return unpackAllocSizeArgs(AllocSizeArgs);
}
-AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned A) {
- MaybeAlign Align(A);
+AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
if (!Align)
return *this;
return *this;
}
-AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned A) {
- MaybeAlign Align(A);
+AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
// Default alignment, allow the target to define how to align it.
if (!Align)
return *this;
// Just print .param .align <a> .b8 .param[size];
// <a> = PAL.getparamalignment
// size = typeallocsize of element type
- unsigned align = PAL.getParamAlignment(paramIndex);
- if (align == 0)
- align = DL.getABITypeAlignment(Ty);
+ const Align align = DL.getValueOrABITypeAlignment(
+ PAL.getParamAlignment(paramIndex), Ty);
unsigned sz = DL.getTypeAllocSize(Ty);
- O << "\t.param .align " << align << " .b8 ";
+ O << "\t.param .align " << align.value() << " .b8 ";
printParamName(I, paramIndex, O);
O << "[" << sz << "]";
// Just print .param .align <a> .b8 .param[size];
// <a> = PAL.getparamalignment
// size = typeallocsize of element type
- unsigned align = PAL.getParamAlignment(paramIndex);
- if (align == 0)
- align = DL.getABITypeAlignment(ETy);
+ Align align =
+ DL.getValueOrABITypeAlignment(PAL.getParamAlignment(paramIndex), ETy);
// Work around a bug in ptxas. When PTX code takes address of
// byval parameter with alignment < 4, ptxas generates code to
// spill argument into memory. Alas on sm_50+ ptxas generates
// TODO: this will need to be undone when we get to support multi-TU
// device-side compilation as it breaks ABI compatibility with nvcc.
// Hopefully ptxas bug is fixed by then.
- if (!isKernelFunc && align < 4)
- align = 4;
+ if (!isKernelFunc && align < Align(4))
+ align = Align(4);
unsigned sz = DL.getTypeAllocSize(ETy);
- O << "\t.param .align " << align << " .b8 ";
+ O << "\t.param .align " << align.value() << " .b8 ";
printParamName(I, paramIndex, O);
O << "[" << sz << "]";
continue;
Attribute::getWithAlignment(C, Align(8)));
AL = AL.addAttribute(C, AttributeList::FirstArgIndex + 1,
Attribute::getWithAlignment(C, Align(32)));
- EXPECT_EQ(8U, AL.getParamAlignment(0));
- EXPECT_EQ(32U, AL.getParamAlignment(1));
+ EXPECT_EQ(Align(8), AL.getParamAlignment(0));
+ EXPECT_EQ(Align(32), AL.getParamAlignment(1));
AttrBuilder B;
B.addAttribute(Attribute::NonNull);
B.addAlignmentAttr(8);
AL = AL.addAttributes(C, AttributeList::FirstArgIndex, B);
- EXPECT_EQ(8U, AL.getParamAlignment(0));
- EXPECT_EQ(32U, AL.getParamAlignment(1));
+ EXPECT_EQ(Align(8), AL.getParamAlignment(0));
+ EXPECT_EQ(Align(32), AL.getParamAlignment(1));
EXPECT_TRUE(AL.hasParamAttribute(0, Attribute::NonNull));
}