Update comment to remove special case for vector extending loads. An
[oota-llvm.git] / include / llvm / CodeGen / RegisterCoalescer.h
index 5ee771c065504abba8d54d1f9a93839f4d55c509..7644433a33a15d2b13404027517ca4749573f3da 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/System/IncludeFile.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/LiveIntervalAnalysis.h"
-#include "llvm/CodeGen/LiveVariables.h"
-#include "llvm/Target/MRegisterInfo.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/ADT/SmallPtrSet.h"
 
 #ifndef LLVM_CODEGEN_REGISTER_COALESCER_H
 #define LLVM_CODEGEN_REGISTER_COALESCER_H
 
-namespace llvm 
-{
+namespace llvm {
+
   class MachineFunction;
   class RegallocQuery;
   class AnalysisUsage;
-  class LiveIntervals;
   class MachineInstr;
-  class MRegisterInfo;
+  class TargetRegisterInfo;
+  class TargetRegisterClass;
+  class TargetInstrInfo;
 
   /// An abstract interface for register coalescers.  Coalescers must
   /// implement this interface to be part of the coalescer analysis
@@ -47,7 +45,7 @@ namespace llvm
 
     /// Reset state.  Can be used to allow a coalescer run by
     /// PassManager to be run again by the register allocator.
-    virtual void reset(MachineFunction &mf) {};
+    virtual void reset(MachineFunction &mf) {}
 
     /// Register allocators must call this from their own
     /// getAnalysisUsage to cover the case where the coalescer is not
@@ -56,7 +54,7 @@ namespace llvm
     /// which to invalidate when running the register allocator or any
     /// pass that might call coalescing.  The long-term solution is to
     /// allow hierarchies of PassManagers.
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {};
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {}
   }; 
 
   /// An abstract interface for register allocators to interact with
@@ -69,11 +67,11 @@ namespace llvm
   ///
   ///   class LinearScanRegallocQuery : public RegallocQuery {
   ///   private:
-  ///     const LiveIntervals &li;
+  ///     const LiveIntervals \&li;
   ///
   ///   public:
   ///     LinearScanRegallocQuery(LiveIntervals &intervals) 
-  ///         : li(intervals) {};
+  ///         : li(intervals) {}
   ///
   ///     /// This is pretty slow and conservative, but since linear scan
   ///     /// allocation doesn't pre-compute interference information it's
@@ -90,14 +88,14 @@ namespace llvm
   ///           interferences.insert(&iv->second);
   ///         }
   ///       }
-  ///     };
+  ///     }
   ///
   ///     /// This is *really* slow and stupid.  See above.
   ///     int getNumberOfInterferences(const LiveInterval &a) const {
   ///       IntervalSet intervals;
   ///       getInterferences(intervals, a);
-  ///       return(intervals.size());
-  ///     };
+  ///       return intervals.size();
+  ///     }
   ///   };  
   ///
   ///   In the allocator:
@@ -113,14 +111,14 @@ namespace llvm
   public:
     typedef SmallPtrSet<const LiveInterval *, 8> IntervalSet;
 
-    virtual ~RegallocQuery() {};
+    virtual ~RegallocQuery() {}
     
     /// Return whether two live ranges interfere.
     virtual bool interfere(const LiveInterval &a,
                            const LiveInterval &b) const {
       // A naive test
-      return(a.overlaps(b));
-    };
+      return a.overlaps(b);
+    }
 
     /// Return the set of intervals that interfere with this one.
     virtual void getInterferences(IntervalSet &interferences,
@@ -134,7 +132,7 @@ namespace llvm
     /// coalescing or other modifications.
     virtual void updateDataForMerge(const LiveInterval &a,
                                     const LiveInterval &b,
-                                    const MachineInstr &copy) {};
+                                    const MachineInstr &copy) {}
 
     /// Allow the register allocator to communicate when it doesn't
     /// want a copy coalesced.  This may be due to assumptions made by
@@ -146,6 +144,93 @@ namespace llvm
       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_;
+
+    /// crossClass_ - True when both regs are virtual, and newRC is constrained.
+    bool crossClass_;
+
+    /// 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), crossClass_(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_; }
+
+    /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's.
+    bool isCrossClass() const { return crossClass_; }
+
+    /// 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