diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 8ae478342f3..92d94f57cc7 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -6741,13 +6741,12 @@ public: }; /// A switch on a value of a builtin type. -class SwitchValueInst - : public InstructionBase { +class SwitchValueInst final + : public InstructionBaseWithTrailingOperands< + SILInstructionKind::SwitchValueInst, + SwitchValueInst, TermInst, SILSuccessor> { friend SILBuilder; - TailAllocatedOperandList<1> Operands; - SwitchValueInst(SILDebugLocation DebugLoc, SILValue Operand, SILBasicBlock *DefaultBB, ArrayRef Cases, ArrayRef BBs); @@ -6759,16 +6758,15 @@ class SwitchValueInst // destinations for each case, ending with the default destination if // present. - OperandValueArrayRef getCaseBuf() const { - return Operands.getDynamicValuesAsArray(); + return OperandValueArrayRef(getAllOperands().slice(1)); } SILSuccessor *getSuccessorBuf() { - return reinterpret_cast(Operands.asArray().end()); + return getTrailingObjects(); } const SILSuccessor *getSuccessorBuf() const { - return reinterpret_cast(Operands.asArray().end()); + return getTrailingObjects(); } static SwitchValueInst * @@ -6780,10 +6778,7 @@ public: /// Clean up tail-allocated successor records for the switch cases. ~SwitchValueInst(); - SILValue getOperand() const { return Operands[0].get(); } - - ArrayRef getAllOperands() const { return Operands.asArray(); } - MutableArrayRef getAllOperands() { return Operands.asArray(); } + SILValue getOperand() const { return getAllOperands()[0].get(); } SuccessorListTy getSuccessors() { return MutableArrayRef{getSuccessorBuf(), @@ -6791,7 +6786,7 @@ public: } unsigned getNumCases() const { - return SILInstruction::Bits.SwitchValueInst.NumCases; + return getAllOperands().size() - 1; } std::pair getCase(unsigned i) const { diff --git a/include/swift/SIL/SILNode.h b/include/swift/SIL/SILNode.h index 978a4fa96e4..e527e9399bd 100644 --- a/include/swift/SIL/SILNode.h +++ b/include/swift/SIL/SILNode.h @@ -307,10 +307,8 @@ protected: IBWTO_BITFIELD(BranchInst, TermInst, 0, : NumPadBits); // Ensure that YieldInst bitfield does not overflow. IBWTO_BITFIELD(YieldInst, TermInst, 0, : NumPadBits); - SWIFT_INLINE_BITFIELD_FULL(SwitchValueInst, TermInst, 1+32, - HasDefault : 1, - : NumPadBits, - NumCases : 32 + IBWTO_BITFIELD(SwitchValueInst, TermInst, 1, + HasDefault : 1 ); SWIFT_INLINE_BITFIELD_FULL(SwitchEnumInstBase, TermInst, 1+32, HasDefault : 1, diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp index a9d7153822c..b348d323db9 100644 --- a/lib/SIL/SILInstructions.cpp +++ b/lib/SIL/SILInstructions.cpp @@ -1262,9 +1262,8 @@ SwitchValueInst::SwitchValueInst(SILDebugLocation Loc, SILValue Operand, SILBasicBlock *DefaultBB, ArrayRef Cases, ArrayRef BBs) - : InstructionBase(Loc), Operands(this, Cases, Operand) { + : InstructionBaseWithTrailingOperands(Operand, Cases, Loc) { SILInstruction::Bits.SwitchValueInst.HasDefault = bool(DefaultBB); - SILInstruction::Bits.SwitchValueInst.NumCases = Cases.size(); // Initialize the successor array. auto *succs = getSuccessorBuf(); unsigned OperandBitWidth = 0; @@ -1324,10 +1323,9 @@ SwitchValueInst *SwitchValueInst::create( Cases.push_back(pair.first); BBs.push_back(pair.second); } - size_t bufSize = sizeof(SwitchValueInst) + - decltype(Operands)::getExtraSize(Cases.size()) + - sizeof(SILSuccessor) * numSuccessors; - void *buf = F.getModule().allocateInst(bufSize, alignof(SwitchValueInst)); + auto size = totalSizeToAlloc(numCases + 1, + numSuccessors); + auto buf = F.getModule().allocateInst(size, alignof(SwitchValueInst)); return ::new (buf) SwitchValueInst(Loc, Operand, DefaultBB, Cases, BBs); }