16
16
// ===----------------------------------------------------------------------===//
17
17
18
18
#include " llvm/ADT/DenseSet.h"
19
+ #include " llvm/ADT/MapVector.h"
19
20
#include " llvm/ADT/PointerIntPair.h"
20
21
#include " llvm/ADT/SetVector.h"
21
22
#include " llvm/ADT/SmallSet.h"
@@ -566,9 +567,10 @@ void MachineSinking::ProcessDbgInst(MachineInstr &MI) {
566
567
MI.getDebugLoc ()->getInlinedAt ());
567
568
bool SeenBefore = SeenDbgVars.contains (Var);
568
569
569
- MachineOperand &MO = MI.getDebugOperand (0 );
570
- if (MO.isReg () && MO.getReg ().isVirtual ())
571
- SeenDbgUsers[MO.getReg ()].push_back (SeenDbgUser (&MI, SeenBefore));
570
+ for (MachineOperand &MO : MI.debug_operands ()) {
571
+ if (MO.isReg () && MO.getReg ().isVirtual ())
572
+ SeenDbgUsers[MO.getReg ()].push_back (SeenDbgUser (&MI, SeenBefore));
573
+ }
572
574
573
575
// Record the variable for any DBG_VALUE, to avoid re-ordering any of them.
574
576
SeenDbgVars.insert (Var);
@@ -1028,14 +1030,14 @@ static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI,
1028
1030
// / leaving an 'undef' DBG_VALUE in the original location. Don't do this if
1029
1031
// / there's any subregister weirdness involved. Returns true if copy
1030
1032
// / propagation occurred.
1031
- static bool attemptDebugCopyProp (MachineInstr &SinkInst, MachineInstr &DbgMI) {
1033
+ static bool attemptDebugCopyProp (MachineInstr &SinkInst, MachineInstr &DbgMI,
1034
+ Register Reg) {
1032
1035
const MachineRegisterInfo &MRI = SinkInst.getMF ()->getRegInfo ();
1033
1036
const TargetInstrInfo &TII = *SinkInst.getMF ()->getSubtarget ().getInstrInfo ();
1034
1037
1035
1038
// Copy DBG_VALUE operand and set the original to undef. We then check to
1036
1039
// see whether this is something that can be copy-forwarded. If it isn't,
1037
1040
// continue around the loop.
1038
- MachineOperand &DbgMO = DbgMI.getDebugOperand (0 );
1039
1041
1040
1042
const MachineOperand *SrcMO = nullptr , *DstMO = nullptr ;
1041
1043
auto CopyOperands = TII.isCopyInstr (SinkInst);
@@ -1048,36 +1050,41 @@ static bool attemptDebugCopyProp(MachineInstr &SinkInst, MachineInstr &DbgMI) {
1048
1050
bool PostRA = MRI.getNumVirtRegs () == 0 ;
1049
1051
1050
1052
// Trying to forward between physical and virtual registers is too hard.
1051
- if (DbgMO. getReg () .isVirtual () != SrcMO->getReg ().isVirtual ())
1053
+ if (Reg .isVirtual () != SrcMO->getReg ().isVirtual ())
1052
1054
return false ;
1053
1055
1054
1056
// Only try virtual register copy-forwarding before regalloc, and physical
1055
1057
// register copy-forwarding after regalloc.
1056
- bool arePhysRegs = !DbgMO. getReg () .isVirtual ();
1058
+ bool arePhysRegs = !Reg .isVirtual ();
1057
1059
if (arePhysRegs != PostRA)
1058
1060
return false ;
1059
1061
1060
1062
// Pre-regalloc, only forward if all subregisters agree (or there are no
1061
1063
// subregs at all). More analysis might recover some forwardable copies.
1062
- if (!PostRA && (DbgMO.getSubReg () != SrcMO->getSubReg () ||
1063
- DbgMO.getSubReg () != DstMO->getSubReg ()))
1064
- return false ;
1064
+ if (!PostRA)
1065
+ for (auto &DbgMO : DbgMI.getDebugOperandsForReg (Reg))
1066
+ if (DbgMO.getSubReg () != SrcMO->getSubReg () ||
1067
+ DbgMO.getSubReg () != DstMO->getSubReg ())
1068
+ return false ;
1065
1069
1066
1070
// Post-regalloc, we may be sinking a DBG_VALUE of a sub or super-register
1067
1071
// of this copy. Only forward the copy if the DBG_VALUE operand exactly
1068
1072
// matches the copy destination.
1069
- if (PostRA && DbgMO. getReg () != DstMO->getReg ())
1073
+ if (PostRA && Reg != DstMO->getReg ())
1070
1074
return false ;
1071
1075
1072
- DbgMO.setReg (SrcMO->getReg ());
1073
- DbgMO.setSubReg (SrcMO->getSubReg ());
1076
+ for (auto &DbgMO : DbgMI.getDebugOperandsForReg (Reg)) {
1077
+ DbgMO.setReg (SrcMO->getReg ());
1078
+ DbgMO.setSubReg (SrcMO->getSubReg ());
1079
+ }
1074
1080
return true ;
1075
1081
}
1076
1082
1083
+ using MIRegs = std::pair<MachineInstr *, SmallVector<unsigned , 2 >>;
1077
1084
// / Sink an instruction and its associated debug instructions.
1078
1085
static void performSink (MachineInstr &MI, MachineBasicBlock &SuccToSinkTo,
1079
1086
MachineBasicBlock::iterator InsertPos,
1080
- SmallVectorImpl<MachineInstr * > &DbgValuesToSink) {
1087
+ SmallVectorImpl<MIRegs > &DbgValuesToSink) {
1081
1088
1082
1089
// If we cannot find a location to use (merge with), then we erase the debug
1083
1090
// location to prevent debug-info driven tools from potentially reporting
@@ -1097,11 +1104,21 @@ static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo,
1097
1104
// DBG_VALUE location as 'undef', indicating that any earlier variable
1098
1105
// location should be terminated as we've optimised away the value at this
1099
1106
// point.
1100
- for (MachineInstr *DbgMI : DbgValuesToSink) {
1107
+ for (auto DbgValueToSink : DbgValuesToSink) {
1108
+ MachineInstr *DbgMI = DbgValueToSink.first ;
1101
1109
MachineInstr *NewDbgMI = DbgMI->getMF ()->CloneMachineInstr (DbgMI);
1102
1110
SuccToSinkTo.insert (InsertPos, NewDbgMI);
1103
1111
1104
- if (!attemptDebugCopyProp (MI, *DbgMI))
1112
+ bool PropagatedAllSunkOps = true ;
1113
+ for (unsigned Reg : DbgValueToSink.second ) {
1114
+ if (DbgMI->hasDebugOperandForReg (Reg)) {
1115
+ if (!attemptDebugCopyProp (MI, *DbgMI, Reg)) {
1116
+ PropagatedAllSunkOps = false ;
1117
+ break ;
1118
+ }
1119
+ }
1120
+ }
1121
+ if (!PropagatedAllSunkOps)
1105
1122
DbgMI->setDebugValueUndef ();
1106
1123
}
1107
1124
}
@@ -1384,7 +1401,7 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
1384
1401
++InsertPos;
1385
1402
1386
1403
// Collect debug users of any vreg that this inst defines.
1387
- SmallVector<MachineInstr * , 4 > DbgUsersToSink;
1404
+ SmallVector<MIRegs , 4 > DbgUsersToSink;
1388
1405
for (auto &MO : MI.operands ()) {
1389
1406
if (!MO.isReg () || !MO.isDef () || !MO.getReg ().isVirtual ())
1390
1407
continue ;
@@ -1398,10 +1415,11 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
1398
1415
if (User.getInt ()) {
1399
1416
// This DBG_VALUE would re-order assignments. If we can't copy-propagate
1400
1417
// it, it can't be recovered. Set it undef.
1401
- if (!attemptDebugCopyProp (MI, *DbgMI))
1418
+ if (!attemptDebugCopyProp (MI, *DbgMI, MO. getReg () ))
1402
1419
DbgMI->setDebugValueUndef ();
1403
1420
} else {
1404
- DbgUsersToSink.push_back (DbgMI);
1421
+ DbgUsersToSink.push_back (
1422
+ {DbgMI, SmallVector<unsigned , 2 >(1 , MO.getReg ())});
1405
1423
}
1406
1424
}
1407
1425
}
@@ -1436,10 +1454,12 @@ void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1436
1454
// be sunk. For the rest, if they are not dominated by the block we will sink
1437
1455
// MI into, propagate the copy source to them.
1438
1456
SmallVector<MachineInstr *, 4 > DbgDefUsers;
1457
+ SmallVector<Register, 4 > DbgUseRegs;
1439
1458
const MachineRegisterInfo &MRI = MI.getMF ()->getRegInfo ();
1440
1459
for (auto &MO : MI.operands ()) {
1441
1460
if (!MO.isReg () || !MO.isDef () || !MO.getReg ().isVirtual ())
1442
1461
continue ;
1462
+ DbgUseRegs.push_back (MO.getReg ());
1443
1463
for (auto &User : MRI.use_instructions (MO.getReg ())) {
1444
1464
if (!User.isDebugValue () || DT->dominates (TargetBlock, User.getParent ()))
1445
1465
continue ;
@@ -1448,17 +1468,21 @@ void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
1448
1468
if (User.getParent () == MI.getParent ())
1449
1469
continue ;
1450
1470
1451
- assert (User.getDebugOperand ( 0 ). isReg ( ) &&
1452
- " DBG_VALUE user of vreg, but non reg operand?" );
1471
+ assert (User.hasDebugOperandForReg (MO. getReg () ) &&
1472
+ " DBG_VALUE user of vreg, but has no operand for it ?" );
1453
1473
DbgDefUsers.push_back (&User);
1454
1474
}
1455
1475
}
1456
1476
1457
1477
// Point the users of this copy that are no longer dominated, at the source
1458
1478
// of the copy.
1459
1479
for (auto *User : DbgDefUsers) {
1460
- User->getDebugOperand (0 ).setReg (MI.getOperand (1 ).getReg ());
1461
- User->getDebugOperand (0 ).setSubReg (MI.getOperand (1 ).getSubReg ());
1480
+ for (auto &Reg : DbgUseRegs) {
1481
+ for (auto &DbgOp : User->getDebugOperandsForReg (Reg)) {
1482
+ DbgOp.setReg (MI.getOperand (1 ).getReg ());
1483
+ DbgOp.setSubReg (MI.getOperand (1 ).getSubReg ());
1484
+ }
1485
+ }
1462
1486
}
1463
1487
}
1464
1488
@@ -1521,8 +1545,10 @@ class PostRAMachineSinking : public MachineFunctionPass {
1521
1545
LiveRegUnits ModifiedRegUnits, UsedRegUnits;
1522
1546
1523
1547
// / Track DBG_VALUEs of (unmodified) register units. Each DBG_VALUE has an
1524
- // / entry in this map for each unit it touches.
1525
- DenseMap<unsigned , TinyPtrVector<MachineInstr *>> SeenDbgInstrs;
1548
+ // / entry in this map for each unit it touches. The DBG_VALUE's entry
1549
+ // / consists of a pointer to the instruction itself, and a vector of registers
1550
+ // / referred to by the instruction that overlap the key register unit.
1551
+ DenseMap<unsigned , SmallVector<MIRegs, 2 >> SeenDbgInstrs;
1526
1552
1527
1553
// / Sink Copy instructions unused in the same block close to their uses in
1528
1554
// / successors.
@@ -1704,18 +1730,27 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
1704
1730
// We must sink this DBG_VALUE if its operand is sunk. To avoid searching
1705
1731
// for DBG_VALUEs later, record them when they're encountered.
1706
1732
if (MI->isDebugValue ()) {
1707
- auto &MO = MI->getDebugOperand (0 );
1708
- if (MO.isReg () && Register::isPhysicalRegister (MO.getReg ())) {
1709
- // Bail if we can already tell the sink would be rejected, rather
1710
- // than needlessly accumulating lots of DBG_VALUEs.
1711
- if (hasRegisterDependency (MI, UsedOpsInCopy, DefedRegsInCopy,
1712
- ModifiedRegUnits, UsedRegUnits))
1713
- continue ;
1714
-
1715
- // Record debug use of each reg unit.
1716
- SmallSet<MCRegister, 4 > Units = getRegUnits (MO.getReg (), TRI);
1717
- for (MCRegister Reg : Units)
1718
- SeenDbgInstrs[Reg].push_back (MI);
1733
+ SmallDenseMap<MCRegister, SmallVector<unsigned , 2 >, 4 > MIUnits;
1734
+ bool IsValid = true ;
1735
+ for (MachineOperand &MO : MI->debug_operands ()) {
1736
+ if (MO.isReg () && Register::isPhysicalRegister (MO.getReg ())) {
1737
+ // Bail if we can already tell the sink would be rejected, rather
1738
+ // than needlessly accumulating lots of DBG_VALUEs.
1739
+ if (hasRegisterDependency (MI, UsedOpsInCopy, DefedRegsInCopy,
1740
+ ModifiedRegUnits, UsedRegUnits)) {
1741
+ IsValid = false ;
1742
+ break ;
1743
+ }
1744
+
1745
+ // Record debug use of each reg unit.
1746
+ SmallSet<MCRegister, 4 > RegUnits = getRegUnits (MO.getReg (), TRI);
1747
+ for (MCRegister Reg : RegUnits)
1748
+ MIUnits[Reg].push_back (MO.getReg ());
1749
+ }
1750
+ }
1751
+ if (IsValid) {
1752
+ for (auto RegOps : MIUnits)
1753
+ SeenDbgInstrs[RegOps.first ].push_back ({MI, RegOps.second });
1719
1754
}
1720
1755
continue ;
1721
1756
}
@@ -1757,18 +1792,22 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
1757
1792
// Collect DBG_VALUEs that must sink with this copy. We've previously
1758
1793
// recorded which reg units that DBG_VALUEs read, if this instruction
1759
1794
// writes any of those units then the corresponding DBG_VALUEs must sink.
1760
- SetVector <MachineInstr *> DbgValsToSinkSet ;
1795
+ MapVector <MachineInstr *, MIRegs::second_type> DbgValsToSinkMap ;
1761
1796
for (auto &MO : MI->operands ()) {
1762
1797
if (!MO.isReg () || !MO.isDef ())
1763
1798
continue ;
1764
1799
1765
1800
SmallSet<MCRegister, 4 > Units = getRegUnits (MO.getReg (), TRI);
1766
- for (MCRegister Reg : Units)
1767
- for (auto *MI : SeenDbgInstrs.lookup (Reg))
1768
- DbgValsToSinkSet.insert (MI);
1801
+ for (MCRegister Reg : Units) {
1802
+ for (auto MIRegs : SeenDbgInstrs.lookup (Reg)) {
1803
+ auto &Regs = DbgValsToSinkMap[MIRegs.first ];
1804
+ for (unsigned Reg : MIRegs.second )
1805
+ Regs.push_back (Reg);
1806
+ }
1807
+ }
1769
1808
}
1770
- SmallVector<MachineInstr * , 4 > DbgValsToSink (DbgValsToSinkSet .begin (),
1771
- DbgValsToSinkSet .end ());
1809
+ SmallVector<MIRegs , 4 > DbgValsToSink (DbgValsToSinkMap .begin (),
1810
+ DbgValsToSinkMap .end ());
1772
1811
1773
1812
// Clear the kill flag if SrcReg is killed between MI and the end of the
1774
1813
// block.
0 commit comments