@@ -92,9 +92,18 @@ class AArch64ExpandPseudo : public MachineFunctionPass {
92
92
bool expandCALL_BTI (MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
93
93
bool expandStoreSwiftAsyncContext (MachineBasicBlock &MBB,
94
94
MachineBasicBlock::iterator MBBI);
95
- MachineBasicBlock *
96
- expandCommitOrRestoreZASave (MachineBasicBlock &MBB,
97
- MachineBasicBlock::iterator MBBI);
95
+ struct ConditionalBlocks {
96
+ MachineBasicBlock &CondBB;
97
+ MachineBasicBlock &EndBB;
98
+ };
99
+ ConditionalBlocks expandConditionalPseudo (MachineBasicBlock &MBB,
100
+ MachineBasicBlock::iterator MBBI,
101
+ DebugLoc DL,
102
+ MachineInstrBuilder &Branch);
103
+ MachineBasicBlock *expandRestoreZASave (MachineBasicBlock &MBB,
104
+ MachineBasicBlock::iterator MBBI);
105
+ MachineBasicBlock *expandCommitZASave (MachineBasicBlock &MBB,
106
+ MachineBasicBlock::iterator MBBI);
98
107
MachineBasicBlock *expandCondSMToggle (MachineBasicBlock &MBB,
99
108
MachineBasicBlock::iterator MBBI);
100
109
};
@@ -991,72 +1000,97 @@ bool AArch64ExpandPseudo::expandStoreSwiftAsyncContext(
991
1000
return true ;
992
1001
}
993
1002
994
- static constexpr unsigned ZERO_ALL_ZA_MASK = 0b11111111 ;
995
-
996
- MachineBasicBlock *AArch64ExpandPseudo::expandCommitOrRestoreZASave (
997
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) {
998
- MachineInstr &MI = *MBBI;
999
- bool IsRestoreZA = MI.getOpcode () == AArch64::RestoreZAPseudo;
1000
- assert ((MI.getOpcode () == AArch64::RestoreZAPseudo ||
1001
- MI.getOpcode () == AArch64::CommitZASavePseudo) &&
1002
- " Expected ZA commit or restore" );
1003
+ AArch64ExpandPseudo::ConditionalBlocks
1004
+ AArch64ExpandPseudo::expandConditionalPseudo (MachineBasicBlock &MBB,
1005
+ MachineBasicBlock::iterator MBBI,
1006
+ DebugLoc DL,
1007
+ MachineInstrBuilder &Branch) {
1003
1008
assert ((std::next (MBBI) != MBB.end () ||
1004
- MI.getParent ()->successors ().begin () !=
1005
- MI.getParent ()->successors ().end ()) &&
1006
- " Unexpected unreachable in block that restores ZA" );
1007
-
1008
- // Compare TPIDR2_EL0 value against 0.
1009
- DebugLoc DL = MI.getDebugLoc ();
1010
- MachineInstrBuilder Branch =
1011
- BuildMI (MBB, MBBI, DL,
1012
- TII->get (IsRestoreZA ? AArch64::CBZX : AArch64::CBNZX))
1013
- .add (MI.getOperand (0 ));
1009
+ MBB.successors ().begin () != MBB.successors ().end ()) &&
1010
+ " Unexpected unreachable in block" );
1014
1011
1015
1012
// Split MBB and create two new blocks:
1016
- // - MBB now contains all instructions before RestoreZAPseudo .
1017
- // - SMBB contains the [Commit|RestoreZA]Pseudo instruction only.
1018
- // - EndBB contains all instructions after [Commit|RestoreZA]Pseudo .
1013
+ // - MBB now contains all instructions before the conditional pseudo .
1014
+ // - CondBB contains the conditional pseudo instruction only.
1015
+ // - EndBB contains all instructions after the conditional pseudo .
1019
1016
MachineInstr &PrevMI = *std::prev (MBBI);
1020
- MachineBasicBlock *SMBB = MBB.splitAt (PrevMI, /* UpdateLiveIns*/ true );
1021
- MachineBasicBlock *EndBB = std::next (MI.getIterator ()) == SMBB->end ()
1022
- ? *SMBB->successors ().begin ()
1023
- : SMBB->splitAt (MI, /* UpdateLiveIns*/ true );
1024
-
1025
- // Add the SMBB label to the CB[N]Z instruction & create a branch to EndBB.
1026
- Branch.addMBB (SMBB);
1017
+ MachineBasicBlock *CondBB = MBB.splitAt (PrevMI, /* UpdateLiveIns*/ true );
1018
+ MachineBasicBlock *EndBB =
1019
+ std::next (MBBI) == CondBB->end ()
1020
+ ? *CondBB->successors ().begin ()
1021
+ : CondBB->splitAt (*MBBI, /* UpdateLiveIns*/ true );
1022
+
1023
+ // Add the SMBB label to the branch instruction & create a branch to EndBB.
1024
+ Branch.addMBB (CondBB);
1027
1025
BuildMI (&MBB, DL, TII->get (AArch64::B))
1028
1026
.addMBB (EndBB);
1029
1027
MBB.addSuccessor (EndBB);
1030
1028
1029
+ // Create branch from CondBB to EndBB. Users of this helper should insert new
1030
+ // instructions at CondBB.back() -- i.e. before the branch.
1031
+ BuildMI (CondBB, DL, TII->get (AArch64::B)).addMBB (EndBB);
1032
+ return {*CondBB, *EndBB};
1033
+ }
1034
+
1035
+ MachineBasicBlock *
1036
+ AArch64ExpandPseudo::expandRestoreZASave (MachineBasicBlock &MBB,
1037
+ MachineBasicBlock::iterator MBBI) {
1038
+ MachineInstr &MI = *MBBI;
1039
+ DebugLoc DL = MI.getDebugLoc ();
1040
+
1041
+ // Compare TPIDR2_EL0 against 0. Restore ZA if TPIDR2_EL0 is zero.
1042
+ MachineInstrBuilder Branch =
1043
+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::CBZX)).add (MI.getOperand (0 ));
1044
+
1045
+ auto [CondBB, EndBB] = expandConditionalPseudo (MBB, MBBI, DL, Branch);
1031
1046
// Replace the pseudo with a call (BL).
1032
1047
MachineInstrBuilder MIB =
1033
- BuildMI (*SMBB, SMBB-> end (), DL, TII->get (AArch64::BL));
1048
+ BuildMI (CondBB, CondBB. back (), DL, TII->get (AArch64::BL));
1034
1049
// Copy operands (mainly the regmask) from the pseudo.
1035
1050
for (unsigned I = 2 ; I < MI.getNumOperands (); ++I)
1036
1051
MIB.add (MI.getOperand (I));
1052
+ // Mark the TPIDR2 block pointer (X0) as an implicit use.
1053
+ MIB.addReg (MI.getOperand (1 ).getReg (), RegState::Implicit);
1037
1054
1038
- if (IsRestoreZA) {
1039
- // Mark the TPIDR2 block pointer (X0) as an implicit use.
1040
- MIB.addReg (MI.getOperand (1 ).getReg (), RegState::Implicit);
1041
- } else /* CommitZA*/ {
1055
+ MI.eraseFromParent ();
1056
+ return &EndBB;
1057
+ }
1058
+
1059
+ static constexpr unsigned ZERO_ALL_ZA_MASK = 0b11111111 ;
1060
+
1061
+ MachineBasicBlock *
1062
+ AArch64ExpandPseudo::expandCommitZASave (MachineBasicBlock &MBB,
1063
+ MachineBasicBlock::iterator MBBI) {
1064
+ MachineInstr &MI = *MBBI;
1065
+ DebugLoc DL = MI.getDebugLoc ();
1066
+
1067
+ // Compare TPIDR2_EL0 against 0. Commit ZA if TPIDR2_EL0 is non-zero.
1068
+ MachineInstrBuilder Branch =
1069
+ BuildMI (MBB, MBBI, DL, TII->get (AArch64::CBNZX)).add (MI.getOperand (0 ));
1070
+
1071
+ auto [CondBB, EndBB] = expandConditionalPseudo (MBB, MBBI, DL, Branch);
1072
+ // Replace the pseudo with a call (BL).
1073
+ MachineInstrBuilder MIB =
1074
+ BuildMI (CondBB, CondBB.back (), DL, TII->get (AArch64::BL));
1075
+ // Copy operands (mainly the regmask) from the pseudo.
1076
+ for (unsigned I = 2 ; I < MI.getNumOperands (); ++I)
1077
+ MIB.add (MI.getOperand (I));
1078
+ // Clear TPIDR2_EL0.
1079
+ BuildMI (CondBB, CondBB.back (), DL, TII->get (AArch64::MSR))
1080
+ .addImm (AArch64SysReg::TPIDR2_EL0)
1081
+ .addReg (AArch64::XZR);
1082
+ bool ZeroZA = MI.getOperand (1 ).getImm () != 0 ;
1083
+ if (ZeroZA) {
1042
1084
[[maybe_unused]] auto *TRI =
1043
1085
MBB.getParent ()->getSubtarget ().getRegisterInfo ();
1044
- // Clear TPIDR2_EL0.
1045
- BuildMI (*SMBB, SMBB->end (), DL, TII->get (AArch64::MSR))
1046
- .addImm (AArch64SysReg::TPIDR2_EL0)
1047
- .addReg (AArch64::XZR);
1048
- bool ZeroZA = MI.getOperand (1 ).getImm () != 0 ;
1049
- if (ZeroZA) {
1050
- assert (MI.definesRegister (AArch64::ZAB0, TRI) && " should define ZA!" );
1051
- BuildMI (*SMBB, SMBB->end (), DL, TII->get (AArch64::ZERO_M))
1052
- .addImm (ZERO_ALL_ZA_MASK)
1053
- .addDef (AArch64::ZAB0, RegState::ImplicitDefine);
1054
- }
1086
+ assert (MI.definesRegister (AArch64::ZAB0, TRI) && " should define ZA!" );
1087
+ BuildMI (CondBB, CondBB.back (), DL, TII->get (AArch64::ZERO_M))
1088
+ .addImm (ZERO_ALL_ZA_MASK)
1089
+ .addDef (AArch64::ZAB0, RegState::ImplicitDefine);
1055
1090
}
1056
1091
1057
- BuildMI (SMBB, DL, TII->get (AArch64::B)).addMBB (EndBB);
1058
1092
MI.eraseFromParent ();
1059
- return EndBB;
1093
+ return & EndBB;
1060
1094
}
1061
1095
1062
1096
MachineBasicBlock *
@@ -1130,24 +1164,9 @@ AArch64ExpandPseudo::expandCondSMToggle(MachineBasicBlock &MBB,
1130
1164
MachineInstrBuilder Tbx =
1131
1165
BuildMI (MBB, MBBI, DL, TII->get (Opc)).addReg (SMReg32).addImm (0 );
1132
1166
1133
- // Split MBB and create two new blocks:
1134
- // - MBB now contains all instructions before MSRcond_pstatesvcrImm1.
1135
- // - SMBB contains the MSRcond_pstatesvcrImm1 instruction only.
1136
- // - EndBB contains all instructions after MSRcond_pstatesvcrImm1.
1137
- MachineInstr &PrevMI = *std::prev (MBBI);
1138
- MachineBasicBlock *SMBB = MBB.splitAt (PrevMI, /* UpdateLiveIns*/ true );
1139
- MachineBasicBlock *EndBB = std::next (MI.getIterator ()) == SMBB->end ()
1140
- ? *SMBB->successors ().begin ()
1141
- : SMBB->splitAt (MI, /* UpdateLiveIns*/ true );
1142
-
1143
- // Add the SMBB label to the TB[N]Z instruction & create a branch to EndBB.
1144
- Tbx.addMBB (SMBB);
1145
- BuildMI (&MBB, DL, TII->get (AArch64::B))
1146
- .addMBB (EndBB);
1147
- MBB.addSuccessor (EndBB);
1148
-
1167
+ auto [CondBB, EndBB] = expandConditionalPseudo (MBB, MBBI, DL, Tbx);
1149
1168
// Create the SMSTART/SMSTOP (MSRpstatesvcrImm1) instruction in SMBB.
1150
- MachineInstrBuilder MIB = BuildMI (*SMBB, SMBB-> begin (), MI.getDebugLoc (),
1169
+ MachineInstrBuilder MIB = BuildMI (CondBB, CondBB. back (), MI.getDebugLoc (),
1151
1170
TII->get (AArch64::MSRpstatesvcrImm1));
1152
1171
// Copy all but the second and third operands of MSRcond_pstatesvcrImm1 (as
1153
1172
// these contain the CopyFromReg for the first argument and the flag to
@@ -1157,10 +1176,8 @@ AArch64ExpandPseudo::expandCondSMToggle(MachineBasicBlock &MBB,
1157
1176
for (unsigned i = 4 ; i < MI.getNumOperands (); ++i)
1158
1177
MIB.add (MI.getOperand (i));
1159
1178
1160
- BuildMI (SMBB, DL, TII->get (AArch64::B)).addMBB (EndBB);
1161
-
1162
1179
MI.eraseFromParent ();
1163
- return EndBB;
1180
+ return & EndBB;
1164
1181
}
1165
1182
1166
1183
bool AArch64ExpandPseudo::expandMultiVecPseudo (
@@ -1674,15 +1691,21 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
1674
1691
return expandCALL_BTI (MBB, MBBI);
1675
1692
case AArch64::StoreSwiftAsyncContext:
1676
1693
return expandStoreSwiftAsyncContext (MBB, MBBI);
1694
+ case AArch64::RestoreZAPseudo:
1677
1695
case AArch64::CommitZASavePseudo:
1678
- case AArch64::RestoreZAPseudo: {
1679
- auto *NewMBB = expandCommitOrRestoreZASave (MBB, MBBI);
1680
- if (NewMBB != &MBB)
1681
- NextMBBI = MBB.end (); // The NextMBBI iterator is invalidated.
1682
- return true ;
1683
- }
1684
1696
case AArch64::MSRpstatePseudo: {
1685
- auto *NewMBB = expandCondSMToggle (MBB, MBBI);
1697
+ auto *NewMBB = [&] {
1698
+ switch (Opcode) {
1699
+ case AArch64::RestoreZAPseudo:
1700
+ return expandRestoreZASave (MBB, MBBI);
1701
+ case AArch64::CommitZASavePseudo:
1702
+ return expandCommitZASave (MBB, MBBI);
1703
+ case AArch64::MSRpstatePseudo:
1704
+ return expandCondSMToggle (MBB, MBBI);
1705
+ default :
1706
+ llvm_unreachable (" Unexpected conditional pseudo!" );
1707
+ }
1708
+ }();
1686
1709
if (NewMBB != &MBB)
1687
1710
NextMBBI = MBB.end (); // The NextMBBI iterator is invalidated.
1688
1711
return true ;
0 commit comments