summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2015-03-25 21:18:24 +0000
committerMatthias Braun <matze@braunis.de>2015-03-25 21:18:24 +0000
commit5d27ef6449e99d26c07a3d8f15e8ad80148e2fa7 (patch)
tree3d6ffdb530072380af0a7c7e56b9129da449797c /llvm/lib/CodeGen
parente962e52a4536bd5f2cba28aa47445fae7103d754 (diff)
downloadbcm5719-llvm-5d27ef6449e99d26c07a3d8f15e8ad80148e2fa7.tar.gz
bcm5719-llvm-5d27ef6449e99d26c07a3d8f15e8ad80148e2fa7.zip
RegisterCoalescer: Fix implicit def handling in register coalescer
If liveranges induced by an IMPLICIT_DEF get completely covered by a proper liverange the IMPLICIT_DEF instructions and its corresponding definitions have to be removed from the live ranges. This has to happen in the subregister live ranges as well (I didn't see this case earlier because in most programs only some subregisters are covered and the IMPLCIT_DEF won't get removed). No testcase, I spent hours trying to create one for one of the public targets, but ultimately failed because I couldn't manage to properly control the placement of COPY and IMPLICIT_DEF instructions from an .ll file. llvm-svn: 233217
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 47bd4cc2fae..fdec8957757 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -1758,6 +1758,9 @@ public:
void eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
SmallVectorImpl<unsigned> &ShrinkRegs);
+ /// Remove liverange defs at places where implicit defs will be removed.
+ void removeImplicitDefs();
+
/// Get the value assignments suitable for passing to LiveInterval::join.
const int *getAssignments() const { return Assignments.data(); }
};
@@ -1858,7 +1861,11 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
assert(DefMI != nullptr);
if (SubRangeJoin) {
// We don't care about the lanes when joining subregister ranges.
- V.ValidLanes = V.WriteLanes = 1;
+ V.WriteLanes = V.ValidLanes = 1;
+ if (DefMI->isImplicitDef()) {
+ V.ValidLanes = 0;
+ V.ErasableImplicitDef = true;
+ }
} else {
bool Redef = false;
V.ValidLanes = V.WriteLanes = computeWriteLanes(DefMI, Redef);
@@ -2341,6 +2348,18 @@ void JoinVals::pruneSubRegValues(LiveInterval &LI, unsigned &ShrinkMask)
LI.removeEmptySubRanges();
}
+void JoinVals::removeImplicitDefs() {
+ for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
+ Val &V = Vals[i];
+ if (V.Resolution != CR_Keep || !V.ErasableImplicitDef || !V.Pruned)
+ continue;
+
+ VNInfo *VNI = LR.getValNumInfo(i);
+ VNI->markUnused();
+ LR.removeValNo(VNI);
+ }
+}
+
void JoinVals::eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
SmallVectorImpl<unsigned> &ShrinkRegs) {
for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
@@ -2416,6 +2435,9 @@ bool RegisterCoalescer::joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
LHSVals.pruneValues(RHSVals, EndPoints, false);
RHSVals.pruneValues(LHSVals, EndPoints, false);
+ LHSVals.removeImplicitDefs();
+ RHSVals.removeImplicitDefs();
+
LRange.verify();
RRange.verify();
OpenPOWER on IntegriCloud