@@ -1055,42 +1055,45 @@ static std::pair<bool, bool> mustSwapOperands(unsigned Pattern) {
1055
1055
}
1056
1056
}
1057
1057
1058
+ void TargetInstrInfo::getReassociateOperandIndices (
1059
+ const MachineInstr &Root, unsigned Pattern,
1060
+ std::array<unsigned , 5 > &OperandIndices) const {
1061
+ switch (Pattern) {
1062
+ case MachineCombinerPattern::REASSOC_AX_BY:
1063
+ OperandIndices = {1 , 1 , 1 , 2 , 2 };
1064
+ break ;
1065
+ case MachineCombinerPattern::REASSOC_AX_YB:
1066
+ OperandIndices = {2 , 1 , 2 , 2 , 1 };
1067
+ break ;
1068
+ case MachineCombinerPattern::REASSOC_XA_BY:
1069
+ OperandIndices = {1 , 2 , 1 , 1 , 2 };
1070
+ break ;
1071
+ case MachineCombinerPattern::REASSOC_XA_YB:
1072
+ OperandIndices = {2 , 2 , 2 , 1 , 1 };
1073
+ break ;
1074
+ default :
1075
+ llvm_unreachable (" unexpected MachineCombinerPattern" );
1076
+ }
1077
+ }
1078
+
1058
1079
// / Attempt the reassociation transformation to reduce critical path length.
1059
1080
// / See the above comments before getMachineCombinerPatterns().
1060
1081
void TargetInstrInfo::reassociateOps (
1061
1082
MachineInstr &Root, MachineInstr &Prev, unsigned Pattern,
1062
1083
SmallVectorImpl<MachineInstr *> &InsInstrs,
1063
1084
SmallVectorImpl<MachineInstr *> &DelInstrs,
1085
+ ArrayRef<unsigned > OperandIndices,
1064
1086
DenseMap<unsigned , unsigned > &InstrIdxForVirtReg) const {
1065
1087
MachineFunction *MF = Root.getMF ();
1066
1088
MachineRegisterInfo &MRI = MF->getRegInfo ();
1067
1089
const TargetInstrInfo *TII = MF->getSubtarget ().getInstrInfo ();
1068
1090
const TargetRegisterInfo *TRI = MF->getSubtarget ().getRegisterInfo ();
1069
1091
const TargetRegisterClass *RC = Root.getRegClassConstraint (0 , TII, TRI);
1070
1092
1071
- // This array encodes the operand index for each parameter because the
1072
- // operands may be commuted. Each row corresponds to a pattern value,
1073
- // and each column specifies the index of A, B, X, Y.
1074
- unsigned OpIdx[4 ][4 ] = {
1075
- { 1 , 1 , 2 , 2 },
1076
- { 1 , 2 , 2 , 1 },
1077
- { 2 , 1 , 1 , 2 },
1078
- { 2 , 2 , 1 , 1 }
1079
- };
1080
-
1081
- int Row;
1082
- switch (Pattern) {
1083
- case MachineCombinerPattern::REASSOC_AX_BY: Row = 0 ; break ;
1084
- case MachineCombinerPattern::REASSOC_AX_YB: Row = 1 ; break ;
1085
- case MachineCombinerPattern::REASSOC_XA_BY: Row = 2 ; break ;
1086
- case MachineCombinerPattern::REASSOC_XA_YB: Row = 3 ; break ;
1087
- default : llvm_unreachable (" unexpected MachineCombinerPattern" );
1088
- }
1089
-
1090
- MachineOperand &OpA = Prev.getOperand (OpIdx[Row][0 ]);
1091
- MachineOperand &OpB = Root.getOperand (OpIdx[Row][1 ]);
1092
- MachineOperand &OpX = Prev.getOperand (OpIdx[Row][2 ]);
1093
- MachineOperand &OpY = Root.getOperand (OpIdx[Row][3 ]);
1093
+ MachineOperand &OpA = Prev.getOperand (OperandIndices[1 ]);
1094
+ MachineOperand &OpB = Root.getOperand (OperandIndices[2 ]);
1095
+ MachineOperand &OpX = Prev.getOperand (OperandIndices[3 ]);
1096
+ MachineOperand &OpY = Root.getOperand (OperandIndices[4 ]);
1094
1097
MachineOperand &OpC = Root.getOperand (0 );
1095
1098
1096
1099
Register RegA = OpA.getReg ();
@@ -1129,21 +1132,83 @@ void TargetInstrInfo::reassociateOps(
1129
1132
std::swap (KillX, KillY);
1130
1133
}
1131
1134
1135
+ unsigned PrevFirstOpIdx, PrevSecondOpIdx;
1136
+ unsigned RootFirstOpIdx, RootSecondOpIdx;
1137
+ switch (Pattern) {
1138
+ case MachineCombinerPattern::REASSOC_AX_BY:
1139
+ PrevFirstOpIdx = OperandIndices[1 ];
1140
+ PrevSecondOpIdx = OperandIndices[3 ];
1141
+ RootFirstOpIdx = OperandIndices[2 ];
1142
+ RootSecondOpIdx = OperandIndices[4 ];
1143
+ break ;
1144
+ case MachineCombinerPattern::REASSOC_AX_YB:
1145
+ PrevFirstOpIdx = OperandIndices[1 ];
1146
+ PrevSecondOpIdx = OperandIndices[3 ];
1147
+ RootFirstOpIdx = OperandIndices[4 ];
1148
+ RootSecondOpIdx = OperandIndices[2 ];
1149
+ break ;
1150
+ case MachineCombinerPattern::REASSOC_XA_BY:
1151
+ PrevFirstOpIdx = OperandIndices[3 ];
1152
+ PrevSecondOpIdx = OperandIndices[1 ];
1153
+ RootFirstOpIdx = OperandIndices[2 ];
1154
+ RootSecondOpIdx = OperandIndices[4 ];
1155
+ break ;
1156
+ case MachineCombinerPattern::REASSOC_XA_YB:
1157
+ PrevFirstOpIdx = OperandIndices[3 ];
1158
+ PrevSecondOpIdx = OperandIndices[1 ];
1159
+ RootFirstOpIdx = OperandIndices[4 ];
1160
+ RootSecondOpIdx = OperandIndices[2 ];
1161
+ break ;
1162
+ default :
1163
+ llvm_unreachable (" unexpected MachineCombinerPattern" );
1164
+ }
1165
+
1166
+ // Basically BuildMI but doesn't add implicit operands by default.
1167
+ auto buildMINoImplicit = [](MachineFunction &MF, const MIMetadata &MIMD,
1168
+ const MCInstrDesc &MCID, Register DestReg) {
1169
+ return MachineInstrBuilder (
1170
+ MF, MF.CreateMachineInstr (MCID, MIMD.getDL (), /* NoImpl=*/ true ))
1171
+ .setPCSections (MIMD.getPCSections ())
1172
+ .addReg (DestReg, RegState::Define);
1173
+ };
1174
+
1132
1175
// Create new instructions for insertion.
1133
1176
MachineInstrBuilder MIB1 =
1134
- BuildMI (*MF, MIMetadata (Prev), TII->get (NewPrevOpc), NewVR)
1135
- .addReg (RegX, getKillRegState (KillX))
1136
- .addReg (RegY, getKillRegState (KillY));
1177
+ buildMINoImplicit (*MF, MIMetadata (Prev), TII->get (NewPrevOpc), NewVR);
1178
+ for (const auto &MO : Prev.explicit_operands ()) {
1179
+ unsigned Idx = MO.getOperandNo ();
1180
+ // Skip the result operand we'd already added.
1181
+ if (Idx == 0 )
1182
+ continue ;
1183
+ if (Idx == PrevFirstOpIdx)
1184
+ MIB1.addReg (RegX, getKillRegState (KillX));
1185
+ else if (Idx == PrevSecondOpIdx)
1186
+ MIB1.addReg (RegY, getKillRegState (KillY));
1187
+ else
1188
+ MIB1.add (MO);
1189
+ }
1190
+ MIB1.copyImplicitOps (Prev);
1137
1191
1138
1192
if (SwapRootOperands) {
1139
1193
std::swap (RegA, NewVR);
1140
1194
std::swap (KillA, KillNewVR);
1141
1195
}
1142
1196
1143
1197
MachineInstrBuilder MIB2 =
1144
- BuildMI (*MF, MIMetadata (Root), TII->get (NewRootOpc), RegC)
1145
- .addReg (RegA, getKillRegState (KillA))
1146
- .addReg (NewVR, getKillRegState (KillNewVR));
1198
+ buildMINoImplicit (*MF, MIMetadata (Root), TII->get (NewRootOpc), RegC);
1199
+ for (const auto &MO : Root.explicit_operands ()) {
1200
+ unsigned Idx = MO.getOperandNo ();
1201
+ // Skip the result operand.
1202
+ if (Idx == 0 )
1203
+ continue ;
1204
+ if (Idx == RootFirstOpIdx)
1205
+ MIB2 = MIB2.addReg (RegA, getKillRegState (KillA));
1206
+ else if (Idx == RootSecondOpIdx)
1207
+ MIB2 = MIB2.addReg (NewVR, getKillRegState (KillNewVR));
1208
+ else
1209
+ MIB2 = MIB2.add (MO);
1210
+ }
1211
+ MIB2.copyImplicitOps (Root);
1147
1212
1148
1213
// Propagate FP flags from the original instructions.
1149
1214
// But clear poison-generating flags because those may not be valid now.
@@ -1187,25 +1252,17 @@ void TargetInstrInfo::genAlternativeCodeSequence(
1187
1252
MachineRegisterInfo &MRI = Root.getMF ()->getRegInfo ();
1188
1253
1189
1254
// Select the previous instruction in the sequence based on the input pattern.
1190
- MachineInstr *Prev = nullptr ;
1191
- switch (Pattern) {
1192
- case MachineCombinerPattern::REASSOC_AX_BY:
1193
- case MachineCombinerPattern::REASSOC_XA_BY:
1194
- Prev = MRI.getUniqueVRegDef (Root.getOperand (1 ).getReg ());
1195
- break ;
1196
- case MachineCombinerPattern::REASSOC_AX_YB:
1197
- case MachineCombinerPattern::REASSOC_XA_YB:
1198
- Prev = MRI.getUniqueVRegDef (Root.getOperand (2 ).getReg ());
1199
- break ;
1200
- default :
1201
- llvm_unreachable (" Unknown pattern for machine combiner" );
1202
- }
1255
+ std::array<unsigned , 5 > OperandIndices;
1256
+ getReassociateOperandIndices (Root, Pattern, OperandIndices);
1257
+ MachineInstr *Prev =
1258
+ MRI.getUniqueVRegDef (Root.getOperand (OperandIndices[0 ]).getReg ());
1203
1259
1204
1260
// Don't reassociate if Prev and Root are in different blocks.
1205
1261
if (Prev->getParent () != Root.getParent ())
1206
1262
return ;
1207
1263
1208
- reassociateOps (Root, *Prev, Pattern, InsInstrs, DelInstrs, InstIdxForVirtReg);
1264
+ reassociateOps (Root, *Prev, Pattern, InsInstrs, DelInstrs, OperandIndices,
1265
+ InstIdxForVirtReg);
1209
1266
}
1210
1267
1211
1268
MachineTraceStrategy TargetInstrInfo::getMachineCombinerTraceStrategy () const {
0 commit comments