+
+/// This turns an int stack alignment (which must be a power of 2) into
+/// the form used internally in Attributes.
+inline Attributes constructStackAlignmentFromInt(unsigned i) {
+ // Default alignment, allow the target to define how to align it.
+ if (i == 0)
+ return None;
+
+ assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+ assert(i <= 0x100 && "Alignment too large.");
+ return Attributes((Log2_32(i)+1) << 26);
+}
+
+/// This returns the stack alignment field of an attribute as a byte alignment
+/// value.
+inline unsigned getStackAlignmentFromAttrs(Attributes A) {
+ Attributes StackAlign = A & Attribute::StackAlignment;
+ if (!StackAlign)
+ return 0;
+
+ return 1U << ((StackAlign.Raw() >> 26) - 1);
+}
+
+/// 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.
+inline 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 & Attribute::Alignment)
+ EncodedAttrs |= (1ull << 16) <<
+ (((Attrs & Attribute::Alignment).Raw()-1) >> 16);
+ EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
+
+ return EncodedAttrs;
+}
+
+/// 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'.
+inline Attributes decodeLLVMAttributesForBitcode(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 Attrs(EncodedAttrs & 0xffff);
+ if (Alignment)
+ Attrs |= Attribute::constructAlignmentFromInt(Alignment);
+ Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
+
+ return Attrs;
+}
+
+