@@ -7165,6 +7165,52 @@ static bool shouldPreventUndefRegUpdateMemFold(MachineFunction &MF,
7165
7165
return VRegDef && VRegDef->isImplicitDef ();
7166
7166
}
7167
7167
7168
+ unsigned X86InstrInfo::commuteOperandsForFold (MachineInstr &MI,
7169
+ unsigned Idx1) const {
7170
+ unsigned Idx2 = CommuteAnyOperandIndex;
7171
+ if (!findCommutedOpIndices (MI, Idx1, Idx2))
7172
+ return Idx1;
7173
+
7174
+ bool HasDef = MI.getDesc ().getNumDefs ();
7175
+ Register Reg0 = HasDef ? MI.getOperand (0 ).getReg () : Register ();
7176
+ Register Reg1 = MI.getOperand (Idx1).getReg ();
7177
+ Register Reg2 = MI.getOperand (Idx2).getReg ();
7178
+ bool Tied1 = 0 == MI.getDesc ().getOperandConstraint (Idx1, MCOI::TIED_TO);
7179
+ bool Tied2 = 0 == MI.getDesc ().getOperandConstraint (Idx2, MCOI::TIED_TO);
7180
+
7181
+ // If either of the commutable operands are tied to the destination
7182
+ // then we can not commute + fold.
7183
+ if ((HasDef && Reg0 == Reg1 && Tied1) || (HasDef && Reg0 == Reg2 && Tied2))
7184
+ return Idx1;
7185
+
7186
+ MachineInstr *CommutedMI = commuteInstruction (MI, false , Idx1, Idx2);
7187
+ if (!CommutedMI) {
7188
+ // Unable to commute.
7189
+ return Idx1;
7190
+ }
7191
+ if (CommutedMI != &MI) {
7192
+ // New instruction. We can't fold from this.
7193
+ CommutedMI->eraseFromParent ();
7194
+ return Idx1;
7195
+ }
7196
+
7197
+ return Idx2;
7198
+ }
7199
+
7200
+ void X86InstrInfo::UndoCommuteForFold (MachineInstr &MI, unsigned Idx1,
7201
+ unsigned Idx2) const {
7202
+ // Folding failed again - undo the commute before returning.
7203
+ MachineInstr *UncommutedMI = commuteInstruction (MI, false , Idx1, Idx2);
7204
+ // New instruction. It doesn't need to be kept.
7205
+ if (UncommutedMI && UncommutedMI != &MI)
7206
+ UncommutedMI->eraseFromParent ();
7207
+ }
7208
+
7209
+ static void printFailMsgforFold (const MachineInstr &MI, unsigned Idx) {
7210
+ if (PrintFailedFusing && !MI.isCopy ())
7211
+ dbgs () << " We failed to fuse operand " << Idx << " in " << MI;
7212
+ }
7213
+
7168
7214
MachineInstr *X86InstrInfo::foldMemoryOperandImpl (
7169
7215
MachineFunction &MF, MachineInstr &MI, unsigned OpNum,
7170
7216
ArrayRef<MachineOperand> MOs, MachineBasicBlock::iterator InsertPt,
@@ -7292,65 +7338,23 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
7292
7338
return NewMI;
7293
7339
}
7294
7340
7295
- // If the instruction and target operand are commutable, commute the
7296
- // instruction and try again.
7297
7341
if (AllowCommute) {
7298
- unsigned CommuteOpIdx1 = OpNum, CommuteOpIdx2 = CommuteAnyOperandIndex;
7299
- if (findCommutedOpIndices (MI, CommuteOpIdx1, CommuteOpIdx2)) {
7300
- bool HasDef = MI.getDesc ().getNumDefs ();
7301
- Register Reg0 = HasDef ? MI.getOperand (0 ).getReg () : Register ();
7302
- Register Reg1 = MI.getOperand (CommuteOpIdx1).getReg ();
7303
- Register Reg2 = MI.getOperand (CommuteOpIdx2).getReg ();
7304
- bool Tied1 =
7305
- 0 == MI.getDesc ().getOperandConstraint (CommuteOpIdx1, MCOI::TIED_TO);
7306
- bool Tied2 =
7307
- 0 == MI.getDesc ().getOperandConstraint (CommuteOpIdx2, MCOI::TIED_TO);
7308
-
7309
- // If either of the commutable operands are tied to the destination
7310
- // then we can not commute + fold.
7311
- if ((HasDef && Reg0 == Reg1 && Tied1) ||
7312
- (HasDef && Reg0 == Reg2 && Tied2))
7313
- return nullptr ;
7314
-
7315
- MachineInstr *CommutedMI =
7316
- commuteInstruction (MI, false , CommuteOpIdx1, CommuteOpIdx2);
7317
- if (!CommutedMI) {
7318
- // Unable to commute.
7319
- return nullptr ;
7320
- }
7321
- if (CommutedMI != &MI) {
7322
- // New instruction. We can't fold from this.
7323
- CommutedMI->eraseFromParent ();
7324
- return nullptr ;
7325
- }
7326
-
7327
- // Attempt to fold with the commuted version of the instruction.
7328
- NewMI = foldMemoryOperandImpl (MF, MI, CommuteOpIdx2, MOs, InsertPt, Size,
7329
- Alignment, /* AllowCommute=*/ false );
7330
- if (NewMI)
7331
- return NewMI;
7332
-
7333
- // Folding failed again - undo the commute before returning.
7334
- MachineInstr *UncommutedMI =
7335
- commuteInstruction (MI, false , CommuteOpIdx1, CommuteOpIdx2);
7336
- if (!UncommutedMI) {
7337
- // Unable to commute.
7338
- return nullptr ;
7339
- }
7340
- if (UncommutedMI != &MI) {
7341
- // New instruction. It doesn't need to be kept.
7342
- UncommutedMI->eraseFromParent ();
7343
- return nullptr ;
7344
- }
7345
-
7346
- // Return here to prevent duplicate fuse failure report.
7342
+ // If the instruction and target operand are commutable, commute the
7343
+ // instruction and try again.
7344
+ unsigned CommuteOpIdx2 = commuteOperandsForFold (MI, OpNum);
7345
+ if (CommuteOpIdx2 == OpNum) {
7346
+ printFailMsgforFold (MI, OpNum);
7347
7347
return nullptr ;
7348
7348
}
7349
+ // Attempt to fold with the commuted version of the instruction.
7350
+ NewMI = foldMemoryOperandImpl (MF, MI, CommuteOpIdx2, MOs, InsertPt, Size,
7351
+ Alignment, /* AllowCommute=*/ false );
7352
+ if (NewMI)
7353
+ return NewMI;
7354
+ UndoCommuteForFold (MI, OpNum, CommuteOpIdx2);
7349
7355
}
7350
7356
7351
- // No fusion
7352
- if (PrintFailedFusing && !MI.isCopy ())
7353
- dbgs () << " We failed to fuse operand " << OpNum << " in " << MI;
7357
+ printFailMsgforFold (MI, OpNum);
7354
7358
return nullptr ;
7355
7359
}
7356
7360
0 commit comments