Added LLVM copyright header.
[oota-llvm.git] / lib / Target / SparcV9 / RegAlloc / PhyRegAlloc.h
index 5922497f11e0e68709f7f67f2b31d79244a74bc9..7ab638f1c679042d569800e3f35c4c7d988a92f5 100644 (file)
@@ -1,43 +1,42 @@
-/* Title:   PhyRegAlloc.h   -*- C++ -*-
-   Author:  Ruchira Sasanka
-   Date:    Aug 20, 01
-   Purpose: This is the main entry point for register allocation.
-
-   Notes:
-   =====
-
- * RegisterClasses: Each RegClass accepts a 
-   MachineRegClass which contains machine specific info about that register
-   class. The code in the RegClass is machine independent and they use
-   access functions in the MachineRegClass object passed into it to get
-   machine specific info.
-
- * Machine dependent work: All parts of the register coloring algorithm
-   except coloring of an individual node are machine independent.
-
-   Register allocation must be done  as:       
-
-      MethodLiveVarInfo LVI(*MethodI );           // compute LV info
-      LVI.analyze();
-
-      TargetMachine &target = ....                             
-
-
-      PhyRegAlloc PRA(*MethodI, target, &LVI);     // allocate regs
-      PRA.allocateRegisters();
-*/ 
-
-#ifndef PHY_REG_ALLOC_H
-#define PHY_REG_ALLOC_H
-
-#include "llvm/CodeGen/RegClass.h"
-#include "llvm/CodeGen/LiveRangeInfo.h"
-#include <deque>
-class MachineCodeForMethod;
-class MachineRegInfo;
-class MethodLiveVarInfo;
+//===-- PhyRegAlloc.h - Graph Coloring Register Allocator -------*- c++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//   
+// This is the main entry point for register allocation.
+//
+// Notes:
+// * RegisterClasses: Each RegClass accepts a 
+//   TargetRegClass which contains machine specific info about that register
+//   class. The code in the RegClass is machine independent and they use
+//   access functions in the TargetRegClass object passed into it to get
+//   machine specific info.
+//
+// * Machine dependent work: All parts of the register coloring algorithm
+//   except coloring of an individual node are machine independent.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PHYREGALLOC_H
+#define PHYREGALLOC_H
+
+#include "LiveRangeInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetRegInfo.h"
+#include "llvm/Target/TargetMachine.h" 
+#include <map>
+
+class MachineFunction;
+class FunctionLiveVarInfo;
 class MachineInstr;
-namespace cfg { class LoopInfo; }
+class LoopInfo;
+class RegClass;
+class Constant;
 
 //----------------------------------------------------------------------------
 // Class AddedInstrns:
@@ -49,112 +48,128 @@ namespace cfg { class LoopInfo; }
 //----------------------------------------------------------------------------
 
 struct AddedInstrns {
-  std::deque<MachineInstr*> InstrnsBefore;// Added insts BEFORE an existing inst
-  std::deque<MachineInstr*> InstrnsAfter; // Added insts AFTER an existing inst
+  std::vector<MachineInstr*> InstrnsBefore;//Insts added BEFORE an existing inst
+  std::vector<MachineInstr*> InstrnsAfter; //Insts added AFTER an existing inst
+  inline void clear () { InstrnsBefore.clear (); InstrnsAfter.clear (); }
 };
 
-typedef std::map<const MachineInstr *, AddedInstrns> AddedInstrMapType;
-
-
-
 //----------------------------------------------------------------------------
 // class PhyRegAlloc:
-// Main class the register allocator. Call allocateRegisters() to allocate
+// Main class the register allocator. Call runOnFunction() to allocate
 // registers for a Function.
 //----------------------------------------------------------------------------
 
-
-class PhyRegAlloc: public NonCopyable {
-
+class PhyRegAlloc : public FunctionPass {
   std::vector<RegClass *> RegClassList; // vector of register classes
   const TargetMachine &TM;              // target machine
-  const Function *Meth;                 // name of the function we work on
-  MachineCodeForMethod &mcInfo;         // descriptor for method's native code
-  MethodLiveVarInfo *const LVI;         // LV information for this method 
+  const Function *Fn;                   // name of the function we work on
+  MachineFunction *MF;                  // descriptor for method's native code
+  FunctionLiveVarInfo *LVI;             // LV information for this method 
                                         // (already computed for BBs) 
-  LiveRangeInfo LRI;                    // LR info  (will be computed)
-  const MachineRegInfo &MRI;            // Machine Register information
+  LiveRangeInfo *LRI;                   // LR info  (will be computed)
+  const TargetRegInfo &MRI;             // Machine Register information
   const unsigned NumOfRegClasses;       // recorded here for efficiency
 
+  // Map to indicate whether operands of each MachineInstr have been
+  // updated according to their assigned colors.  This is only used in
+  // assertion checking (debug builds).
+  std::map<const MachineInstr *, bool> OperandsColoredMap;
   
-  AddedInstrMapType AddedInstrMap;      // to store instrns added in this phase
+  // AddedInstrMap - Used to store instrns added in this phase
+  std::map<const MachineInstr *, AddedInstrns> AddedInstrMap;
+
+  // ScratchRegsUsed - Contains scratch register uses for a particular MI.
+  typedef std::multimap<const MachineInstr*, int> ScratchRegsUsedTy;
+  ScratchRegsUsedTy ScratchRegsUsed;
+
   AddedInstrns AddedInstrAtEntry;       // to store instrns added at entry
-  cfg::LoopInfo *LoopDepthCalc;         // to calculate loop depths 
-  ReservedColorListType ResColList;     // A set of reserved regs if desired.
-                                        // currently not used
+  const LoopInfo *LoopDepthCalc;        // to calculate loop depths 
 
-public:
-  PhyRegAlloc(Function *F, const TargetMachine& TM, MethodLiveVarInfo *Lvi,
-              cfg::LoopInfo *LoopDepthCalc);
-  ~PhyRegAlloc();
+  std::map<const Function *, Constant *> FnAllocState;
 
-  // main method called for allocating registers
-  //
-  void allocateRegisters();           
+  PhyRegAlloc(const PhyRegAlloc&);     // DO NOT IMPLEMENT
+  void operator=(const PhyRegAlloc&);  // DO NOT IMPLEMENT
+public:
+  inline PhyRegAlloc (const TargetMachine &TM_) :
+    TM (TM_), MRI (TM.getRegInfo ()),
+    NumOfRegClasses (MRI.getNumOfRegClasses ()) { }
+  virtual ~PhyRegAlloc() { }
 
+  /// runOnFunction - Main method called for allocating registers.
+  ///
+  virtual bool runOnFunction (Function &F);
 
-  // access to register classes by class ID
-  // 
-  const RegClass*  getRegClassByID(unsigned int id) const {
-                                                    return RegClassList[id];
-  }
-        RegClass*  getRegClassByID(unsigned int id)       {
-                                                    return RegClassList[id]; }
-  
-  
-private:
+  virtual bool doFinalization (Module &M);
 
+  virtual void getAnalysisUsage (AnalysisUsage &AU) const;
 
+  const char *getPassName () const {
+    return "Traditional graph-coloring reg. allocator";
+  }
 
-  //------- ------------------ private methods---------------------------------
+  inline const RegClass* getRegClassByID(unsigned id) const {
+    return RegClassList[id];
+  }
+  inline RegClass *getRegClassByID(unsigned id) { return RegClassList[id]; }
 
+private:
   void addInterference(const Value *Def, const ValueSet *LVSet, 
                       bool isCallInst);
+  bool markAllocatedRegs(MachineInstr* MInst);
 
   void addInterferencesForArgs();
   void createIGNodeListsAndIGs();
   void buildInterferenceGraphs();
+  void saveState();
 
-  void setCallInterferences(const MachineInstr *MInst
-                           const ValueSet *LVSetAft );
+  void setCallInterferences(const MachineInstr *MI, 
+                           const ValueSet *LVSetAft);
 
   void move2DelayedInstr(const MachineInstr *OrigMI, 
-                        const MachineInstr *DelayedMI );
+                        const MachineInstr *DelayedMI);
 
   void markUnusableSugColors();
   void allocateStackSpace4SpilledLRs();
 
-  void insertCode4SpilledLR     (const LiveRange *LR, 
-                                 MachineInstr *MInst,
-                                 const BasicBlock *BB,
-                                 const unsigned OpNum);
+  void insertCode4SpilledLR(const LiveRange *LR, 
+                            MachineBasicBlock::iterator& MII,
+                            MachineBasicBlock &MBB, unsigned OpNum);
 
-  inline void constructLiveRanges() { LRI.constructLiveRanges(); }      
+  // Method for inserting caller saving code. The caller must save all the
+  // volatile registers live across a call.
+  void insertCallerSavingCode(std::vector<MachineInstr*>& instrnsBefore,
+                              std::vector<MachineInstr*>& instrnsAfter,
+                              MachineInstr *CallMI,
+                              const BasicBlock *BB);
 
   void colorIncomingArgs();
   void colorCallRetArgs();
   void updateMachineCode();
+  void updateInstruction(MachineBasicBlock::iterator& MII,
+                         MachineBasicBlock &MBB);
 
-  void printLabel(const Value *const Val);
-  void printMachineCode();
-
-  friend class UltraSparcRegInfo;
-
-
-  int getUsableUniRegAtMI(RegClass *RC, int RegType, 
-                         const MachineInstr *MInst,
-                         const ValueSet *LVSetBef, MachineInstr *&MIBef, 
-                         MachineInstr *&MIAft );
-
-  int getUnusedUniRegAtMI(RegClass *RC,  const MachineInstr *MInst, 
-                      const ValueSet *LVSetBef);
+  int getUsableUniRegAtMI(int RegType, const ValueSet *LVSetBef,
+                         MachineInstr *MI,
+                          std::vector<MachineInstr*>& MIBef,
+                          std::vector<MachineInstr*>& MIAft);
+  
+  // Callback method used to find unused registers. 
+  // LVSetBef is the live variable set to search for an unused register.
+  // If it is not specified, the LV set before the current MI is used.
+  // This is sufficient as long as no new copy instructions are generated
+  // to copy the free register to memory.
+  // 
+  int getUnusedUniRegAtMI(RegClass *RC, int RegType,
+                          const MachineInstr *MI,
+                          const ValueSet *LVSetBef = 0);
+  
+  void setRelRegsUsedByThisInst(RegClass *RC, int RegType,
+                                const MachineInstr *MI);
 
-  void setRelRegsUsedByThisInst(RegClass *RC, const MachineInstr *MInst );
-  int getUniRegNotUsedByThisInst(RegClass *RC, const MachineInstr *MInst);
+  int getUniRegNotUsedByThisInst(RegClass *RC, int RegType,
+                                 const MachineInstr *MI);
 
-  void addInterf4PseudoInstr(const MachineInstr *MInst);
+  void addInterf4PseudoInstr(const MachineInstr *MI);
 };
 
-
 #endif
-