diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -121,16 +121,21 @@ // Operands are allocated by an ArrayRecycler. MachineOperand *Operands = nullptr; // Pointer to the first operand. - uint32_t Flags = 0; // Various bits of additional - // information about machine - // instruction. - uint16_t NumOperands = 0; // Number of operands on instruction. - uint8_t AsmPrinterFlags = 0; // Various bits of information used by - // the AsmPrinter to emit helpful - // comments. This is *not* semantic - // information. Do not use this for - // anything other than to convey comment - // information to AsmPrinter. + +#define LLVM_MID_NUMOPERANDS_BITS 24 +#define LLVM_MID_FLAGS_BITS 24 +#define LLVM_MID_ASMPRINTERFLAGS_BITS 8 + LLVM_PACKED(struct MachineInstrDetail { + /// Number of operands on instruction. + uint32_t NumOperands : LLVM_MID_NUMOPERANDS_BITS; + /// Various bits of additional information about the machine instruction. + uint32_t Flags : LLVM_MID_FLAGS_BITS; + /// Various bits of information used by the AsmPrinter to emit helpful + /// comments. This is *not* semantic information. Do not use this for + /// anything other than to convey comment information to AsmPrinter. + uint8_t AsmPrinterFlags : LLVM_MID_ASMPRINTERFLAGS_BITS; + }) + Detail = {0, 0, 0}; // OperandCapacity has uint8_t size, so it should be next to AsmPrinterFlags // to properly pack. @@ -335,50 +340,50 @@ } /// Return the asm printer flags bitvector. - uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; } + uint8_t getAsmPrinterFlags() const { return Detail.AsmPrinterFlags; } /// Clear the AsmPrinter bitvector. - void clearAsmPrinterFlags() { AsmPrinterFlags = 0; } + void clearAsmPrinterFlags() { Detail.AsmPrinterFlags = 0; } /// Return whether an AsmPrinter flag is set. bool getAsmPrinterFlag(CommentFlag Flag) const { - return AsmPrinterFlags & Flag; + return Detail.AsmPrinterFlags & Flag; } /// Set a flag for the AsmPrinter. - void setAsmPrinterFlag(uint8_t Flag) { - AsmPrinterFlags |= Flag; - } + void setAsmPrinterFlag(uint8_t Flag) { Detail.AsmPrinterFlags |= Flag; } /// Clear specific AsmPrinter flags. void clearAsmPrinterFlag(CommentFlag Flag) { - AsmPrinterFlags &= ~Flag; + Detail.AsmPrinterFlags &= ~Flag; } /// Return the MI flags bitvector. - uint32_t getFlags() const { - return Flags; - } + uint32_t getFlags() const { return Detail.Flags; } /// Return whether an MI flag is set. - bool getFlag(MIFlag Flag) const { - return Flags & Flag; - } + bool getFlag(MIFlag Flag) const { return Detail.Flags & Flag; } /// Set a MI flag. void setFlag(MIFlag Flag) { - Flags |= (uint32_t)Flag; + assert(unsigned(Flag) <= ((1u << LLVM_MII_FLAGS_BITS) - 1) && + "set not in desirable range?"); + Detail.Flags |= (uint32_t)Flag; } void setFlags(unsigned flags) { + assert(flags <= ((1u << LLVM_MII_FLAGS_BITS) - 1) && + "multi-set not in desirable range?"); // Filter out the automatically maintained flags. unsigned Mask = BundledPred | BundledSucc; - Flags = (Flags & Mask) | (flags & ~Mask); + Detail.Flags = (Detail.Flags & Mask) | (flags & ~Mask); } /// clearFlag - Clear a MI flag. void clearFlag(MIFlag Flag) { - Flags &= ~((uint32_t)Flag); + assert(unsigned(Flag) <= ((1u << LLVM_MII_FLAGS_BITS) - 1) && + "clear not in desirable range?"); + Detail.Flags &= ~((uint32_t)Flag); } /// Return true if MI is in a bundle (but not the first MI in a bundle). @@ -523,7 +528,7 @@ unsigned getOpcode() const { return MCID->Opcode; } /// Retuns the total number of operands. - unsigned getNumOperands() const { return NumOperands; } + unsigned getNumOperands() const { return Detail.NumOperands; } /// Returns the total number of operands which are debug locations. unsigned getNumDebugOperands() const { @@ -640,10 +645,12 @@ using const_mop_iterator = const MachineOperand *; mop_iterator operands_begin() { return Operands; } - mop_iterator operands_end() { return Operands + NumOperands; } + mop_iterator operands_end() { return Operands + Detail.NumOperands; } const_mop_iterator operands_begin() const { return Operands; } - const_mop_iterator operands_end() const { return Operands + NumOperands; } + const_mop_iterator operands_end() const { + return Operands + Detail.NumOperands; + } iterator_range operands() { return make_range(operands_begin(), operands_end()); diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -134,7 +134,7 @@ } // Copy all the sensible flags. - setFlags(MI.Flags); + setFlags(MI.Detail.Flags); } void MachineInstr::moveBefore(MachineInstr *MovePos) { @@ -192,11 +192,12 @@ /// an explicit operand it is added at the end of the explicit operand list /// (before the first implicit operand). void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { - assert(NumOperands < USHRT_MAX && "Cannot add more operands."); + assert(NumOperands < ((1u << LLVM_MID_NUMOPERANDS_BITS) - 1) && + "Cannot add more operands."); assert(MCID && "Cannot add operands before providing an instr descriptor"); // Check if we're adding one of our existing operands. - if (&Op >= Operands && &Op < Operands + NumOperands) { + if (&Op >= Operands && &Op < Operands + Detail.NumOperands) { // This is unusual: MI->addOperand(MI->getOperand(i)). // If adding Op requires reallocating or moving existing operands around, // the Op reference could go stale. Support it by copying Op. @@ -242,10 +243,10 @@ } // Move the operands following the insertion point. - if (OpNo != NumOperands) - moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, - MRI); - ++NumOperands; + if (OpNo != Detail.NumOperands) + moveOperands(Operands + OpNo + 1, OldOperands + OpNo, + Detail.NumOperands - OpNo, MRI); + ++Detail.NumOperands; // Deallocate the old operand array. if (OldOperands != Operands && OldOperands) @@ -303,9 +304,9 @@ // MachineOperand having a trivial destructor anyway, and adding a call here // wouldn't make it 'destructor-correct'. - if (unsigned N = NumOperands - 1 - OpNo) + if (unsigned N = Detail.NumOperands - 1 - OpNo) moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); - --NumOperands; + --Detail.NumOperands; } void MachineInstr::setExtraInfo(MachineFunction &MF, @@ -582,7 +583,7 @@ } void MachineInstr::copyIRFlags(const Instruction &I) { - Flags = copyFlagsFromInstruction(I); + Detail.Flags = copyFlagsFromInstruction(I); } bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const { @@ -947,7 +948,7 @@ OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); else // Otherwise, just check the current operands. - for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) + for (unsigned i = 0, e = Detail.NumOperands; i < e && CurRC; ++i) CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); return CurRC; }