@@ -105,6 +105,9 @@ namespace {
105
105
using AllSuccsCache =
106
106
std::map<MachineBasicBlock *, SmallVector<MachineBasicBlock *, 4 >>;
107
107
108
+ // Remember debug uses of vregs seen, so we know what to sink out of blocks.
109
+ DenseMap<unsigned , TinyPtrVector<MachineInstr *>> SeenDbgUsers;
110
+
108
111
public:
109
112
static char ID; // Pass identification
110
113
@@ -132,6 +135,7 @@ namespace {
132
135
133
136
private:
134
137
bool ProcessBlock (MachineBasicBlock &MBB);
138
+ void ProcessDbgInst (MachineInstr &MI);
135
139
bool isWorthBreakingCriticalEdge (MachineInstr &MI,
136
140
MachineBasicBlock *From,
137
141
MachineBasicBlock *To);
@@ -153,8 +157,14 @@ namespace {
153
157
MachineBasicBlock *To,
154
158
bool BreakPHIEdge);
155
159
bool SinkInstruction (MachineInstr &MI, bool &SawStore,
156
-
157
160
AllSuccsCache &AllSuccessors);
161
+
162
+ // / If we sink a COPY inst, some debug users of it's destination may no
163
+ // / longer be dominated by the COPY, and will eventually be dropped.
164
+ // / This is easily rectified by forwarding the non-dominated debug uses
165
+ // / to the copy source.
166
+ void SalvageUnsunkDebugUsersOfCopy (MachineInstr &,
167
+ MachineBasicBlock *TargetBlock);
158
168
bool AllUsesDominatedByBlock (unsigned Reg, MachineBasicBlock *MBB,
159
169
MachineBasicBlock *DefMBB,
160
170
bool &BreakPHIEdge, bool &LocalUse) const ;
@@ -367,8 +377,11 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
367
377
if (!ProcessedBegin)
368
378
--I;
369
379
370
- if (MI.isDebugInstr ())
380
+ if (MI.isDebugInstr ()) {
381
+ if (MI.isDebugValue ())
382
+ ProcessDbgInst (MI);
371
383
continue ;
384
+ }
372
385
373
386
bool Joined = PerformTrivialForwardCoalescing (MI, &MBB);
374
387
if (Joined) {
@@ -384,9 +397,23 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
384
397
// If we just processed the first instruction in the block, we're done.
385
398
} while (!ProcessedBegin);
386
399
400
+ SeenDbgUsers.clear ();
401
+
387
402
return MadeChange;
388
403
}
389
404
405
+ void MachineSinking::ProcessDbgInst (MachineInstr &MI) {
406
+ // When we see DBG_VALUEs for registers, record any vreg it reads, so that
407
+ // we know what to sink if the vreg def sinks.
408
+ assert (MI.isDebugValue () && " Expected DBG_VALUE for processing" );
409
+
410
+ MachineOperand &MO = MI.getOperand (0 );
411
+ if (!MO.isReg () || !MO.getReg ().isVirtual ())
412
+ return ;
413
+
414
+ SeenDbgUsers[MO.getReg ()].push_back (&MI);
415
+ }
416
+
390
417
bool MachineSinking::isWorthBreakingCriticalEdge (MachineInstr &MI,
391
418
MachineBasicBlock *From,
392
419
MachineBasicBlock *To) {
@@ -731,22 +758,13 @@ static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI,
731
758
MBP.LHS .getReg () == BaseOp->getReg ();
732
759
}
733
760
734
- // / Sink an instruction and its associated debug instructions. If the debug
735
- // / instructions to be sunk are already known, they can be provided in DbgVals.
761
+ // / Sink an instruction and its associated debug instructions.
736
762
static void performSink (MachineInstr &MI, MachineBasicBlock &SuccToSinkTo,
737
763
MachineBasicBlock::iterator InsertPos,
738
- SmallVectorImpl<MachineInstr *> *DbgVals = nullptr ) {
764
+ SmallVectorImpl<MachineInstr *> &DbgValuesToSink ) {
739
765
const MachineRegisterInfo &MRI = MI.getMF ()->getRegInfo ();
740
766
const TargetInstrInfo &TII = *MI.getMF ()->getSubtarget ().getInstrInfo ();
741
767
742
- // If debug values are provided use those, otherwise call collectDebugValues.
743
- SmallVector<MachineInstr *, 2 > DbgValuesToSink;
744
- if (DbgVals)
745
- DbgValuesToSink.insert (DbgValuesToSink.begin (),
746
- DbgVals->begin (), DbgVals->end ());
747
- else
748
- MI.collectDebugValues (DbgValuesToSink);
749
-
750
768
// If we cannot find a location to use (merge with), then we erase the debug
751
769
// location to prevent debug-info driven tools from potentially reporting
752
770
// wrong location information.
@@ -929,7 +947,25 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
929
947
while (InsertPos != SuccToSinkTo->end () && InsertPos->isPHI ())
930
948
++InsertPos;
931
949
932
- performSink (MI, *SuccToSinkTo, InsertPos);
950
+ // Collect debug users of any vreg that this inst defines.
951
+ SmallVector<MachineInstr *, 4 > DbgUsersToSink;
952
+ for (auto &MO : MI.operands ()) {
953
+ if (!MO.isReg () || !MO.isDef () || !MO.getReg ().isVirtual ())
954
+ continue ;
955
+ if (!SeenDbgUsers.count (MO.getReg ()))
956
+ continue ;
957
+
958
+ auto &Users = SeenDbgUsers[MO.getReg ()];
959
+ DbgUsersToSink.insert (DbgUsersToSink.end (), Users.begin (), Users.end ());
960
+ }
961
+
962
+ // After sinking, some debug users may not be dominated any more. If possible,
963
+ // copy-propagate their operands. As it's expensive, don't do this if there's
964
+ // no debuginfo in the program.
965
+ if (MI.getMF ()->getFunction ().getSubprogram () && MI.isCopy ())
966
+ SalvageUnsunkDebugUsersOfCopy (MI, SuccToSinkTo);
967
+
968
+ performSink (MI, *SuccToSinkTo, InsertPos, DbgUsersToSink);
933
969
934
970
// Conservatively, clear any kill flags, since it's possible that they are no
935
971
// longer correct.
@@ -944,6 +980,41 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
944
980
return true ;
945
981
}
946
982
983
+ void MachineSinking::SalvageUnsunkDebugUsersOfCopy (
984
+ MachineInstr &MI, MachineBasicBlock *TargetBlock) {
985
+ assert (MI.isCopy ());
986
+ assert (MI.getOperand (1 ).isReg ());
987
+
988
+ // Enumerate all users of vreg operands that are def'd. Skip those that will
989
+ // be sunk. For the rest, if they are not dominated by the block we will sink
990
+ // MI into, propagate the copy source to them.
991
+ SmallVector<MachineInstr *, 4 > DbgDefUsers;
992
+ const MachineRegisterInfo &MRI = MI.getMF ()->getRegInfo ();
993
+ for (auto &MO : MI.operands ()) {
994
+ if (!MO.isReg () || !MO.isDef () || !MO.getReg ().isVirtual ())
995
+ continue ;
996
+ for (auto &User : MRI.use_instructions (MO.getReg ())) {
997
+ if (!User.isDebugValue () || DT->dominates (TargetBlock, User.getParent ()))
998
+ continue ;
999
+
1000
+ // If is in same block, will either sink or be use-before-def.
1001
+ if (User.getParent () == MI.getParent ())
1002
+ continue ;
1003
+
1004
+ assert (User.getOperand (0 ).isReg () &&
1005
+ " DBG_VALUE user of vreg, but non reg operand?" );
1006
+ DbgDefUsers.push_back (&User);
1007
+ }
1008
+ }
1009
+
1010
+ // Point the users of this copy that are no longer dominated, at the source
1011
+ // of the copy.
1012
+ for (auto *User : DbgDefUsers) {
1013
+ User->getOperand (0 ).setReg (MI.getOperand (1 ).getReg ());
1014
+ User->getOperand (0 ).setSubReg (MI.getOperand (1 ).getSubReg ());
1015
+ }
1016
+ }
1017
+
947
1018
// ===----------------------------------------------------------------------===//
948
1019
// This pass is not intended to be a replacement or a complete alternative
949
1020
// for the pre-ra machine sink pass. It is only designed to sink COPY
@@ -1253,7 +1324,7 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
1253
1324
// block.
1254
1325
clearKillFlags (MI, CurBB, UsedOpsInCopy, UsedRegUnits, TRI);
1255
1326
MachineBasicBlock::iterator InsertPos = SuccBB->getFirstNonPHI ();
1256
- performSink (*MI, *SuccBB, InsertPos, & DbgValsToSink);
1327
+ performSink (*MI, *SuccBB, InsertPos, DbgValsToSink);
1257
1328
updateLiveIn (MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy);
1258
1329
1259
1330
Changed = true ;
0 commit comments