| OLD | NEW |
| 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// | 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan 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 /// \file | 10 /// \file |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 for (CfgNode *Node : Func->getNodes()) { | 125 for (CfgNode *Node : Func->getNodes()) { |
| 126 for (Inst &I : Node->getInsts()) { | 126 for (Inst &I : Node->getInsts()) { |
| 127 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) { | 127 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) { |
| 128 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted()) | 128 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted()) |
| 129 Kills.push_back(I.getNumber()); | 129 Kills.push_back(I.getNumber()); |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 | 134 |
| 135 // Validate the integrity of the live ranges. If there are any errors, it |
| 136 // prints details and returns false. On success, it returns true. |
| 137 bool LinearScan::livenessValidateIntervals( |
| 138 const DefUseErrorList &DefsWithoutUses, |
| 139 const DefUseErrorList &UsesBeforeDefs, |
| 140 const CfgVector<InstNumberT> &LRBegin, |
| 141 const CfgVector<InstNumberT> &LREnd) { |
| 142 if (DefsWithoutUses.empty() && UsesBeforeDefs.empty()) |
| 143 return true; |
| 144 |
| 145 if (!BuildDefs::dump()) |
| 146 return false; |
| 147 |
| 148 const VarList &Vars = Func->getVariables(); |
| 149 OstreamLocker L(Ctx); |
| 150 Ostream &Str = Ctx->getStrDump(); |
| 151 for (SizeT VarNum : DefsWithoutUses) { |
| 152 Variable *Var = Vars[VarNum]; |
| 153 Str << "LR def without use, instruction " << LRBegin[VarNum] |
| 154 << ", variable " << Var->getName(Func) << "\n"; |
| 155 } |
| 156 for (SizeT VarNum : UsesBeforeDefs) { |
| 157 Variable *Var = Vars[VarNum]; |
| 158 Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable " |
| 159 << Var->getName(Func) << "\n"; |
| 160 } |
| 161 return false; |
| 162 } |
| 163 |
| 135 // Prepare for very simple register allocation of only infinite-weight | 164 // Prepare for very simple register allocation of only infinite-weight |
| 136 // Variables while respecting pre-colored Variables. Some properties we take | 165 // Variables while respecting pre-colored Variables. Some properties we take |
| 137 // advantage of: | 166 // advantage of: |
| 138 // | 167 // |
| 139 // * Live ranges of interest consist of a single segment. | 168 // * Live ranges of interest consist of a single segment. |
| 140 // | 169 // |
| 141 // * Live ranges of interest never span a call instruction. | 170 // * Live ranges of interest never span a call instruction. |
| 142 // | 171 // |
| 143 // * Phi instructions are not considered because either phis have already been | 172 // * Phi instructions are not considered because either phis have already been |
| 144 // lowered, or they don't contain any pre-colored or infinite-weight | 173 // lowered, or they don't contain any pre-colored or infinite-weight |
| (...skipping 16 matching lines...) Expand all Loading... |
| 161 TimerMarker T(TimerStack::TT_initUnhandled, Func); | 190 TimerMarker T(TimerStack::TT_initUnhandled, Func); |
| 162 FindPreference = false; | 191 FindPreference = false; |
| 163 FindOverlap = false; | 192 FindOverlap = false; |
| 164 SizeT NumVars = 0; | 193 SizeT NumVars = 0; |
| 165 const VarList &Vars = Func->getVariables(); | 194 const VarList &Vars = Func->getVariables(); |
| 166 | 195 |
| 167 // Iterate across all instructions and record the begin and end of the live | 196 // Iterate across all instructions and record the begin and end of the live |
| 168 // range for each variable that is pre-colored or infinite weight. | 197 // range for each variable that is pre-colored or infinite weight. |
| 169 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); | 198 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); |
| 170 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); | 199 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); |
| 200 DefUseErrorList DefsWithoutUses, UsesBeforeDefs; |
| 171 for (CfgNode *Node : Func->getNodes()) { | 201 for (CfgNode *Node : Func->getNodes()) { |
| 172 for (Inst &Inst : Node->getInsts()) { | 202 for (Inst &Inst : Node->getInsts()) { |
| 173 if (Inst.isDeleted()) | 203 if (Inst.isDeleted()) |
| 174 continue; | 204 continue; |
| 205 FOREACH_VAR_IN_INST(Var, Inst) { |
| 206 if (Var->getIgnoreLiveness()) |
| 207 continue; |
| 208 if (Var->hasReg() || Var->mustHaveReg()) { |
| 209 SizeT VarNum = Var->getIndex(); |
| 210 LREnd[VarNum] = Inst.getNumber(); |
| 211 if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel) |
| 212 UsesBeforeDefs.push_back(VarNum); |
| 213 } |
| 214 } |
| 175 if (const Variable *Var = Inst.getDest()) { | 215 if (const Variable *Var = Inst.getDest()) { |
| 176 if (!Var->getIgnoreLiveness() && | 216 if (!Var->getIgnoreLiveness() && |
| 177 (Var->hasReg() || Var->mustHaveReg())) { | 217 (Var->hasReg() || Var->mustHaveReg())) { |
| 178 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { | 218 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { |
| 179 LRBegin[Var->getIndex()] = Inst.getNumber(); | 219 LRBegin[Var->getIndex()] = Inst.getNumber(); |
| 180 ++NumVars; | 220 ++NumVars; |
| 181 } | 221 } |
| 182 } | 222 } |
| 183 } | 223 } |
| 184 FOREACH_VAR_IN_INST(Var, Inst) { | |
| 185 if (Var->getIgnoreLiveness()) | |
| 186 continue; | |
| 187 if (Var->hasReg() || Var->mustHaveReg()) | |
| 188 LREnd[Var->getIndex()] = Inst.getNumber(); | |
| 189 } | |
| 190 } | 224 } |
| 191 } | 225 } |
| 192 | 226 |
| 193 Unhandled.reserve(NumVars); | 227 Unhandled.reserve(NumVars); |
| 194 UnhandledPrecolored.reserve(NumVars); | 228 UnhandledPrecolored.reserve(NumVars); |
| 195 for (SizeT i = 0; i < Vars.size(); ++i) { | 229 for (SizeT i = 0; i < Vars.size(); ++i) { |
| 196 Variable *Var = Vars[i]; | 230 Variable *Var = Vars[i]; |
| 197 if (LRBegin[i] != Inst::NumberSentinel) { | 231 if (LRBegin[i] != Inst::NumberSentinel) { |
| 198 assert(LREnd[i] != Inst::NumberSentinel); | 232 if (LREnd[i] == Inst::NumberSentinel) { |
| 233 DefsWithoutUses.push_back(i); |
| 234 continue; |
| 235 } |
| 199 Unhandled.push_back(Var); | 236 Unhandled.push_back(Var); |
| 200 Var->resetLiveRange(); | 237 Var->resetLiveRange(); |
| 201 Var->addLiveRange(LRBegin[i], LREnd[i]); | 238 Var->addLiveRange(LRBegin[i], LREnd[i]); |
| 202 Var->untrimLiveRange(); | 239 Var->untrimLiveRange(); |
| 203 if (Var->hasReg()) { | 240 if (Var->hasReg()) { |
| 204 Var->setRegNumTmp(Var->getRegNum()); | 241 Var->setRegNumTmp(Var->getRegNum()); |
| 205 Var->setMustHaveReg(); | 242 Var->setMustHaveReg(); |
| 206 UnhandledPrecolored.push_back(Var); | 243 UnhandledPrecolored.push_back(Var); |
| 207 } | 244 } |
| 208 --NumVars; | 245 --NumVars; |
| 209 } | 246 } |
| 210 } | 247 } |
| 248 |
| 249 if (!livenessValidateIntervals(DefsWithoutUses, UsesBeforeDefs, LRBegin, |
| 250 LREnd)) { |
| 251 llvm::report_fatal_error("initForInfOnly: Liveness error"); |
| 252 return; |
| 253 } |
| 254 |
| 255 if (!DefsWithoutUses.empty() || !UsesBeforeDefs.empty()) { |
| 256 if (BuildDefs::dump()) { |
| 257 OstreamLocker L(Ctx); |
| 258 Ostream &Str = Ctx->getStrDump(); |
| 259 for (SizeT VarNum : DefsWithoutUses) { |
| 260 Variable *Var = Vars[VarNum]; |
| 261 Str << "LR def without use, instruction " << LRBegin[VarNum] |
| 262 << ", variable " << Var->getName(Func) << "\n"; |
| 263 } |
| 264 for (SizeT VarNum : UsesBeforeDefs) { |
| 265 Variable *Var = Vars[VarNum]; |
| 266 Str << "LR use before def, instruction " << LREnd[VarNum] |
| 267 << ", variable " << Var->getName(Func) << "\n"; |
| 268 } |
| 269 } |
| 270 llvm::report_fatal_error("initForInfOnly: Liveness error"); |
| 271 } |
| 211 // This isn't actually a fatal condition, but it would be nice to know if we | 272 // This isn't actually a fatal condition, but it would be nice to know if we |
| 212 // somehow pre-calculated Unhandled's size wrong. | 273 // somehow pre-calculated Unhandled's size wrong. |
| 213 assert(NumVars == 0); | 274 assert(NumVars == 0); |
| 214 | 275 |
| 215 // Don't build up the list of Kills because we know that no infinite-weight | 276 // Don't build up the list of Kills because we know that no infinite-weight |
| 216 // Variable has a live range spanning a call. | 277 // Variable has a live range spanning a call. |
| 217 Kills.clear(); | 278 Kills.clear(); |
| 218 } | 279 } |
| 219 | 280 |
| 220 void LinearScan::init(RegAllocKind Kind) { | 281 void LinearScan::init(RegAllocKind Kind) { |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 Str << "\n"; | 944 Str << "\n"; |
| 884 } | 945 } |
| 885 Str << "++++++ Inactive:\n"; | 946 Str << "++++++ Inactive:\n"; |
| 886 for (const Variable *Item : Inactive) { | 947 for (const Variable *Item : Inactive) { |
| 887 dumpLiveRange(Item, Func); | 948 dumpLiveRange(Item, Func); |
| 888 Str << "\n"; | 949 Str << "\n"; |
| 889 } | 950 } |
| 890 } | 951 } |
| 891 | 952 |
| 892 } // end of namespace Ice | 953 } // end of namespace Ice |
| OLD | NEW |