Skip to content

Commit f3f4ad9

Browse files
nikicGeorgeARM
authored andcommitted
[IR] Replace blockaddress refcount with single flag (llvm#138239)
BasicBlock currently has a blockaddress refcount. However, blockaddresses are uniqued, which means that there can only be a single blockaddress for a given BasicBlock. Prior to llvm#137958 there were some edge case exceptions to this, but now it always holds. As such, replace the refcount with a single flag. As we're now just tracking two bits, I've dropped the BasicBlockBits structure, as I found it more annoying than useful (esp with the weird AIX workarounds). Instead handle the subclass data the same way we do in Operators.
1 parent 8380a65 commit f3f4ad9

File tree

3 files changed

+26
-69
lines changed

3 files changed

+26
-69
lines changed

llvm/include/llvm/IR/BasicBlock.h

Lines changed: 21 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,24 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
564564
BasicBlock::iterator FromBeginIt,
565565
BasicBlock::iterator FromEndIt);
566566

567+
enum {
568+
HasAddressTaken = 1 << 0,
569+
InstrOrderValid = 1 << 1,
570+
};
571+
572+
void setHasAddressTaken(bool B) {
573+
if (B)
574+
SubclassOptionalData |= HasAddressTaken;
575+
else
576+
SubclassOptionalData &= ~HasAddressTaken;
577+
}
578+
579+
/// Shadow Value::setValueSubclassData with a private forwarding method so
580+
/// that any future subclasses cannot accidentally use it.
581+
void setValueSubclassData(unsigned short D) {
582+
Value::setValueSubclassData(D);
583+
}
584+
567585
public:
568586
/// Returns a pointer to the symbol table if one exists.
569587
ValueSymbolTable *getValueSymbolTable();
@@ -669,7 +687,7 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
669687
/// Returns true if there are any uses of this basic block other than
670688
/// direct branches, switches, etc. to it.
671689
bool hasAddressTaken() const {
672-
return getBasicBlockBits().BlockAddressRefCount != 0;
690+
return SubclassOptionalData & HasAddressTaken;
673691
}
674692

675693
/// 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
711729

712730
/// Returns true if the Order field of child Instructions is valid.
713731
bool isInstrOrderValid() const {
714-
return getBasicBlockBits().InstrOrderValid;
732+
return SubclassOptionalData & InstrOrderValid;
715733
}
716734

717735
/// Mark instruction ordering invalid. Done on every instruction insert.
718736
void invalidateOrders() {
719737
validateInstrOrdering();
720-
BasicBlockBits Bits = getBasicBlockBits();
721-
Bits.InstrOrderValid = false;
722-
setBasicBlockBits(Bits);
738+
SubclassOptionalData &= ~InstrOrderValid;
723739
}
724740

725741
/// Renumber instructions and mark the ordering as valid.
@@ -734,63 +750,6 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
734750
/// each ordering to ensure that transforms have the same algorithmic
735751
/// complexity when asserts are enabled as when they are disabled.
736752
void validateInstrOrdering() const;
737-
738-
private:
739-
#if defined(_AIX) && (!defined(__GNUC__) || defined(__clang__))
740-
// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
741-
// and give the `pack` pragma push semantics.
742-
#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")
743-
#define END_TWO_BYTE_PACK() _Pragma("pack(pop)")
744-
#else
745-
#define BEGIN_TWO_BYTE_PACK()
746-
#define END_TWO_BYTE_PACK()
747-
#endif
748-
749-
BEGIN_TWO_BYTE_PACK()
750-
/// Bitfield to help interpret the bits in Value::SubclassData.
751-
struct BasicBlockBits {
752-
unsigned short BlockAddressRefCount : 15;
753-
unsigned short InstrOrderValid : 1;
754-
};
755-
END_TWO_BYTE_PACK()
756-
757-
#undef BEGIN_TWO_BYTE_PACK
758-
#undef END_TWO_BYTE_PACK
759-
760-
/// Safely reinterpret the subclass data bits to a more useful form.
761-
BasicBlockBits getBasicBlockBits() const {
762-
static_assert(sizeof(BasicBlockBits) == sizeof(unsigned short),
763-
"too many bits for Value::SubclassData");
764-
unsigned short ValueData = getSubclassDataFromValue();
765-
BasicBlockBits AsBits;
766-
memcpy(&AsBits, &ValueData, sizeof(AsBits));
767-
return AsBits;
768-
}
769-
770-
/// Reinterpret our subclass bits and store them back into Value.
771-
void setBasicBlockBits(BasicBlockBits AsBits) {
772-
unsigned short D;
773-
memcpy(&D, &AsBits, sizeof(D));
774-
Value::setValueSubclassData(D);
775-
}
776-
777-
/// Increment the internal refcount of the number of BlockAddresses
778-
/// referencing this BasicBlock by \p Amt.
779-
///
780-
/// This is almost always 0, sometimes one possibly, but almost never 2, and
781-
/// inconceivably 3 or more.
782-
void AdjustBlockAddressRefCount(int Amt) {
783-
BasicBlockBits Bits = getBasicBlockBits();
784-
Bits.BlockAddressRefCount += Amt;
785-
setBasicBlockBits(Bits);
786-
assert(Bits.BlockAddressRefCount < 255 && "Refcount wrap-around");
787-
}
788-
789-
/// Shadow Value::setValueSubclassData with a private forwarding method so
790-
/// that any future subclasses cannot accidentally use it.
791-
void setValueSubclassData(unsigned short D) {
792-
Value::setValueSubclassData(D);
793-
}
794753
};
795754

796755
// Create wrappers for C Binding types (see CBindingWrapping.h).

llvm/lib/IR/BasicBlock.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,9 +732,7 @@ void BasicBlock::renumberInstructions() {
732732
I.Order = Order++;
733733

734734
// Set the bit to indicate that the instruction order valid and cached.
735-
BasicBlockBits Bits = getBasicBlockBits();
736-
Bits.InstrOrderValid = true;
737-
setBasicBlockBits(Bits);
735+
SubclassOptionalData |= InstrOrderValid;
738736

739737
NumInstrRenumberings++;
740738
}

llvm/lib/IR/Constants.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,7 +1911,7 @@ BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
19111911
BlockAddress::BlockAddress(Type *Ty, BasicBlock *BB)
19121912
: Constant(Ty, Value::BlockAddressVal, AllocMarker) {
19131913
setOperand(0, BB);
1914-
BB->AdjustBlockAddressRefCount(1);
1914+
BB->setHasAddressTaken(true);
19151915
}
19161916

19171917
BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
@@ -1926,7 +1926,7 @@ BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
19261926
/// Remove the constant from the constant table.
19271927
void BlockAddress::destroyConstantImpl() {
19281928
getType()->getContext().pImpl->BlockAddresses.erase(getBasicBlock());
1929-
getBasicBlock()->AdjustBlockAddressRefCount(-1);
1929+
getBasicBlock()->setHasAddressTaken(false);
19301930
}
19311931

19321932
Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) {
@@ -1939,14 +1939,14 @@ Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) {
19391939
if (NewBA)
19401940
return NewBA;
19411941

1942-
getBasicBlock()->AdjustBlockAddressRefCount(-1);
1942+
getBasicBlock()->setHasAddressTaken(false);
19431943

19441944
// Remove the old entry, this can't cause the map to rehash (just a
19451945
// tombstone will get added).
19461946
getContext().pImpl->BlockAddresses.erase(getBasicBlock());
19471947
NewBA = this;
19481948
setOperand(0, NewBB);
1949-
getBasicBlock()->AdjustBlockAddressRefCount(1);
1949+
getBasicBlock()->setHasAddressTaken(true);
19501950

19511951
// If we just want to keep the existing value, then return null.
19521952
// Callers know that this means we shouldn't delete this value.

0 commit comments

Comments
 (0)