Be a bit more efficient when processing the active and inactive
[oota-llvm.git] / lib / Target / SparcV9 / RegAlloc / LiveRange.h
1 //===-- LiveRange.h - Store info about a live range -------------*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // Implements a live range using a SetVector of Value *s.  We keep only
11 // defs in a LiveRange.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LIVERANGE_H
16 #define LIVERANGE_H
17
18 #include "llvm/Value.h"
19 #include "Support/SetVector.h"
20 #include <iostream>
21
22 namespace llvm {
23
24 class RegClass;
25 class IGNode;
26
27 class LiveRange {
28 public:
29   typedef SetVector<const Value *> ValueContainerType;
30   typedef ValueContainerType::iterator iterator;
31   typedef ValueContainerType::const_iterator const_iterator;
32
33 private:
34   ValueContainerType MyValues; // Values in this LiveRange
35   RegClass *MyRegClass;        // register class (e.g., int, FP) for this LR
36
37   /// doesSpanAcrossCalls - Does this live range span across calls? 
38   /// This information is used by graph coloring algo to avoid allocating
39   /// volatile colors to live ranges that span across calls (since they have to
40   /// be saved/restored)
41   ///
42   bool doesSpanAcrossCalls;
43
44   IGNode *UserIGNode;         // IGNode which uses this LR
45   int Color;                  // color assigned to this live range
46   bool mustSpill;             // whether this LR must be spilt
47
48   /// SuggestedColor - if this LR has a suggested color, can it
49   /// really be allocated?  A suggested color cannot be allocated when the
50   /// suggested color is volatile and when there are call
51   /// interferences.
52   ///
53   int SuggestedColor;        // The suggested color for this LR
54
55   /// CanUseSuggestedCol - It is possible that a suggested color for
56   /// this live range is not available before graph coloring (e.g., it
57   /// can be allocated to another live range which interferes with
58   /// this)
59   /// 
60   bool CanUseSuggestedCol;
61
62   /// SpilledStackOffsetFromFP - If this LR is spilled, its stack
63   /// offset from *FP*. The spilled offsets must always be relative to
64   /// the FP.
65   ///
66   int SpilledStackOffsetFromFP;
67
68   /// HasSpillOffset - True iff this live range has a spill offset.
69   ///
70   bool HasSpillOffset;
71
72   /// SpillCost - The spill cost of this live range. Calculated using loop depth
73   /// of each reference to each Value in the live range.
74   ///
75   unsigned SpillCost;
76
77 public:
78   iterator        begin()       { return MyValues.begin();    }
79   const_iterator  begin() const { return MyValues.begin();    }
80   iterator          end()       { return MyValues.end();      }
81   const_iterator    end() const { return MyValues.end();      }
82   bool insert(const Value *&X)  { return MyValues.insert (X); }
83   void insert(iterator b, iterator e) { MyValues.insert (b, e); }
84
85   LiveRange() {
86     Color = SuggestedColor = -1;        // not yet colored 
87     mustSpill = false;
88     MyRegClass = 0;
89     UserIGNode = 0;
90     doesSpanAcrossCalls = false;
91     CanUseSuggestedCol = true;
92     HasSpillOffset = false;
93     SpillCost = 0;
94   }
95
96   void setRegClass(RegClass *RC) { MyRegClass = RC; }
97
98   RegClass *getRegClass() const { assert(MyRegClass); return MyRegClass; }
99   unsigned getRegClassID() const;
100
101   bool hasColor() const { return Color != -1; }
102   
103   unsigned getColor() const { assert(Color != -1); return (unsigned)Color; }
104
105   void setColor(unsigned Col) { Color = (int)Col; }
106
107   inline void setCallInterference() { 
108     doesSpanAcrossCalls = 1;
109   }
110   inline void clearCallInterference() { 
111     doesSpanAcrossCalls = 0;
112   }
113
114   inline bool isCallInterference() const { 
115     return doesSpanAcrossCalls == 1; 
116   } 
117
118   inline void markForSpill() { mustSpill = true; }
119
120   inline bool isMarkedForSpill() const { return mustSpill; }
121
122   inline void setSpillOffFromFP(int StackOffset) {
123     assert(mustSpill && "This LR is not spilled");
124     SpilledStackOffsetFromFP = StackOffset;
125     HasSpillOffset = true;
126   }
127
128   inline void modifySpillOffFromFP(int StackOffset) {
129     assert(mustSpill && "This LR is not spilled");
130     SpilledStackOffsetFromFP = StackOffset;
131     HasSpillOffset = true;
132   }
133
134   inline bool hasSpillOffset() const {
135     return HasSpillOffset;
136   }
137
138   inline int getSpillOffFromFP() const {
139     assert(HasSpillOffset && "This LR is not spilled");
140     return SpilledStackOffsetFromFP;
141   }
142
143   inline void setUserIGNode(IGNode *IGN) {
144     assert(!UserIGNode); UserIGNode = IGN;
145   }
146
147   // getUserIGNode - NULL if the user is not allocated
148   inline IGNode *getUserIGNode() const { return UserIGNode; }
149
150   inline const Type *getType() const {
151     return (*begin())->getType();  // set's don't have a front
152   }
153   
154   inline void setSuggestedColor(int Col) {
155     if (SuggestedColor == -1)
156       SuggestedColor = Col;
157   }
158
159   inline unsigned getSuggestedColor() const {
160     assert(SuggestedColor != -1);      // only a valid color is obtained
161     return (unsigned)SuggestedColor;
162   }
163
164   inline bool hasSuggestedColor() const {
165     return SuggestedColor != -1;
166   }
167
168   inline bool isSuggestedColorUsable() const {
169     assert(hasSuggestedColor() && "No suggested color");
170     return CanUseSuggestedCol;
171   }
172
173   inline void setSuggestedColorUsable(bool val) {
174     assert(hasSuggestedColor() && "No suggested color");
175     CanUseSuggestedCol = val;
176   }
177
178   inline void addSpillCost(unsigned cost) {
179     SpillCost += cost;
180   }
181
182   inline unsigned getSpillCost() const {
183     return SpillCost;
184   }
185 };
186
187 static inline std::ostream &operator << (std::ostream &os, const LiveRange &lr) {
188   os << "LiveRange@" << (void *)(&lr);
189   return os;
190 };
191
192 } // End llvm namespace
193
194 #endif