@@ -240,6 +240,8 @@ namespace {
240
240
void addRegClassDefCounts (std::vector<unsigned > &RegClassDefCounts,
241
241
Register Reg) const ;
242
242
243
+ void findAndSortDefOperandIndexes (const MachineInstr &MI);
244
+
243
245
void allocateInstruction (MachineInstr &MI);
244
246
void handleDebugValue (MachineInstr &MI);
245
247
void handleBundle (MachineInstr &MI);
@@ -265,18 +267,18 @@ namespace {
265
267
void allocVirtRegUndef (MachineOperand &MO);
266
268
void assignDanglingDebugValues (MachineInstr &Def, Register VirtReg,
267
269
MCPhysReg Reg);
268
- void defineLiveThroughVirtReg (MachineInstr &MI, unsigned OpNum,
270
+ bool defineLiveThroughVirtReg (MachineInstr &MI, unsigned OpNum,
269
271
Register VirtReg);
270
- void defineVirtReg (MachineInstr &MI, unsigned OpNum, Register VirtReg,
272
+ bool defineVirtReg (MachineInstr &MI, unsigned OpNum, Register VirtReg,
271
273
bool LookAtPhysRegUses = false );
272
- void useVirtReg (MachineInstr &MI, unsigned OpNum, Register VirtReg);
274
+ bool useVirtReg (MachineInstr &MI, unsigned OpNum, Register VirtReg);
273
275
274
276
MachineBasicBlock::iterator
275
277
getMBBBeginInsertionPoint (MachineBasicBlock &MBB,
276
278
SmallSet<Register, 2 > &PrologLiveIns) const ;
277
279
278
280
void reloadAtBegin (MachineBasicBlock &MBB);
279
- void setPhysReg (MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
281
+ bool setPhysReg (MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
280
282
281
283
Register traceCopies (Register VirtReg) const ;
282
284
Register traceCopyChain (Register Reg) const ;
@@ -875,10 +877,11 @@ void RegAllocFast::allocVirtRegUndef(MachineOperand &MO) {
875
877
876
878
// / Variation of defineVirtReg() with special handling for livethrough regs
877
879
// / (tied or earlyclobber) that may interfere with preassigned uses.
878
- void RegAllocFast::defineLiveThroughVirtReg (MachineInstr &MI, unsigned OpNum,
880
+ // / \return true if MI's MachineOperands were re-arranged/invalidated.
881
+ bool RegAllocFast::defineLiveThroughVirtReg (MachineInstr &MI, unsigned OpNum,
879
882
Register VirtReg) {
880
883
if (!shouldAllocateRegister (VirtReg))
881
- return ;
884
+ return false ;
882
885
LiveRegMap::iterator LRI = findLiveVirtReg (VirtReg);
883
886
if (LRI != LiveVirtRegs.end ()) {
884
887
MCPhysReg PrevReg = LRI->PhysReg ;
@@ -909,11 +912,13 @@ void RegAllocFast::defineLiveThroughVirtReg(MachineInstr &MI, unsigned OpNum,
909
912
// / perform an allocation if:
910
913
// / - It is a dead definition without any uses.
911
914
// / - The value is live out and all uses are in different basic blocks.
912
- void RegAllocFast::defineVirtReg (MachineInstr &MI, unsigned OpNum,
915
+ // /
916
+ // / \return true if MI's MachineOperands were re-arranged/invalidated.
917
+ bool RegAllocFast::defineVirtReg (MachineInstr &MI, unsigned OpNum,
913
918
Register VirtReg, bool LookAtPhysRegUses) {
914
919
assert (VirtReg.isVirtual () && " Not a virtual register" );
915
920
if (!shouldAllocateRegister (VirtReg))
916
- return ;
921
+ return false ;
917
922
MachineOperand &MO = MI.getOperand (OpNum);
918
923
LiveRegMap::iterator LRI;
919
924
bool New;
@@ -974,15 +979,16 @@ void RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum,
974
979
BundleVirtRegsMap[VirtReg] = PhysReg;
975
980
}
976
981
markRegUsedInInstr (PhysReg);
977
- setPhysReg (MI, MO, PhysReg);
982
+ return setPhysReg (MI, MO, PhysReg);
978
983
}
979
984
980
985
// / Allocates a register for a VirtReg use.
981
- void RegAllocFast::useVirtReg (MachineInstr &MI, unsigned OpNum,
986
+ // / \return true if MI's MachineOperands were re-arranged/invalidated.
987
+ bool RegAllocFast::useVirtReg (MachineInstr &MI, unsigned OpNum,
982
988
Register VirtReg) {
983
989
assert (VirtReg.isVirtual () && " Not a virtual register" );
984
990
if (!shouldAllocateRegister (VirtReg))
985
- return ;
991
+ return false ;
986
992
MachineOperand &MO = MI.getOperand (OpNum);
987
993
LiveRegMap::iterator LRI;
988
994
bool New;
@@ -1019,8 +1025,7 @@ void RegAllocFast::useVirtReg(MachineInstr &MI, unsigned OpNum,
1019
1025
if (LRI->Error ) {
1020
1026
const TargetRegisterClass &RC = *MRI->getRegClass (VirtReg);
1021
1027
ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder (&RC);
1022
- setPhysReg (MI, MO, *AllocationOrder.begin ());
1023
- return ;
1028
+ return setPhysReg (MI, MO, *AllocationOrder.begin ());
1024
1029
}
1025
1030
}
1026
1031
@@ -1030,18 +1035,17 @@ void RegAllocFast::useVirtReg(MachineInstr &MI, unsigned OpNum,
1030
1035
BundleVirtRegsMap[VirtReg] = LRI->PhysReg ;
1031
1036
}
1032
1037
markRegUsedInInstr (LRI->PhysReg );
1033
- setPhysReg (MI, MO, LRI->PhysReg );
1038
+ return setPhysReg (MI, MO, LRI->PhysReg );
1034
1039
}
1035
1040
1036
- // / Changes operand OpNum in MI the refer the PhysReg, considering subregs. This
1037
- // / may invalidate any operand pointers. Return true if the operand kills its
1038
- // / register.
1039
- void RegAllocFast::setPhysReg (MachineInstr &MI, MachineOperand &MO,
1041
+ // / Changes operand OpNum in MI the refer the PhysReg, considering subregs.
1042
+ // / \return true if MI's MachineOperands were re-arranged/invalidated.
1043
+ bool RegAllocFast::setPhysReg (MachineInstr &MI, MachineOperand &MO,
1040
1044
MCPhysReg PhysReg) {
1041
1045
if (!MO.getSubReg ()) {
1042
1046
MO.setReg (PhysReg);
1043
1047
MO.setIsRenamable (true );
1044
- return ;
1048
+ return false ;
1045
1049
}
1046
1050
1047
1051
// Handle subregister index.
@@ -1057,7 +1061,8 @@ void RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO,
1057
1061
// register kill.
1058
1062
if (MO.isKill ()) {
1059
1063
MI.addRegisterKilled (PhysReg, TRI, true );
1060
- return ;
1064
+ // Conservatively assume implicit MOs were re-arranged
1065
+ return true ;
1061
1066
}
1062
1067
1063
1068
// A <def,read-undef> of a sub-register requires an implicit def of the full
@@ -1067,7 +1072,10 @@ void RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO,
1067
1072
MI.addRegisterDead (PhysReg, TRI, true );
1068
1073
else
1069
1074
MI.addRegisterDefined (PhysReg, TRI);
1075
+ // Conservatively assume implicit MOs were re-arranged
1076
+ return true ;
1070
1077
}
1078
+ return false ;
1071
1079
}
1072
1080
1073
1081
#ifndef NDEBUG
@@ -1147,6 +1155,72 @@ void RegAllocFast::addRegClassDefCounts(std::vector<unsigned> &RegClassDefCounts
1147
1155
}
1148
1156
}
1149
1157
1158
+ // / Compute \ref DefOperandIndexes so it contains the indices of "def" operands
1159
+ // / that are to be allocated. Those are ordered in a way that small classes,
1160
+ // / early clobbers and livethroughs are allocated first.
1161
+ void RegAllocFast::findAndSortDefOperandIndexes (const MachineInstr &MI) {
1162
+ DefOperandIndexes.clear ();
1163
+
1164
+ // Track number of defs which may consume a register from the class.
1165
+ std::vector<unsigned > RegClassDefCounts (TRI->getNumRegClasses (), 0 );
1166
+ assert (RegClassDefCounts[0 ] == 0 );
1167
+
1168
+ LLVM_DEBUG (dbgs () << " Need to assign livethroughs\n " );
1169
+ for (unsigned I = 0 , E = MI.getNumOperands (); I < E; ++I) {
1170
+ const MachineOperand &MO = MI.getOperand (I);
1171
+ if (!MO.isReg ())
1172
+ continue ;
1173
+ Register Reg = MO.getReg ();
1174
+ if (MO.readsReg ()) {
1175
+ if (Reg.isPhysical ()) {
1176
+ LLVM_DEBUG (dbgs () << " mark extra used: " << printReg (Reg, TRI) << ' \n ' );
1177
+ markPhysRegUsedInInstr (Reg);
1178
+ }
1179
+ }
1180
+
1181
+ if (MO.isDef ()) {
1182
+ if (Reg.isVirtual () && shouldAllocateRegister (Reg))
1183
+ DefOperandIndexes.push_back (I);
1184
+
1185
+ addRegClassDefCounts (RegClassDefCounts, Reg);
1186
+ }
1187
+ }
1188
+
1189
+ llvm::sort (DefOperandIndexes, [&](uint16_t I0, uint16_t I1) {
1190
+ const MachineOperand &MO0 = MI.getOperand (I0);
1191
+ const MachineOperand &MO1 = MI.getOperand (I1);
1192
+ Register Reg0 = MO0.getReg ();
1193
+ Register Reg1 = MO1.getReg ();
1194
+ const TargetRegisterClass &RC0 = *MRI->getRegClass (Reg0);
1195
+ const TargetRegisterClass &RC1 = *MRI->getRegClass (Reg1);
1196
+
1197
+ // Identify regclass that are easy to use up completely just in this
1198
+ // instruction.
1199
+ unsigned ClassSize0 = RegClassInfo.getOrder (&RC0).size ();
1200
+ unsigned ClassSize1 = RegClassInfo.getOrder (&RC1).size ();
1201
+
1202
+ bool SmallClass0 = ClassSize0 < RegClassDefCounts[RC0.getID ()];
1203
+ bool SmallClass1 = ClassSize1 < RegClassDefCounts[RC1.getID ()];
1204
+ if (SmallClass0 > SmallClass1)
1205
+ return true ;
1206
+ if (SmallClass0 < SmallClass1)
1207
+ return false ;
1208
+
1209
+ // Allocate early clobbers and livethrough operands first.
1210
+ bool Livethrough0 = MO0.isEarlyClobber () || MO0.isTied () ||
1211
+ (MO0.getSubReg () == 0 && !MO0.isUndef ());
1212
+ bool Livethrough1 = MO1.isEarlyClobber () || MO1.isTied () ||
1213
+ (MO1.getSubReg () == 0 && !MO1.isUndef ());
1214
+ if (Livethrough0 > Livethrough1)
1215
+ return true ;
1216
+ if (Livethrough0 < Livethrough1)
1217
+ return false ;
1218
+
1219
+ // Tie-break rule: operand index.
1220
+ return I0 < I1;
1221
+ });
1222
+ }
1223
+
1150
1224
void RegAllocFast::allocateInstruction (MachineInstr &MI) {
1151
1225
// The basic algorithm here is:
1152
1226
// 1. Mark registers of def operands as free
@@ -1218,97 +1292,56 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
1218
1292
// Allocate virtreg defs.
1219
1293
if (HasDef) {
1220
1294
if (HasVRegDef) {
1295
+ // Note that Implicit MOs can get re-arranged by defineVirtReg(), so loop
1296
+ // multiple times to ensure no operand is missed.
1297
+ bool ReArrangedImplicitOps = true ;
1298
+
1221
1299
// Special handling for early clobbers, tied operands or subregister defs:
1222
1300
// Compared to "normal" defs these:
1223
1301
// - Must not use a register that is pre-assigned for a use operand.
1224
1302
// - In order to solve tricky inline assembly constraints we change the
1225
1303
// heuristic to figure out a good operand order before doing
1226
1304
// assignments.
1227
1305
if (NeedToAssignLiveThroughs) {
1228
- DefOperandIndexes.clear ();
1229
1306
PhysRegUses.clear ();
1230
1307
1231
- // Track number of defs which may consume a register from the class.
1232
- std::vector<unsigned > RegClassDefCounts (TRI->getNumRegClasses (), 0 );
1233
- assert (RegClassDefCounts[0 ] == 0 );
1234
-
1235
- LLVM_DEBUG (dbgs () << " Need to assign livethroughs\n " );
1236
- for (unsigned I = 0 , E = MI.getNumOperands (); I < E; ++I) {
1237
- const MachineOperand &MO = MI.getOperand (I);
1238
- if (!MO.isReg ())
1239
- continue ;
1240
- Register Reg = MO.getReg ();
1241
- if (MO.readsReg ()) {
1242
- if (Reg.isPhysical ()) {
1243
- LLVM_DEBUG (dbgs () << " mark extra used: " << printReg (Reg, TRI)
1244
- << ' \n ' );
1245
- markPhysRegUsedInInstr (Reg);
1308
+ while (ReArrangedImplicitOps) {
1309
+ ReArrangedImplicitOps = false ;
1310
+ findAndSortDefOperandIndexes (MI);
1311
+ for (uint16_t OpIdx : DefOperandIndexes) {
1312
+ MachineOperand &MO = MI.getOperand (OpIdx);
1313
+ LLVM_DEBUG (dbgs () << " Allocating " << MO << ' \n ' );
1314
+ unsigned Reg = MO.getReg ();
1315
+ if (MO.isEarlyClobber () ||
1316
+ (MO.isTied () && !TiedOpIsUndef (MO, OpIdx)) ||
1317
+ (MO.getSubReg () && !MO.isUndef ())) {
1318
+ ReArrangedImplicitOps = defineLiveThroughVirtReg (MI, OpIdx, Reg);
1319
+ } else {
1320
+ ReArrangedImplicitOps = defineVirtReg (MI, OpIdx, Reg);
1321
+ }
1322
+ if (ReArrangedImplicitOps) {
1323
+ // Implicit operands of MI were re-arranged,
1324
+ // re-compute DefOperandIndexes.
1325
+ break ;
1246
1326
}
1247
- }
1248
-
1249
- if (MO.isDef ()) {
1250
- if (Reg.isVirtual () && shouldAllocateRegister (Reg))
1251
- DefOperandIndexes.push_back (I);
1252
-
1253
- addRegClassDefCounts (RegClassDefCounts, Reg);
1254
- }
1255
- }
1256
-
1257
- llvm::sort (DefOperandIndexes, [&](uint16_t I0, uint16_t I1) {
1258
- const MachineOperand &MO0 = MI.getOperand (I0);
1259
- const MachineOperand &MO1 = MI.getOperand (I1);
1260
- Register Reg0 = MO0.getReg ();
1261
- Register Reg1 = MO1.getReg ();
1262
- const TargetRegisterClass &RC0 = *MRI->getRegClass (Reg0);
1263
- const TargetRegisterClass &RC1 = *MRI->getRegClass (Reg1);
1264
-
1265
- // Identify regclass that are easy to use up completely just in this
1266
- // instruction.
1267
- unsigned ClassSize0 = RegClassInfo.getOrder (&RC0).size ();
1268
- unsigned ClassSize1 = RegClassInfo.getOrder (&RC1).size ();
1269
-
1270
- bool SmallClass0 = ClassSize0 < RegClassDefCounts[RC0.getID ()];
1271
- bool SmallClass1 = ClassSize1 < RegClassDefCounts[RC1.getID ()];
1272
- if (SmallClass0 > SmallClass1)
1273
- return true ;
1274
- if (SmallClass0 < SmallClass1)
1275
- return false ;
1276
-
1277
- // Allocate early clobbers and livethrough operands first.
1278
- bool Livethrough0 = MO0.isEarlyClobber () || MO0.isTied () ||
1279
- (MO0.getSubReg () == 0 && !MO0.isUndef ());
1280
- bool Livethrough1 = MO1.isEarlyClobber () || MO1.isTied () ||
1281
- (MO1.getSubReg () == 0 && !MO1.isUndef ());
1282
- if (Livethrough0 > Livethrough1)
1283
- return true ;
1284
- if (Livethrough0 < Livethrough1)
1285
- return false ;
1286
-
1287
- // Tie-break rule: operand index.
1288
- return I0 < I1;
1289
- });
1290
-
1291
- for (uint16_t OpIdx : DefOperandIndexes) {
1292
- MachineOperand &MO = MI.getOperand (OpIdx);
1293
- LLVM_DEBUG (dbgs () << " Allocating " << MO << ' \n ' );
1294
- unsigned Reg = MO.getReg ();
1295
- if (MO.isEarlyClobber () ||
1296
- (MO.isTied () && !TiedOpIsUndef (MO, OpIdx)) ||
1297
- (MO.getSubReg () && !MO.isUndef ())) {
1298
- defineLiveThroughVirtReg (MI, OpIdx, Reg);
1299
- } else {
1300
- defineVirtReg (MI, OpIdx, Reg);
1301
1327
}
1302
1328
}
1303
1329
} else {
1304
1330
// Assign virtual register defs.
1305
- for (unsigned I = 0 , E = MI.getNumOperands (); I < E; ++I) {
1306
- MachineOperand &MO = MI.getOperand (I);
1307
- if (!MO.isReg () || !MO.isDef ())
1308
- continue ;
1309
- Register Reg = MO.getReg ();
1310
- if (Reg.isVirtual ())
1311
- defineVirtReg (MI, I, Reg);
1331
+ while (ReArrangedImplicitOps) {
1332
+ ReArrangedImplicitOps = false ;
1333
+ for (unsigned I = 0 , E = MI.getNumOperands (); I < E; ++I) {
1334
+ MachineOperand &MO = MI.getOperand (I);
1335
+ if (!MO.isReg () || !MO.isDef ())
1336
+ continue ;
1337
+ Register Reg = MO.getReg ();
1338
+ if (Reg.isVirtual ()) {
1339
+ ReArrangedImplicitOps = defineVirtReg (MI, I, Reg);
1340
+ if (ReArrangedImplicitOps) {
1341
+ break ;
1342
+ }
1343
+ }
1344
+ }
1312
1345
}
1313
1346
}
1314
1347
}
@@ -1382,29 +1415,35 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
1382
1415
}
1383
1416
1384
1417
// Allocate virtreg uses and insert reloads as necessary.
1418
+ // Implicit MOs can get moved/removed by useVirtReg(), so loop multiple
1419
+ // times to ensure no operand is missed.
1385
1420
bool HasUndefUse = false ;
1386
- for (unsigned I = 0 ; I < MI.getNumOperands (); ++I) {
1387
- MachineOperand &MO = MI.getOperand (I);
1388
- if (!MO.isReg () || !MO.isUse ())
1389
- continue ;
1390
- Register Reg = MO.getReg ();
1391
- if (!Reg.isVirtual () || !shouldAllocateRegister (Reg))
1392
- continue ;
1393
-
1394
- if (MO.isUndef ()) {
1395
- HasUndefUse = true ;
1396
- continue ;
1397
- }
1398
-
1421
+ bool ReArrangedImplicitMOs = true ;
1422
+ while (ReArrangedImplicitMOs) {
1423
+ ReArrangedImplicitMOs = false ;
1424
+ for (unsigned I = 0 ; I < MI.getNumOperands (); ++I) {
1425
+ MachineOperand &MO = MI.getOperand (I);
1426
+ if (!MO.isReg () || !MO.isUse ())
1427
+ continue ;
1428
+ Register Reg = MO.getReg ();
1429
+ if (!Reg.isVirtual () || !shouldAllocateRegister (Reg))
1430
+ continue ;
1399
1431
1400
- // Populate MayLiveAcrossBlocks in case the use block is allocated before
1401
- // the def block (removing the vreg uses).
1402
- mayLiveIn (Reg);
1432
+ if (MO.isUndef ()) {
1433
+ HasUndefUse = true ;
1434
+ continue ;
1435
+ }
1403
1436
1437
+ // Populate MayLiveAcrossBlocks in case the use block is allocated before
1438
+ // the def block (removing the vreg uses).
1439
+ mayLiveIn (Reg);
1404
1440
1405
- assert (!MO.isInternalRead () && " Bundles not supported" );
1406
- assert (MO.readsReg () && " reading use" );
1407
- useVirtReg (MI, I, Reg);
1441
+ assert (!MO.isInternalRead () && " Bundles not supported" );
1442
+ assert (MO.readsReg () && " reading use" );
1443
+ ReArrangedImplicitMOs = useVirtReg (MI, I, Reg);
1444
+ if (ReArrangedImplicitMOs)
1445
+ break ;
1446
+ }
1408
1447
}
1409
1448
1410
1449
// Allocate undef operands. This is a separate step because in a situation
0 commit comments