OLD | NEW |
1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===// | 1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the Operand class and its | 10 // This file implements the Operand class and its |
(...skipping 18 matching lines...) Expand all Loading... |
29 } | 29 } |
30 | 30 |
31 bool operator<(const RegWeight &A, const RegWeight &B) { | 31 bool operator<(const RegWeight &A, const RegWeight &B) { |
32 return A.getWeight() < B.getWeight(); | 32 return A.getWeight() < B.getWeight(); |
33 } | 33 } |
34 bool operator<=(const RegWeight &A, const RegWeight &B) { return !(B < A); } | 34 bool operator<=(const RegWeight &A, const RegWeight &B) { return !(B < A); } |
35 bool operator==(const RegWeight &A, const RegWeight &B) { | 35 bool operator==(const RegWeight &A, const RegWeight &B) { |
36 return !(B < A) && !(A < B); | 36 return !(B < A) && !(A < B); |
37 } | 37 } |
38 | 38 |
| 39 void LiveRange::addSegment(int32_t Start, int32_t End) { |
| 40 #ifdef USE_SET |
| 41 RangeElementType Element(Start, End); |
| 42 RangeType::iterator Next = Range.lower_bound(Element); |
| 43 assert(Next == Range.upper_bound(Element)); // Element not already present |
| 44 |
| 45 // Beginning of code that merges contiguous segments. TODO: change |
| 46 // "if(true)" to "if(false)" to see if this extra optimization code |
| 47 // gives any performance gain, or is just destabilizing. |
| 48 if (true) { |
| 49 RangeType::iterator FirstDelete = Next; |
| 50 RangeType::iterator Prev = Next; |
| 51 bool hasPrev = (Next != Range.begin()); |
| 52 bool hasNext = (Next != Range.end()); |
| 53 if (hasPrev) |
| 54 --Prev; |
| 55 // See if Element and Next should be joined. |
| 56 if (hasNext && End == Next->first) { |
| 57 Element.second = Next->second; |
| 58 ++Next; |
| 59 } |
| 60 // See if Prev and Element should be joined. |
| 61 if (hasPrev && Prev->second == Start) { |
| 62 Element.first = Prev->first; |
| 63 FirstDelete = Prev; |
| 64 } |
| 65 Range.erase(FirstDelete, Next); |
| 66 } |
| 67 // End of code that merges contiguous segments. |
| 68 |
| 69 Range.insert(Next, Element); |
| 70 #else |
| 71 if (Range.empty()) { |
| 72 Range.push_back(RangeElementType(Start, End)); |
| 73 return; |
| 74 } |
| 75 // Special case for faking in-arg liveness. |
| 76 if (End < Range.front().first) { |
| 77 assert(Start < 0); |
| 78 Range.push_front(RangeElementType(Start, End)); |
| 79 return; |
| 80 } |
| 81 int32_t CurrentEnd = Range.back().second; |
| 82 assert(Start >= CurrentEnd); |
| 83 // Check for merge opportunity. |
| 84 if (Start == CurrentEnd) { |
| 85 Range.back().second = End; |
| 86 return; |
| 87 } |
| 88 Range.push_back(RangeElementType(Start, End)); |
| 89 #endif |
| 90 } |
| 91 |
| 92 // Returns true if this live range ends before Other's live range |
| 93 // starts. This means that the highest instruction number in this |
| 94 // live range is less than or equal to the lowest instruction number |
| 95 // of the Other live range. |
| 96 bool LiveRange::endsBefore(const LiveRange &Other) const { |
| 97 // Neither range should be empty, but let's be graceful. |
| 98 if (Range.empty() || Other.Range.empty()) |
| 99 return true; |
| 100 int32_t MyEnd = (*Range.rbegin()).second; |
| 101 int32_t OtherStart = (*Other.Range.begin()).first; |
| 102 return MyEnd <= OtherStart; |
| 103 } |
| 104 |
| 105 // Returns true if there is any overlap between the two live ranges. |
| 106 bool LiveRange::overlaps(const LiveRange &Other) const { |
| 107 // Do a two-finger walk through the two sorted lists of segments. |
| 108 RangeType::const_iterator I1 = Range.begin(), I2 = Other.Range.begin(); |
| 109 RangeType::const_iterator E1 = Range.end(), E2 = Other.Range.end(); |
| 110 while (I1 != E1 && I2 != E2) { |
| 111 if (I1->second <= I2->first) { |
| 112 ++I1; |
| 113 continue; |
| 114 } |
| 115 if (I2->second <= I1->first) { |
| 116 ++I2; |
| 117 continue; |
| 118 } |
| 119 return true; |
| 120 } |
| 121 return false; |
| 122 } |
| 123 |
| 124 // Returns true if the live range contains the given instruction |
| 125 // number. This is only used for validating the live range |
| 126 // calculation. |
| 127 bool LiveRange::containsValue(int32_t Value) const { |
| 128 for (RangeType::const_iterator I = Range.begin(), E = Range.end(); I != E; |
| 129 ++I) { |
| 130 if (I->first <= Value && Value <= I->second) |
| 131 return true; |
| 132 } |
| 133 return false; |
| 134 } |
| 135 |
39 void Variable::setUse(const Inst *Inst, const CfgNode *Node) { | 136 void Variable::setUse(const Inst *Inst, const CfgNode *Node) { |
40 if (DefNode == NULL) | 137 if (DefNode == NULL) |
41 return; | 138 return; |
42 if (llvm::isa<InstPhi>(Inst) || Node != DefNode) | 139 if (llvm::isa<InstPhi>(Inst) || Node != DefNode) |
43 DefNode = NULL; | 140 DefNode = NULL; |
44 } | 141 } |
45 | 142 |
46 void Variable::setDefinition(Inst *Inst, const CfgNode *Node) { | 143 void Variable::setDefinition(Inst *Inst, const CfgNode *Node) { |
47 if (DefNode == NULL) | 144 if (DefNode == NULL) |
48 return; | 145 return; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 int32_t Offset = getStackOffset(); | 205 int32_t Offset = getStackOffset(); |
109 if (Offset) { | 206 if (Offset) { |
110 if (Offset > 0) | 207 if (Offset > 0) |
111 Str << "+"; | 208 Str << "+"; |
112 Str << Offset; | 209 Str << Offset; |
113 } | 210 } |
114 Str << "]"; | 211 Str << "]"; |
115 } | 212 } |
116 } | 213 } |
117 | 214 |
118 void ConstantRelocatable::emit(const Cfg *Func) const { | 215 void ConstantRelocatable::emit(GlobalContext *Ctx) const { |
119 Ostream &Str = Func->getContext()->getStrEmit(); | 216 Ostream &Str = Ctx->getStrEmit(); |
120 if (SuppressMangling) | 217 if (SuppressMangling) |
121 Str << Name; | 218 Str << Name; |
122 else | 219 else |
123 Str << Func->getContext()->mangleName(Name); | 220 Str << Ctx->mangleName(Name); |
124 if (Offset) { | 221 if (Offset) { |
125 if (Offset > 0) | 222 if (Offset > 0) |
126 Str << "+"; | 223 Str << "+"; |
127 Str << Offset; | 224 Str << Offset; |
128 } | 225 } |
129 } | 226 } |
130 | 227 |
131 void ConstantRelocatable::dump(const Cfg *Func) const { | 228 void ConstantRelocatable::dump(GlobalContext *Ctx) const { |
132 Ostream &Str = Func->getContext()->getStrDump(); | 229 Ostream &Str = Ctx->getStrDump(); |
133 Str << "@" << Name; | 230 Str << "@" << Name; |
134 if (Offset) | 231 if (Offset) |
135 Str << "+" << Offset; | 232 Str << "+" << Offset; |
136 } | 233 } |
137 | 234 |
| 235 void LiveRange::dump(Ostream &Str) const { |
| 236 Str << "(weight=" << Weight << ") "; |
| 237 for (RangeType::const_iterator I = Range.begin(), E = Range.end(); I != E; |
| 238 ++I) { |
| 239 if (I != Range.begin()) |
| 240 Str << ", "; |
| 241 Str << "[" << (*I).first << ":" << (*I).second << ")"; |
| 242 } |
| 243 } |
| 244 |
| 245 Ostream &operator<<(Ostream &Str, const LiveRange &L) { |
| 246 L.dump(Str); |
| 247 return Str; |
| 248 } |
| 249 |
138 Ostream &operator<<(Ostream &Str, const RegWeight &W) { | 250 Ostream &operator<<(Ostream &Str, const RegWeight &W) { |
139 if (W.getWeight() == RegWeight::Inf) | 251 if (W.getWeight() == RegWeight::Inf) |
140 Str << "Inf"; | 252 Str << "Inf"; |
141 else | 253 else |
142 Str << W.getWeight(); | 254 Str << W.getWeight(); |
143 return Str; | 255 return Str; |
144 } | 256 } |
145 | 257 |
146 } // end of namespace Ice | 258 } // end of namespace Ice |
OLD | NEW |