2929#include < optional>
3030#include < string>
3131#include < utility>
32- #include < variant>
3332#include < vector>
3433
3534namespace llvm {
@@ -532,63 +531,83 @@ class MCCFIInstruction {
532531 OpValOffset,
533532 };
534533
535- // Held in ExtraFields for most common OpTypes, exceptions follow.
536- struct CommonFields {
537- unsigned Register = std::numeric_limits<unsigned >::max();
538- int64_t Offset = 0 ;
539- unsigned Register2 = std::numeric_limits<unsigned >::max();
540- unsigned AddressSpace = 0 ;
541- };
542- // Held in ExtraFields when OpEscape.
543- struct EscapeFields {
544- std::vector<char > Values;
545- std::string Comment;
546- };
547- // Held in ExtraFields when OpLabel.
548- struct LabelFields {
549- MCSymbol *CfiLabel = nullptr ;
550- };
551-
552534private:
553535 MCSymbol *Label;
554- std::variant<CommonFields, EscapeFields, LabelFields> ExtraFields;
536+ union {
537+ struct {
538+ unsigned Register;
539+ int64_t Offset;
540+ } RI;
541+ struct {
542+ unsigned Register;
543+ int64_t Offset;
544+ unsigned AddressSpace;
545+ } RIA;
546+ struct {
547+ unsigned Register;
548+ unsigned Register2;
549+ } RR;
550+ MCSymbol *CfiLabel;
551+ } U;
555552 OpType Operation;
556553 SMLoc Loc;
554+ std::vector<char > Values;
555+ std::string Comment;
557556
558- template <class FieldsType >
559- MCCFIInstruction (OpType Op, MCSymbol *L, FieldsType &&EF, SMLoc Loc)
560- : Label(L), ExtraFields(std::forward<FieldsType>(EF)), Operation(Op),
561- Loc(Loc) {}
557+ MCCFIInstruction (OpType Op, MCSymbol *L, unsigned R, int64_t O, SMLoc Loc,
558+ StringRef V = " " , StringRef Comment = " " )
559+ : Label(L), Operation(Op), Loc(Loc), Values(V.begin(), V.end()),
560+ Comment (Comment) {
561+ assert (Op != OpRegister && Op != OpLLVMDefAspaceCfa);
562+ U.RI = {R, O};
563+ }
564+ MCCFIInstruction (OpType Op, MCSymbol *L, unsigned R1, unsigned R2, SMLoc Loc)
565+ : Label(L), Operation(Op), Loc(Loc) {
566+ assert (Op == OpRegister);
567+ U.RR = {R1, R2};
568+ }
569+ MCCFIInstruction (OpType Op, MCSymbol *L, unsigned R, int64_t O, unsigned AS,
570+ SMLoc Loc)
571+ : Label(L), Operation(Op), Loc(Loc) {
572+ assert (Op == OpLLVMDefAspaceCfa);
573+ U.RIA = {R, O, AS};
574+ }
575+
576+ MCCFIInstruction (OpType Op, MCSymbol *L, MCSymbol *CfiLabel, SMLoc Loc)
577+ : Label(L), Operation(Op), Loc(Loc) {
578+ assert (Op == OpLabel);
579+ U.CfiLabel = CfiLabel;
580+ }
562581
563582public:
564583 // / .cfi_def_cfa defines a rule for computing CFA as: take address from
565584 // / Register and add Offset to it.
566585 static MCCFIInstruction cfiDefCfa (MCSymbol *L, unsigned Register,
567586 int64_t Offset, SMLoc Loc = {}) {
568- return { OpDefCfa, L, CommonFields{ Register, Offset} , Loc} ;
587+ return MCCFIInstruction ( OpDefCfa, L, Register, Offset, Loc) ;
569588 }
570589
571590 // / .cfi_def_cfa_register modifies a rule for computing CFA. From now
572591 // / on Register will be used instead of the old one. Offset remains the same.
573592 static MCCFIInstruction createDefCfaRegister (MCSymbol *L, unsigned Register,
574593 SMLoc Loc = {}) {
575- return { OpDefCfaRegister, L, CommonFields{ Register}, Loc} ;
594+ return MCCFIInstruction ( OpDefCfaRegister, L, Register, INT64_C ( 0 ), Loc) ;
576595 }
577596
578597 // / .cfi_def_cfa_offset modifies a rule for computing CFA. Register
579598 // / remains the same, but offset is new. Note that it is the absolute offset
580599 // / that will be added to a defined register to the compute CFA address.
581600 static MCCFIInstruction cfiDefCfaOffset (MCSymbol *L, int64_t Offset,
582601 SMLoc Loc = {}) {
583- return { OpDefCfaOffset, L, CommonFields{ 0 , Offset} , Loc} ;
602+ return MCCFIInstruction ( OpDefCfaOffset, L, 0 , Offset, Loc) ;
584603 }
585604
586605 // / .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
587606 // / Offset is a relative value that is added/subtracted from the previous
588607 // / offset.
589608 static MCCFIInstruction createAdjustCfaOffset (MCSymbol *L, int64_t Adjustment,
590609 SMLoc Loc = {}) {
591- return { OpAdjustCfaOffset, L, CommonFields{ 0 , Adjustment} , Loc} ;
610+ return MCCFIInstruction ( OpAdjustCfaOffset, L, 0 , Adjustment, Loc) ;
592611 }
593612
594613 // FIXME: Update the remaining docs to use the new proposal wording.
@@ -599,153 +618,151 @@ class MCCFIInstruction {
599618 int64_t Offset,
600619 unsigned AddressSpace,
601620 SMLoc Loc) {
602- return { OpLLVMDefAspaceCfa, L,
603- CommonFields{Register, Offset, 0 , AddressSpace} , Loc} ;
621+ return MCCFIInstruction ( OpLLVMDefAspaceCfa, L, Register, Offset ,
622+ AddressSpace, Loc) ;
604623 }
605624
606625 // / .cfi_offset Previous value of Register is saved at offset Offset
607626 // / from CFA.
608627 static MCCFIInstruction createOffset (MCSymbol *L, unsigned Register,
609628 int64_t Offset, SMLoc Loc = {}) {
610- return { OpOffset, L, CommonFields{ Register, Offset} , Loc} ;
629+ return MCCFIInstruction ( OpOffset, L, Register, Offset, Loc) ;
611630 }
612631
613632 // / .cfi_rel_offset Previous value of Register is saved at offset
614633 // / Offset from the current CFA register. This is transformed to .cfi_offset
615634 // / using the known displacement of the CFA register from the CFA.
616635 static MCCFIInstruction createRelOffset (MCSymbol *L, unsigned Register,
617636 int64_t Offset, SMLoc Loc = {}) {
618- return { OpRelOffset, L, CommonFields{ Register, Offset} , Loc} ;
637+ return MCCFIInstruction ( OpRelOffset, L, Register, Offset, Loc) ;
619638 }
620639
621640 // / .cfi_register Previous value of Register1 is saved in
622641 // / register Register2.
623642 static MCCFIInstruction createRegister (MCSymbol *L, unsigned Register1,
624643 unsigned Register2, SMLoc Loc = {}) {
625- return { OpRegister, L, CommonFields{ Register1, 0 , Register2} , Loc} ;
644+ return MCCFIInstruction ( OpRegister, L, Register1, Register2, Loc) ;
626645 }
627646
628647 // / .cfi_window_save SPARC register window is saved.
629648 static MCCFIInstruction createWindowSave (MCSymbol *L, SMLoc Loc = {}) {
630- return { OpWindowSave, L, CommonFields{}, Loc} ;
649+ return MCCFIInstruction ( OpWindowSave, L, 0 , INT64_C ( 0 ), Loc) ;
631650 }
632651
633652 // / .cfi_negate_ra_state AArch64 negate RA state.
634653 static MCCFIInstruction createNegateRAState (MCSymbol *L, SMLoc Loc = {}) {
635- return { OpNegateRAState, L, CommonFields{}, Loc} ;
654+ return MCCFIInstruction ( OpNegateRAState, L, 0 , INT64_C ( 0 ), Loc) ;
636655 }
637656
638657 // / .cfi_negate_ra_state_with_pc AArch64 negate RA state with PC.
639658 static MCCFIInstruction createNegateRAStateWithPC (MCSymbol *L,
640659 SMLoc Loc = {}) {
641- return { OpNegateRAStateWithPC, L, CommonFields{}, Loc} ;
660+ return MCCFIInstruction ( OpNegateRAStateWithPC, L, 0 , INT64_C ( 0 ), Loc) ;
642661 }
643662
644663 // / .cfi_restore says that the rule for Register is now the same as it
645664 // / was at the beginning of the function, after all initial instructions added
646665 // / by .cfi_startproc were executed.
647666 static MCCFIInstruction createRestore (MCSymbol *L, unsigned Register,
648667 SMLoc Loc = {}) {
649- return { OpRestore, L, CommonFields{ Register}, Loc} ;
668+ return MCCFIInstruction ( OpRestore, L, Register, INT64_C ( 0 ), Loc) ;
650669 }
651670
652671 // / .cfi_undefined From now on the previous value of Register can't be
653672 // / restored anymore.
654673 static MCCFIInstruction createUndefined (MCSymbol *L, unsigned Register,
655674 SMLoc Loc = {}) {
656- return { OpUndefined, L, CommonFields{ Register}, Loc} ;
675+ return MCCFIInstruction ( OpUndefined, L, Register, INT64_C ( 0 ), Loc) ;
657676 }
658677
659678 // / .cfi_same_value Current value of Register is the same as in the
660679 // / previous frame. I.e., no restoration is needed.
661680 static MCCFIInstruction createSameValue (MCSymbol *L, unsigned Register,
662681 SMLoc Loc = {}) {
663- return { OpSameValue, L, CommonFields{ Register}, Loc} ;
682+ return MCCFIInstruction ( OpSameValue, L, Register, INT64_C ( 0 ), Loc) ;
664683 }
665684
666685 // / .cfi_remember_state Save all current rules for all registers.
667686 static MCCFIInstruction createRememberState (MCSymbol *L, SMLoc Loc = {}) {
668- return { OpRememberState, L, CommonFields{}, Loc} ;
687+ return MCCFIInstruction ( OpRememberState, L, 0 , INT64_C ( 0 ), Loc) ;
669688 }
670689
671690 // / .cfi_restore_state Restore the previously saved state.
672691 static MCCFIInstruction createRestoreState (MCSymbol *L, SMLoc Loc = {}) {
673- return { OpRestoreState, L, CommonFields{}, Loc} ;
692+ return MCCFIInstruction ( OpRestoreState, L, 0 , INT64_C ( 0 ), Loc) ;
674693 }
675694
676695 // / .cfi_escape Allows the user to add arbitrary bytes to the unwind
677696 // / info.
678697 static MCCFIInstruction createEscape (MCSymbol *L, StringRef Vals,
679698 SMLoc Loc = {}, StringRef Comment = " " ) {
680- return {OpEscape, L,
681- EscapeFields{std::vector<char >(Vals.begin (), Vals.end ()),
682- Comment.str ()},
683- Loc};
699+ return MCCFIInstruction (OpEscape, L, 0 , 0 , Loc, Vals, Comment);
684700 }
685701
686702 // / A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
687703 static MCCFIInstruction createGnuArgsSize (MCSymbol *L, int64_t Size,
688704 SMLoc Loc = {}) {
689- return { OpGnuArgsSize, L, CommonFields{ 0 , Size} , Loc} ;
705+ return MCCFIInstruction ( OpGnuArgsSize, L, 0 , Size, Loc) ;
690706 }
691707
692708 static MCCFIInstruction createLabel (MCSymbol *L, MCSymbol *CfiLabel,
693709 SMLoc Loc) {
694- return { OpLabel, L, LabelFields{ CfiLabel} , Loc} ;
710+ return MCCFIInstruction ( OpLabel, L, CfiLabel, Loc) ;
695711 }
696712
697713 // / .cfi_val_offset Previous value of Register is offset Offset from the
698714 // / current CFA register.
699715 static MCCFIInstruction createValOffset (MCSymbol *L, unsigned Register,
700716 int64_t Offset, SMLoc Loc = {}) {
701- return { OpValOffset, L, CommonFields{ Register, Offset} , Loc} ;
717+ return MCCFIInstruction ( OpValOffset, L, Register, Offset, Loc) ;
702718 }
703719
704720 OpType getOperation () const { return Operation; }
705721 MCSymbol *getLabel () const { return Label; }
706722
707723 unsigned getRegister () const {
724+ if (Operation == OpRegister)
725+ return U.RR .Register ;
726+ if (Operation == OpLLVMDefAspaceCfa)
727+ return U.RIA .Register ;
708728 assert (Operation == OpDefCfa || Operation == OpOffset ||
709729 Operation == OpRestore || Operation == OpUndefined ||
710730 Operation == OpSameValue || Operation == OpDefCfaRegister ||
711- Operation == OpRelOffset || Operation == OpValOffset ||
712- Operation == OpRegister || Operation == OpLLVMDefAspaceCfa);
713- return std::get<CommonFields>(ExtraFields).Register ;
731+ Operation == OpRelOffset || Operation == OpValOffset);
732+ return U.RI .Register ;
714733 }
715734
716735 unsigned getRegister2 () const {
717736 assert (Operation == OpRegister);
718- return std::get<CommonFields>(ExtraFields) .Register2 ;
737+ return U. RR .Register2 ;
719738 }
720739
721740 unsigned getAddressSpace () const {
722741 assert (Operation == OpLLVMDefAspaceCfa);
723- return std::get<CommonFields>(ExtraFields) .AddressSpace ;
742+ return U. RIA .AddressSpace ;
724743 }
725744
726745 int64_t getOffset () const {
746+ if (Operation == OpLLVMDefAspaceCfa)
747+ return U.RIA .Offset ;
727748 assert (Operation == OpDefCfa || Operation == OpOffset ||
728749 Operation == OpRelOffset || Operation == OpDefCfaOffset ||
729750 Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize ||
730- Operation == OpValOffset || Operation == OpLLVMDefAspaceCfa );
731- return std::get<CommonFields>(ExtraFields) .Offset ;
751+ Operation == OpValOffset);
752+ return U. RI .Offset ;
732753 }
733754
734755 MCSymbol *getCfiLabel () const {
735756 assert (Operation == OpLabel);
736- return std::get<LabelFields>(ExtraFields) .CfiLabel ;
757+ return U .CfiLabel ;
737758 }
738759
739760 StringRef getValues () const {
740761 assert (Operation == OpEscape);
741- auto &Values = std::get<EscapeFields>(ExtraFields).Values ;
742762 return StringRef (&Values[0 ], Values.size ());
743763 }
744764
745- StringRef getComment () const {
746- assert (Operation == OpEscape);
747- return std::get<EscapeFields>(ExtraFields).Comment ;
748- }
765+ StringRef getComment () const { return Comment; }
749766 SMLoc getLoc () const { return Loc; }
750767};
751768
0 commit comments