diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -54,6 +54,17 @@ // The 15 first bits of `Value::SubclassData` are available for subclasses of // `Instruction` to use. using OpaqueField = Bitfield::Element; // Next bit:15 + + // Template alias so that all Instruction storing alignment use the same + // definiton. + // Valid alignments are powers of two from 2^0 to 2^MaxAlignmentExponent = + // 2^29. We store them as Log2(Alignment), so we need 5 bits to encode the 30 + // possible values. + template + using AlignmentBitfieldElement = + typename Bitfield::Element; + private: // The last bit is used to store whether the instruction has metadata attached // or not. diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -60,7 +60,7 @@ class AllocaInst : public UnaryInstruction { Type *AllocatedType; - using AlignmentField = Bitfield::Element; // Next bit:5 + using AlignmentField = AlignmentBitfieldElement<0>; // Next bit:5 using UsedWithInAllocaField = Bitfield::Element; // Next bit:6 using SwiftErrorField = Bitfield::Element; // Next bit:7 @@ -113,11 +113,15 @@ /// Return the alignment of the memory that is being allocated by the /// instruction. Align getAlign() const { - return *decodeMaybeAlign(getSubclassData()); + return Align(1ULL << getSubclassData()); } + + void setAlignment(Align Align) { + setSubclassData(Log2(Align)); + } + // FIXME: Remove this one transition to Align is over. unsigned getAlignment() const { return getAlign().value(); } - void setAlignment(Align Align); /// Return true if this alloca is in the entry block of the function and is a /// constant size. If so, the code generator will fold it into the @@ -165,9 +169,9 @@ /// Value to store whether or not the load is volatile. class LoadInst : public UnaryInstruction { using VolatileField = Bitfield::Element; // Next bit:1 - using AlignmentField = Bitfield::Element; // Next bit:7 - using OrderingField = Bitfield::Element; // Next bit:10 + using AlignmentField = AlignmentBitfieldElement<1>; // Next bit:6 + using OrderingField = Bitfield::Element; // Next bit:9 void AssertOK(); @@ -210,10 +214,12 @@ /// Return the alignment of the access that is being performed. Align getAlign() const { - return *decodeMaybeAlign(getSubclassData()); + return Align(1ULL << (getSubclassData())); } - void setAlignment(Align Alignment); + void setAlignment(Align Align) { + setSubclassData(Log2(Align)); + } /// Returns the ordering constraint of this load instruction. AtomicOrdering getOrdering() const { @@ -290,9 +296,9 @@ /// An instruction for storing to memory. class StoreInst : public Instruction { using VolatileField = Bitfield::Element; // Next bit:1 - using AlignmentField = Bitfield::Element; // Next bit:7 - using OrderingField = Bitfield::Element; // Next bit:10 + using AlignmentField = AlignmentBitfieldElement<1>; // Next bit:6 + using OrderingField = Bitfield::Element; // Next bit:9 void AssertOK(); @@ -337,10 +343,12 @@ unsigned getAlignment() const { return getAlign().value(); } Align getAlign() const { - return *decodeMaybeAlign(getSubclassData()); + return Align(1ULL << (getSubclassData())); } - void setAlignment(Align Alignment); + void setAlignment(Align Align) { + setSubclassData(Log2(Align)); + } /// Returns the ordering constraint of this store instruction. AtomicOrdering getOrdering() const { diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1297,11 +1297,6 @@ setName(Name); } -void AllocaInst::setAlignment(Align Align) { - assert(Align <= MaximumAlignment && - "Alignment is greater than MaximumAlignment!"); - setSubclassData(encode(Align)); -} bool AllocaInst::isArrayAllocation() const { if (ConstantInt *CI = dyn_cast(getOperand(0))) @@ -1393,12 +1388,6 @@ setName(Name); } -void LoadInst::setAlignment(Align Align) { - assert(Align <= MaximumAlignment && - "Alignment is greater than MaximumAlignment!"); - setSubclassData(encode(Align)); -} - //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// @@ -1470,11 +1459,6 @@ AssertOK(); } -void StoreInst::setAlignment(Align Alignment) { - assert(Alignment <= MaximumAlignment && - "Alignment is greater than MaximumAlignment!"); - setSubclassData(encode(Alignment)); -} //===----------------------------------------------------------------------===// // AtomicCmpXchgInst Implementation