Add a LiveRangeEdit::Delegate protocol.
[oota-llvm.git] / lib / CodeGen / LiveRangeEdit.h
1 //===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // The LiveRangeEdit class represents changes done to a virtual register when it
11 // is spilled or split.
12 //
13 // The parent register is never changed. Instead, a number of new virtual
14 // registers are created and added to the newRegs vector.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_CODEGEN_LIVERANGEEDIT_H
19 #define LLVM_CODEGEN_LIVERANGEEDIT_H
20
21 #include "llvm/CodeGen/LiveInterval.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23
24 namespace llvm {
25
26 class AliasAnalysis;
27 class LiveIntervals;
28 class MachineRegisterInfo;
29 class VirtRegMap;
30
31 class LiveRangeEdit {
32 public:
33   /// Callback methods for LiveRangeEdit owners.
34   struct Delegate {
35     /// Called immediately before erasing a dead machine instruction.
36     virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
37   };
38
39 private:
40   LiveInterval &parent_;
41   SmallVectorImpl<LiveInterval*> &newRegs_;
42   Delegate *const delegate_;
43   const SmallVectorImpl<LiveInterval*> *uselessRegs_;
44
45   /// firstNew_ - Index of the first register added to newRegs_.
46   const unsigned firstNew_;
47
48   /// scannedRemattable_ - true when remattable values have been identified.
49   bool scannedRemattable_;
50
51   /// remattable_ - Values defined by remattable instructions as identified by
52   /// tii.isTriviallyReMaterializable().
53   SmallPtrSet<const VNInfo*,4> remattable_;
54
55   /// rematted_ - Values that were actually rematted, and so need to have their
56   /// live range trimmed or entirely removed.
57   SmallPtrSet<const VNInfo*,4> rematted_;
58
59   /// scanRemattable - Identify the parent_ values that may rematerialize.
60   void scanRemattable(LiveIntervals &lis,
61                       const TargetInstrInfo &tii,
62                       AliasAnalysis *aa);
63
64   /// allUsesAvailableAt - Return true if all registers used by OrigMI at
65   /// OrigIdx are also available with the same value at UseIdx.
66   bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
67                           SlotIndex UseIdx, LiveIntervals &lis);
68
69 public:
70   /// Create a LiveRangeEdit for breaking down parent into smaller pieces.
71   /// @param parent The register being spilled or split.
72   /// @param newRegs List to receive any new registers created. This needn't be
73   ///                empty initially, any existing registers are ignored.
74   /// @param uselessRegs List of registers that can't be used when
75   ///        rematerializing values because they are about to be removed.
76   LiveRangeEdit(LiveInterval &parent,
77                 SmallVectorImpl<LiveInterval*> &newRegs,
78                 Delegate *delegate,
79                 const SmallVectorImpl<LiveInterval*> *uselessRegs = 0)
80     : parent_(parent), newRegs_(newRegs),
81       delegate_(delegate),
82       uselessRegs_(uselessRegs),
83       firstNew_(newRegs.size()),
84       scannedRemattable_(false) {}
85
86   LiveInterval &getParent() const { return parent_; }
87   unsigned getReg() const { return parent_.reg; }
88
89   /// Iterator for accessing the new registers added by this edit.
90   typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator;
91   iterator begin() const { return newRegs_.begin()+firstNew_; }
92   iterator end() const { return newRegs_.end(); }
93   unsigned size() const { return newRegs_.size()-firstNew_; }
94   bool empty() const { return size() == 0; }
95   LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; }
96
97   /// create - Create a new register with the same class and stack slot as
98   /// parent.
99   LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&);
100
101   /// anyRematerializable - Return true if any parent values may be
102   /// rematerializable.
103   /// This function must be called before any rematerialization is attempted.
104   bool anyRematerializable(LiveIntervals&, const TargetInstrInfo&,
105                            AliasAnalysis*);
106
107   /// Remat - Information needed to rematerialize at a specific location.
108   struct Remat {
109     VNInfo *ParentVNI;      // parent_'s value at the remat location.
110     MachineInstr *OrigMI;   // Instruction defining ParentVNI.
111     explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {}
112   };
113
114   /// canRematerializeAt - Determine if ParentVNI can be rematerialized at
115   /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI.
116   /// When cheapAsAMove is set, only cheap remats are allowed.
117   bool canRematerializeAt(Remat &RM,
118                           SlotIndex UseIdx,
119                           bool cheapAsAMove,
120                           LiveIntervals &lis);
121
122   /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
123   /// instruction into MBB before MI. The new instruction is mapped, but
124   /// liveness is not updated.
125   /// Return the SlotIndex of the new instruction.
126   SlotIndex rematerializeAt(MachineBasicBlock &MBB,
127                             MachineBasicBlock::iterator MI,
128                             unsigned DestReg,
129                             const Remat &RM,
130                             LiveIntervals&,
131                             const TargetInstrInfo&,
132                             const TargetRegisterInfo&);
133
134   /// markRematerialized - explicitly mark a value as rematerialized after doing
135   /// it manually.
136   void markRematerialized(const VNInfo *ParentVNI) {
137     rematted_.insert(ParentVNI);
138   }
139
140   /// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
141   bool didRematerialize(const VNInfo *ParentVNI) const {
142     return rematted_.count(ParentVNI);
143   }
144
145   /// eliminateDeadDefs - Try to delete machine instructions that are now dead
146   /// (allDefsAreDead returns true). This may cause live intervals to be trimmed
147   /// and further dead efs to be eliminated.
148   void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
149                          LiveIntervals&,
150                          const TargetInstrInfo&);
151
152 };
153
154 }
155
156 #endif