diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h index c9169cb601809..9ee0bacb5c258 100644 --- a/llvm/include/llvm/IR/BasicBlock.h +++ b/llvm/include/llvm/IR/BasicBlock.h @@ -564,6 +564,24 @@ class BasicBlock final : public Value, // Basic blocks are data objects also BasicBlock::iterator FromBeginIt, BasicBlock::iterator FromEndIt); + enum { + HasAddressTaken = 1 << 0, + InstrOrderValid = 1 << 1, + }; + + void setHasAddressTaken(bool B) { + if (B) + SubclassOptionalData |= HasAddressTaken; + else + SubclassOptionalData &= ~HasAddressTaken; + } + + /// Shadow Value::setValueSubclassData with a private forwarding method so + /// that any future subclasses cannot accidentally use it. + void setValueSubclassData(unsigned short D) { + Value::setValueSubclassData(D); + } + public: /// Returns a pointer to the symbol table if one exists. ValueSymbolTable *getValueSymbolTable(); @@ -669,7 +687,7 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Returns true if there are any uses of this basic block other than /// direct branches, switches, etc. to it. bool hasAddressTaken() const { - return getBasicBlockBits().BlockAddressRefCount != 0; + return SubclassOptionalData & HasAddressTaken; } /// Update all phi nodes in this basic block to refer to basic block \p New @@ -711,15 +729,13 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// Returns true if the Order field of child Instructions is valid. bool isInstrOrderValid() const { - return getBasicBlockBits().InstrOrderValid; + return SubclassOptionalData & InstrOrderValid; } /// Mark instruction ordering invalid. Done on every instruction insert. void invalidateOrders() { validateInstrOrdering(); - BasicBlockBits Bits = getBasicBlockBits(); - Bits.InstrOrderValid = false; - setBasicBlockBits(Bits); + SubclassOptionalData &= ~InstrOrderValid; } /// Renumber instructions and mark the ordering as valid. @@ -734,63 +750,6 @@ class BasicBlock final : public Value, // Basic blocks are data objects also /// each ordering to ensure that transforms have the same algorithmic /// complexity when asserts are enabled as when they are disabled. void validateInstrOrdering() const; - -private: -#if defined(_AIX) && (!defined(__GNUC__) || defined(__clang__)) -// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words -// and give the `pack` pragma push semantics. -#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)") -#define END_TWO_BYTE_PACK() _Pragma("pack(pop)") -#else -#define BEGIN_TWO_BYTE_PACK() -#define END_TWO_BYTE_PACK() -#endif - - BEGIN_TWO_BYTE_PACK() - /// Bitfield to help interpret the bits in Value::SubclassData. - struct BasicBlockBits { - unsigned short BlockAddressRefCount : 15; - unsigned short InstrOrderValid : 1; - }; - END_TWO_BYTE_PACK() - -#undef BEGIN_TWO_BYTE_PACK -#undef END_TWO_BYTE_PACK - - /// Safely reinterpret the subclass data bits to a more useful form. - BasicBlockBits getBasicBlockBits() const { - static_assert(sizeof(BasicBlockBits) == sizeof(unsigned short), - "too many bits for Value::SubclassData"); - unsigned short ValueData = getSubclassDataFromValue(); - BasicBlockBits AsBits; - memcpy(&AsBits, &ValueData, sizeof(AsBits)); - return AsBits; - } - - /// Reinterpret our subclass bits and store them back into Value. - void setBasicBlockBits(BasicBlockBits AsBits) { - unsigned short D; - memcpy(&D, &AsBits, sizeof(D)); - Value::setValueSubclassData(D); - } - - /// Increment the internal refcount of the number of BlockAddresses - /// referencing this BasicBlock by \p Amt. - /// - /// This is almost always 0, sometimes one possibly, but almost never 2, and - /// inconceivably 3 or more. - void AdjustBlockAddressRefCount(int Amt) { - BasicBlockBits Bits = getBasicBlockBits(); - Bits.BlockAddressRefCount += Amt; - setBasicBlockBits(Bits); - assert(Bits.BlockAddressRefCount < 255 && "Refcount wrap-around"); - } - - /// Shadow Value::setValueSubclassData with a private forwarding method so - /// that any future subclasses cannot accidentally use it. - void setValueSubclassData(unsigned short D) { - Value::setValueSubclassData(D); - } }; // Create wrappers for C Binding types (see CBindingWrapping.h). diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index c632b1b2dc2ab..b4c16447bc686 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -732,9 +732,7 @@ void BasicBlock::renumberInstructions() { I.Order = Order++; // Set the bit to indicate that the instruction order valid and cached. - BasicBlockBits Bits = getBasicBlockBits(); - Bits.InstrOrderValid = true; - setBasicBlockBits(Bits); + SubclassOptionalData |= InstrOrderValid; NumInstrRenumberings++; } diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 49107a421149e..d7c847e541052 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1911,7 +1911,7 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) { BlockAddress::BlockAddress(Type *Ty, BasicBlock *BB) : Constant(Ty, Value::BlockAddressVal, AllocMarker) { setOperand(0, BB); - BB->AdjustBlockAddressRefCount(1); + BB->setHasAddressTaken(true); } BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { @@ -1926,7 +1926,7 @@ BlockAddress *BlockAddress::lookup(const BasicBlock *BB) { /// Remove the constant from the constant table. void BlockAddress::destroyConstantImpl() { getType()->getContext().pImpl->BlockAddresses.erase(getBasicBlock()); - getBasicBlock()->AdjustBlockAddressRefCount(-1); + getBasicBlock()->setHasAddressTaken(false); } Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) { @@ -1939,14 +1939,14 @@ Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) { if (NewBA) return NewBA; - getBasicBlock()->AdjustBlockAddressRefCount(-1); + getBasicBlock()->setHasAddressTaken(false); // Remove the old entry, this can't cause the map to rehash (just a // tombstone will get added). getContext().pImpl->BlockAddresses.erase(getBasicBlock()); NewBA = this; setOperand(0, NewBB); - getBasicBlock()->AdjustBlockAddressRefCount(1); + getBasicBlock()->setHasAddressTaken(true); // If we just want to keep the existing value, then return null. // Callers know that this means we shouldn't delete this value.