summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2014-12-10 01:13:04 +0000
committerMatthias Braun <matze@braunis.de>2014-12-10 01:13:04 +0000
commitd70caaf5a5ce376ddebe260cdc698615fc7d5d17 (patch)
treea365e22e31dbd10c5ea3242807dfc6d87b3da8d9 /llvm/lib/CodeGen
parent587e27415d94e6a09b2a9cce5555883fad378a9c (diff)
downloadbcm5719-llvm-d70caaf5a5ce376ddebe260cdc698615fc7d5d17.tar.gz
bcm5719-llvm-d70caaf5a5ce376ddebe260cdc698615fc7d5d17.zip
VirtRegMap: No implicit defs/uses for super registers with subreg liveness tracking.
Adding the implicit defs/uses to the superregisters is semantically questionable but was not dangerous before as the register allocator never assigned the same register to two overlapping LiveIntervals even when the actually live subregisters do not overlap. With subregister liveness tracking enabled this does actually happen and leads to subsequent bugs if we don't stop adding the superregister defs/uses. llvm-svn: 223892
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/LiveIntervalAnalysis.cpp24
-rw-r--r--llvm/lib/CodeGen/VirtRegMap.cpp14
2 files changed, 33 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
index dde55f9dd48..1e78259731b 100644
--- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -671,6 +671,30 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
CancelKill = true;
break;
}
+
+ // If an instruction writes to a subregister, a new segment starts in the
+ // LiveInterval. In this case adding Kill-Flags is incorrect if no
+ // super registers defs/uses are appended to the instruction which is
+ // what we do when subregister liveness tracking is enabled.
+ if (MRI->tracksSubRegLiveness()) {
+ // Next segment has to be adjacent in the subregister write case.
+ LiveRange::iterator N = std::next(RI);
+ if (N != LI->end() && N->start == RI->end) {
+ // See if we have a partial write operand
+ bool IsFullWrite = false;
+ for (MachineInstr::const_mop_iterator MOp = MI->operands_begin(),
+ MOpE = MI->operands_end(); MOp != MOpE; ++MOp) {
+ if (MOp->isReg() && !MOp->isDef() && MOp->getReg() == Reg
+ && MOp->getSubReg() == 0) {
+ IsFullWrite = true;
+ break;
+ }
+ }
+ if (!IsFullWrite)
+ CancelKill = true;
+ }
+ }
+
if (CancelKill)
MI->clearRegisterKills(Reg, nullptr);
else
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp
index 0d17d43d972..3d72d204ac4 100644
--- a/llvm/lib/CodeGen/VirtRegMap.cpp
+++ b/llvm/lib/CodeGen/VirtRegMap.cpp
@@ -266,6 +266,7 @@ void VirtRegRewriter::addMBBLiveIns() {
}
void VirtRegRewriter::rewrite() {
+ bool NoSubRegLiveness = !MRI->tracksSubRegLiveness();
SmallVector<unsigned, 8> SuperDeads;
SmallVector<unsigned, 8> SuperDefs;
SmallVector<unsigned, 8> SuperKills;
@@ -347,7 +348,8 @@ void VirtRegRewriter::rewrite() {
// A virtual register kill refers to the whole register, so we may
// have to add <imp-use,kill> operands for the super-register. A
// partial redef always kills and redefines the super-register.
- if (MO.readsReg() && (MO.isDef() || MO.isKill()))
+ if (NoSubRegLiveness && MO.readsReg()
+ && (MO.isDef() || MO.isKill()))
SuperKills.push_back(PhysReg);
if (MO.isDef()) {
@@ -358,10 +360,12 @@ void VirtRegRewriter::rewrite() {
MO.setIsUndef(false);
// Also add implicit defs for the super-register.
- if (MO.isDead())
- SuperDeads.push_back(PhysReg);
- else
- SuperDefs.push_back(PhysReg);
+ if (NoSubRegLiveness) {
+ if (MO.isDead())
+ SuperDeads.push_back(PhysReg);
+ else
+ SuperDefs.push_back(PhysReg);
+ }
}
// PhysReg operands cannot have subregister indexes.
OpenPOWER on IntegriCloud