[llvm-branch-commits] [llvm-branch] r106110 - in /llvm/branches/Apple/Troughton: ./ include/llvm/CodeGen/RegisterCoalescer.h lib/CodeGen/RegisterCoalescer.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp lib/CodeGen/SimpleRegisterCoalescing.h test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll
Jakob Stoklund Olesen
stoklund at 2pi.dk
Wed Jun 16 09:52:15 PDT 2010
Author: stoklund
Date: Wed Jun 16 11:52:15 2010
New Revision: 106110
URL: http://llvm.org/viewvc/llvm-project?rev=106110&view=rev
Log:
$ svn merge -c 105997 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r105997 into '.':
A test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll
U include/llvm/CodeGen/RegisterCoalescer.h
U lib/CodeGen/SimpleRegisterCoalescing.cpp
U lib/CodeGen/SimpleRegisterCoalescing.h
U lib/CodeGen/RegisterCoalescer.cpp
Added:
llvm/branches/Apple/Troughton/test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll
- copied unchanged from r105997, llvm/trunk/test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll
Modified:
llvm/branches/Apple/Troughton/ (props changed)
llvm/branches/Apple/Troughton/include/llvm/CodeGen/RegisterCoalescer.h
llvm/branches/Apple/Troughton/lib/CodeGen/RegisterCoalescer.cpp
llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.cpp
llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.h
Propchange: llvm/branches/Apple/Troughton/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jun 16 11:52:15 2010
@@ -1 +1 @@
-/llvm/trunk:105358,105361,105369,105372,105399,105427,105437,105439,105441,105470,105473,105481,105498,105541,105554,105557,105585-105586,105634,105653,105665,105669,105677,105745,105749,105774-105775,105836,105845,105862,105938,105959,105965,105969,105982,105990-105991,105998,106004,106021,106051
+/llvm/trunk:105358,105361,105369,105372,105399,105427,105437,105439,105441,105470,105473,105481,105498,105541,105554,105557,105585-105586,105634,105653,105665,105669,105677,105745,105749,105774-105775,105836,105845,105862,105938,105959,105965,105969,105982,105990-105991,105997-105998,106004,106021,106051
Modified: llvm/branches/Apple/Troughton/include/llvm/CodeGen/RegisterCoalescer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/include/llvm/CodeGen/RegisterCoalescer.h?rev=106110&r1=106109&r2=106110&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/include/llvm/CodeGen/RegisterCoalescer.h (original)
+++ llvm/branches/Apple/Troughton/include/llvm/CodeGen/RegisterCoalescer.h Wed Jun 16 11:52:15 2010
@@ -25,6 +25,9 @@
class RegallocQuery;
class AnalysisUsage;
class MachineInstr;
+ class TargetRegisterInfo;
+ class TargetRegisterClass;
+ class TargetInstrInfo;
/// An abstract interface for register coalescers. Coalescers must
/// implement this interface to be part of the coalescer analysis
@@ -141,6 +144,87 @@
return true;
}
};
+
+
+ /// CoalescerPair - A helper class for register coalescers. When deciding if
+ /// two registers can be coalesced, CoalescerPair can determine if a copy
+ /// instruction would become an identity copy after coalescing.
+ class CoalescerPair {
+ const TargetInstrInfo &tii_;
+ const TargetRegisterInfo &tri_;
+
+ /// dstReg_ - The register that will be left after coalescing. It can be a
+ /// virtual or physical register.
+ unsigned dstReg_;
+
+ /// srcReg_ - the virtual register that will be coalesced into dstReg.
+ unsigned srcReg_;
+
+ /// subReg_ - The subregister index of srcReg in dstReg_. It is possible the
+ /// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a
+ /// virtual register.
+ unsigned subIdx_;
+
+ /// partial_ - True when the original copy was a partial subregister copy.
+ bool partial_;
+
+ /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy
+ /// instruction.
+ bool flipped_;
+
+ /// newRC_ - The register class of the coalesced register, or NULL if dstReg_
+ /// is a physreg.
+ const TargetRegisterClass *newRC_;
+
+ /// compose - Compose subreg indices a and b, either may be 0.
+ unsigned compose(unsigned, unsigned) const;
+
+ /// isMoveInstr - Return true if MI is a move or subreg instruction.
+ bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst,
+ unsigned &SrcSub, unsigned &DstSub) const;
+
+ public:
+ CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri)
+ : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0),
+ partial_(false), flipped_(false), newRC_(0) {}
+
+ /// setRegisters - set registers to match the copy instruction MI. Return
+ /// false if MI is not a coalescable copy instruction.
+ bool setRegisters(const MachineInstr*);
+
+ /// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible
+ /// because dstReg_ is a physical register, or subIdx_ is set.
+ bool flip();
+
+ /// isCoalescable - Return true if MI is a copy instruction that will become
+ /// an identity copy after coalescing.
+ bool isCoalescable(const MachineInstr*) const;
+
+ /// isPhys - Return true if DstReg is a physical register.
+ bool isPhys() const { return !newRC_; }
+
+ /// isPartial - Return true if the original copy instruction did not copy the
+ /// full register, but was a subreg operation.
+ bool isPartial() const { return partial_; }
+
+ /// isFlipped - Return true when getSrcReg is the register being defined by
+ /// the original copy instruction.
+ bool isFlipped() const { return flipped_; }
+
+ /// getDstReg - Return the register (virtual or physical) that will remain
+ /// after coalescing.
+ unsigned getDstReg() const { return dstReg_; }
+
+ /// getSrcReg - Return the virtual register that will be coalesced away.
+ unsigned getSrcReg() const { return srcReg_; }
+
+ /// getSubIdx - Return the subregister index in DstReg that SrcReg will be
+ /// coalesced into, or 0.
+ unsigned getSubIdx() const { return subIdx_; }
+
+ /// getNewRC - Return the register class of the coalesced register.
+ const TargetRegisterClass *getNewRC() const { return newRC_; }
+ };
}
// Because of the way .a files work, we must force the SimpleRC
Modified: llvm/branches/Apple/Troughton/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/CodeGen/RegisterCoalescer.cpp?rev=106110&r1=106109&r2=106110&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/CodeGen/RegisterCoalescer.cpp Wed Jun 16 11:52:15 2010
@@ -16,6 +16,8 @@
#include "llvm/CodeGen/RegisterCoalescer.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Pass.h"
@@ -33,6 +35,151 @@
//
RegisterCoalescer::~RegisterCoalescer() {}
+unsigned CoalescerPair::compose(unsigned a, unsigned b) const {
+ if (!a) return b;
+ if (!b) return a;
+ return tri_.composeSubRegIndices(a, b);
+}
+
+bool CoalescerPair::isMoveInstr(const MachineInstr *MI,
+ unsigned &Src, unsigned &Dst,
+ unsigned &SrcSub, unsigned &DstSub) const {
+ if (MI->isExtractSubreg()) {
+ Dst = MI->getOperand(0).getReg();
+ DstSub = MI->getOperand(0).getSubReg();
+ Src = MI->getOperand(1).getReg();
+ SrcSub = compose(MI->getOperand(1).getSubReg(), MI->getOperand(2).getImm());
+ } else if (MI->isInsertSubreg() || MI->isSubregToReg()) {
+ Dst = MI->getOperand(0).getReg();
+ DstSub = compose(MI->getOperand(0).getSubReg(), MI->getOperand(3).getImm());
+ Src = MI->getOperand(2).getReg();
+ SrcSub = MI->getOperand(2).getSubReg();
+ } else if (!tii_.isMoveInstr(*MI, Src, Dst, SrcSub, DstSub)) {
+ return false;
+ }
+ return true;
+}
+
+bool CoalescerPair::setRegisters(const MachineInstr *MI) {
+ srcReg_ = dstReg_ = subIdx_ = 0;
+ newRC_ = 0;
+ flipped_ = false;
+
+ unsigned Src, Dst, SrcSub, DstSub;
+ if (!isMoveInstr(MI, Src, Dst, SrcSub, DstSub))
+ return false;
+ partial_ = SrcSub || DstSub;
+
+ // If one register is a physreg, it must be Dst.
+ if (TargetRegisterInfo::isPhysicalRegister(Src)) {
+ if (TargetRegisterInfo::isPhysicalRegister(Dst))
+ return false;
+ std::swap(Src, Dst);
+ std::swap(SrcSub, DstSub);
+ flipped_ = true;
+ }
+
+ const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
+
+ if (TargetRegisterInfo::isPhysicalRegister(Dst)) {
+ // Eliminate DstSub on a physreg.
+ if (DstSub) {
+ Dst = tri_.getSubReg(Dst, DstSub);
+ if (!Dst) return false;
+ DstSub = 0;
+ }
+
+ // Eliminate SrcSub by picking a corresponding Dst superregister.
+ if (SrcSub) {
+ Dst = tri_.getMatchingSuperReg(Dst, SrcSub, MRI.getRegClass(Src));
+ if (!Dst) return false;
+ SrcSub = 0;
+ } else if (!MRI.getRegClass(Src)->contains(Dst)) {
+ return false;
+ }
+ } else {
+ // Both registers are virtual.
+
+ // Identical sub to sub.
+ if (SrcSub == DstSub)
+ SrcSub = DstSub = 0;
+ else if (SrcSub && DstSub)
+ return false; // FIXME: Qreg:ssub_3 + Dreg:ssub_1 => QReg:dsub_1 + Dreg.
+
+ // There can be no SrcSub.
+ if (SrcSub) {
+ std::swap(Src, Dst);
+ DstSub = SrcSub;
+ SrcSub = 0;
+ assert(!flipped_ && "Unexpected flip");
+ flipped_ = true;
+ }
+
+ // Find the new register class.
+ const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
+ const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
+ if (DstSub)
+ newRC_ = tri_.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
+ else
+ newRC_ = getCommonSubClass(DstRC, SrcRC);
+ if (!newRC_)
+ return false;
+ }
+ // Check our invariants
+ assert(TargetRegisterInfo::isVirtualRegister(Src) && "Src must be virtual");
+ assert(!(TargetRegisterInfo::isPhysicalRegister(Dst) && DstSub) &&
+ "Cannot have a physical SubIdx");
+ srcReg_ = Src;
+ dstReg_ = Dst;
+ subIdx_ = DstSub;
+ return true;
+}
+
+bool CoalescerPair::flip() {
+ if (subIdx_ || TargetRegisterInfo::isPhysicalRegister(dstReg_))
+ return false;
+ std::swap(srcReg_, dstReg_);
+ flipped_ = !flipped_;
+ return true;
+}
+
+bool CoalescerPair::isCoalescable(const MachineInstr *MI) const {
+ if (!MI)
+ return false;
+ unsigned Src, Dst, SrcSub, DstSub;
+ if (!isMoveInstr(MI, Src, Dst, SrcSub, DstSub))
+ return false;
+
+ // Find the virtual register that is srcReg_.
+ if (Dst == srcReg_) {
+ std::swap(Src, Dst);
+ std::swap(SrcSub, DstSub);
+ } else if (Src != srcReg_) {
+ return false;
+ }
+
+ // Now check that Dst matches dstReg_.
+ if (TargetRegisterInfo::isPhysicalRegister(dstReg_)) {
+ if (!TargetRegisterInfo::isPhysicalRegister(Dst))
+ return false;
+ assert(!subIdx_ && "Inconsistent CoalescerPair state.");
+ // DstSub could be set for a physreg from INSERT_SUBREG.
+ if (DstSub)
+ Dst = tri_.getSubReg(Dst, DstSub);
+ // Full copy of Src.
+ if (!SrcSub)
+ return dstReg_ == Dst;
+ // This is a partial register copy. Check that the parts match.
+ return tri_.getSubReg(dstReg_, SrcSub) == Dst;
+ } else {
+ // dstReg_ is virtual.
+ if (dstReg_ != Dst)
+ return false;
+ // Registers match, do the subregisters line up?
+ return compose(subIdx_, SrcSub) == DstSub;
+ }
+}
+
// Because of the way .a files work, we must force the SimpleRC
// implementation to be pulled in if the RegisterCoalescer classes are
// pulled in. Otherwise we run the risk of RegisterCoalescer being
Modified: llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=106110&r1=106109&r2=106110&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.cpp Wed Jun 16 11:52:15 2010
@@ -1395,6 +1395,12 @@
return false; // Not coalescable.
}
+ CoalescerPair CP(*tii_, *tri_);
+ if (!CP.setRegisters(CopyMI)) {
+ DEBUG(dbgs() << "\tNot coalescable.\n");
+ return false;
+ }
+
bool SrcIsPhys = TargetRegisterInfo::isPhysicalRegister(SrcReg);
bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg);
@@ -1722,7 +1728,7 @@
DEBUG(dbgs() << "\tNot profitable!\n");
return false;
}
- } else if (!JoinIntervals(DstInt, SrcInt, Swapped)) {
+ } else if (!JoinIntervals(DstInt, SrcInt, Swapped, CP)) {
// Coalescing failed.
// If definition of source is defined by trivial computation, try
@@ -1919,33 +1925,13 @@
return std::find(V.begin(), V.end(), Val) != V.end();
}
-static bool isValNoDefMove(const MachineInstr *MI, unsigned DR, unsigned SR,
- const TargetInstrInfo *TII,
- const TargetRegisterInfo *TRI) {
- unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
- if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
- ;
- else if (MI->isExtractSubreg()) {
- DstReg = MI->getOperand(0).getReg();
- SrcReg = MI->getOperand(1).getReg();
- } else if (MI->isSubregToReg() ||
- MI->isInsertSubreg()) {
- DstReg = MI->getOperand(0).getReg();
- SrcReg = MI->getOperand(2).getReg();
- } else
- return false;
- return (SrcReg == SR || TRI->isSuperRegister(SR, SrcReg)) &&
- (DstReg == DR || TRI->isSuperRegister(DR, DstReg));
-}
-
/// RangeIsDefinedByCopyFromReg - Return true if the specified live range of
/// the specified live interval is defined by a copy from the specified
/// register.
-bool SimpleRegisterCoalescing::RangeIsDefinedByCopyFromReg(LiveInterval &li,
- LiveRange *LR,
- unsigned Reg) {
- unsigned SrcReg = li_->getVNInfoSourceReg(LR->valno);
- if (SrcReg == Reg)
+bool SimpleRegisterCoalescing::RangeIsDefinedByCopy(LiveInterval &li,
+ LiveRange *LR,
+ CoalescerPair &CP) {
+ if (CP.isCoalescable(LR->valno->getCopy()))
return true;
// FIXME: Do isPHIDef and isDefAccurate both need to be tested?
if ((LR->valno->isPHIDef() || !LR->valno->isDefAccurate()) &&
@@ -1954,7 +1940,7 @@
// It's a sub-register live interval, we may not have precise information.
// Re-compute it.
MachineInstr *DefMI = li_->getInstructionFromIndex(LR->start);
- if (DefMI && isValNoDefMove(DefMI, li.reg, Reg, tii_, tri_)) {
+ if (CP.isCoalescable(DefMI)) {
// Cache computed info.
LR->valno->def = LR->start;
LR->valno->setCopy(DefMI);
@@ -1986,7 +1972,8 @@
/// value number and that the RHS is not defined by a copy from this
/// interval. This returns false if the intervals are not joinable, or it
/// joins them and returns true.
-bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS){
+bool SimpleRegisterCoalescing::SimpleJoin(LiveInterval &LHS, LiveInterval &RHS,
+ CoalescerPair &CP) {
assert(RHS.containsOneValue());
// Some number (potentially more than one) value numbers in the current
@@ -2028,7 +2015,7 @@
if (LHSIt->valno->hasRedefByEC())
return false;
// Copy from the RHS?
- if (!RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg))
+ if (!RangeIsDefinedByCopy(LHS, LHSIt, CP))
return false; // Nope, bail out.
if (ValueLiveAt(LHSIt, LHS.end(), RHSIt->valno->def))
@@ -2072,7 +2059,7 @@
return false;
// Otherwise, if this is a copy from the RHS, mark it as being merged
// in.
- if (RangeIsDefinedByCopyFromReg(LHS, LHSIt, RHS.reg)) {
+ if (RangeIsDefinedByCopy(LHS, LHSIt, CP)) {
if (ValueLiveAt(LHSIt, LHS.end(), RHSIt->valno->def))
// Here is an interesting situation:
// BB1:
@@ -2171,7 +2158,7 @@
/// below to update aliases.
bool
SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
- bool &Swapped) {
+ bool &Swapped, CoalescerPair &CP) {
// Compute the final value assignment, assuming that the live ranges can be
// coalesced.
SmallVector<int, 16> LHSValNoAssignments;
@@ -2252,7 +2239,7 @@
// faster checks to see if the live ranges are coalescable. This joiner
// can't swap the LHS/RHS intervals though.
if (!TargetRegisterInfo::isPhysicalRegister(RHS.reg)) {
- return SimpleJoin(LHS, RHS);
+ return SimpleJoin(LHS, RHS, CP);
} else {
RHSValNoInfo = RHSValNoInfo0;
}
@@ -2318,7 +2305,7 @@
// DstReg is known to be a register in the LHS interval. If the src is
// from the RHS interval, we can use its value #.
- if (li_->getVNInfoSourceReg(VNI) != RHS.reg)
+ if (!CP.isCoalescable(VNI->getCopy()))
continue;
// Figure out the value # from the RHS.
@@ -2338,7 +2325,7 @@
// DstReg is known to be a register in the RHS interval. If the src is
// from the LHS interval, we can use its value #.
- if (li_->getVNInfoSourceReg(VNI) != LHS.reg)
+ if (!CP.isCoalescable(VNI->getCopy()))
continue;
// Figure out the value # from the LHS.
Modified: llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.h?rev=106110&r1=106109&r2=106110&view=diff
==============================================================================
--- llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/branches/Apple/Troughton/lib/CodeGen/SimpleRegisterCoalescing.h Wed Jun 16 11:52:15 2010
@@ -111,14 +111,15 @@
/// physreg, this method always canonicalizes DestInt to be it. The output
/// "SrcInt" will not have been modified, so we can use this information
/// below to update aliases.
- bool JoinIntervals(LiveInterval &LHS, LiveInterval &RHS, bool &Swapped);
+ bool JoinIntervals(LiveInterval &LHS, LiveInterval &RHS, bool &Swapped,
+ CoalescerPair &CP);
/// SimpleJoin - Attempt to join the specified interval into this one. The
/// caller of this method must guarantee that the RHS only contains a single
/// value number and that the RHS is not defined by a copy from this
/// interval. This returns false if the intervals are not joinable, or it
/// joins them and returns true.
- bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS);
+ bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS, CoalescerPair &CP);
/// Return true if the two specified registers belong to different register
/// classes. The registers may be either phys or virt regs.
@@ -210,11 +211,10 @@
bool ValueLiveAt(LiveInterval::iterator LRItr, LiveInterval::iterator LREnd,
SlotIndex defPoint) const;
- /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of
- /// the specified live interval is defined by a copy from the specified
- /// register.
- bool RangeIsDefinedByCopyFromReg(LiveInterval &li, LiveRange *LR,
- unsigned Reg);
+ /// RangeIsDefinedByCopy - Return true if the specified live range of the
+ /// specified live interval is defined by a coalescable copy.
+ bool RangeIsDefinedByCopy(LiveInterval &li, LiveRange *LR,
+ CoalescerPair &CP);
/// UpdateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and
/// update the subregister number if it is not zero. If DstReg is a
More information about the llvm-branch-commits
mailing list