summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse.llvm@gmail.com>2019-08-19 09:53:07 +0000
committerJeremy Morse <jeremy.morse.llvm@gmail.com>2019-08-19 09:53:07 +0000
commit176bbd5cde362ad965dcda5cc72b655117685a5a (patch)
tree5240dd93e0201d521712863fa8221ef9dc05cd05 /llvm/lib/CodeGen/MachineSink.cpp
parent2cafd872fb97f2899ac0f1b01ed82ee88581c86d (diff)
downloadbcm5719-llvm-176bbd5cde362ad965dcda5cc72b655117685a5a.tar.gz
bcm5719-llvm-176bbd5cde362ad965dcda5cc72b655117685a5a.zip
[DebugInfo] Make postra sinking of DBG_VALUEs subregister-safe
Currently the machine instruction sinker identifies DBG_VALUE insts that also need to sink by comparing register numbers. Unfortunately this isn't safe, because (after register allocation) a DBG_VALUE may read a register that aliases what's being sunk. To fix this, identify the DBG_VALUEs that need to sink by recording & examining their register units. Register units gives us the following guarantee: "Two registers overlap if and only if they have a common register unit" [MCRegisterInfo.h] Thus we can always identify aliasing DBG_VALUEs if the set of register units read by the DBG_VALUE, and the register units of the instruction being sunk, intersect. (MachineSink already uses classes like "LiveRegUnits" for determining sinking validity anyway). The test added checks for super and subregister DBG_VALUE reads of a sunk copy being sunk as well. Differential Revision: https://reviews.llvm.org/D58191 llvm-svn: 369247
Diffstat (limited to 'llvm/lib/CodeGen/MachineSink.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp37
1 files changed, 28 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index 3d5530d4b8d..8f0d436dfa5 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -36,8 +36,9 @@
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
@@ -957,8 +958,9 @@ private:
/// Track which register units have been modified and used.
LiveRegUnits ModifiedRegUnits, UsedRegUnits;
- /// Track DBG_VALUEs of (unmodified) register units.
- DenseMap<unsigned, TinyPtrVector<MachineInstr*>> SeenDbgInstrs;
+ /// Track DBG_VALUEs of (unmodified) register units. Each DBG_VALUE has an
+ /// entry in this map for each unit it touches.
+ DenseMap<unsigned, TinyPtrVector<MachineInstr *>> SeenDbgInstrs;
/// Sink Copy instructions unused in the same block close to their uses in
/// successors.
@@ -1093,6 +1095,14 @@ static bool hasRegisterDependency(MachineInstr *MI,
return HasRegDependency;
}
+static SmallSet<unsigned, 4> getRegUnits(unsigned Reg,
+ const TargetRegisterInfo *TRI) {
+ SmallSet<unsigned, 4> RegUnits;
+ for (auto RI = MCRegUnitIterator(Reg, TRI); RI.isValid(); ++RI)
+ RegUnits.insert(*RI);
+ return RegUnits;
+}
+
bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
MachineFunction &MF,
const TargetRegisterInfo *TRI,
@@ -1136,8 +1146,10 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
ModifiedRegUnits, UsedRegUnits))
continue;
- // Record debug use of this register.
- SeenDbgInstrs[MO.getReg()].push_back(MI);
+ // Record debug use of each reg unit.
+ SmallSet<unsigned, 4> Units = getRegUnits(MO.getReg(), TRI);
+ for (unsigned Reg : Units)
+ SeenDbgInstrs[Reg].push_back(MI);
}
continue;
}
@@ -1176,15 +1188,22 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
assert((SuccBB->pred_size() == 1 && *SuccBB->pred_begin() == &CurBB) &&
"Unexpected predecessor");
- // Collect DBG_VALUEs that must sink with this copy.
+ // Collect DBG_VALUEs that must sink with this copy. We've previously
+ // recorded which reg units that DBG_VALUEs read, if this instruction
+ // writes any of those units then the corresponding DBG_VALUEs must sink.
+ SetVector<MachineInstr *> DbgValsToSinkSet;
SmallVector<MachineInstr *, 4> DbgValsToSink;
for (auto &MO : MI->operands()) {
if (!MO.isReg() || !MO.isDef())
continue;
- Register reg = MO.getReg();
- for (auto *MI : SeenDbgInstrs.lookup(reg))
- DbgValsToSink.push_back(MI);
+
+ SmallSet<unsigned, 4> Units = getRegUnits(MO.getReg(), TRI);
+ for (unsigned Reg : Units)
+ for (auto *MI : SeenDbgInstrs.lookup(Reg))
+ DbgValsToSinkSet.insert(MI);
}
+ DbgValsToSink.insert(DbgValsToSink.begin(), DbgValsToSinkSet.begin(),
+ DbgValsToSinkSet.end());
// Clear the kill flag if SrcReg is killed between MI and the end of the
// block.
OpenPOWER on IntegriCloud