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 /// \file | 10 /// \file |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 } | 206 } |
207 } | 207 } |
208 | 208 |
209 void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr, | 209 void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr, |
210 CfgNode *Node) { | 210 CfgNode *Node) { |
211 // TODO(stichnot): If the definition occurs in the last instruction of the | 211 // TODO(stichnot): If the definition occurs in the last instruction of the |
212 // block, consider not marking this as a separate use. But be careful not to | 212 // block, consider not marking this as a separate use. But be careful not to |
213 // omit all uses of the variable if markDef() and markUse() both use this | 213 // omit all uses of the variable if markDef() and markUse() both use this |
214 // optimization. | 214 // optimization. |
215 assert(Node); | 215 assert(Node); |
216 // Verify that instructions are added in increasing order. | 216 // Verify that instructions are added in increasing order. |
217 #ifndef NDEBUG | 217 if (BuildDefs::asserts()) { |
218 if (TrackingKind == VMK_All) { | 218 if (TrackingKind == VMK_All) { |
219 const Inst *LastInstruction = | 219 const Inst *LastInstruction = |
220 Definitions.empty() ? FirstOrSingleDefinition : Definitions.back(); | 220 Definitions.empty() ? FirstOrSingleDefinition : Definitions.back(); |
221 assert(LastInstruction == nullptr || | 221 (void)LastInstruction; |
222 Instr->getNumber() >= LastInstruction->getNumber()); | 222 assert(LastInstruction == nullptr || |
| 223 Instr->getNumber() >= LastInstruction->getNumber()); |
| 224 } |
223 } | 225 } |
224 #endif | |
225 constexpr bool IsImplicit = false; | 226 constexpr bool IsImplicit = false; |
226 markUse(TrackingKind, Instr, Node, IsImplicit); | 227 markUse(TrackingKind, Instr, Node, IsImplicit); |
227 if (TrackingKind == VMK_Uses) | 228 if (TrackingKind == VMK_Uses) |
228 return; | 229 return; |
229 if (FirstOrSingleDefinition == nullptr) | 230 if (FirstOrSingleDefinition == nullptr) |
230 FirstOrSingleDefinition = Instr; | 231 FirstOrSingleDefinition = Instr; |
231 else if (TrackingKind == VMK_All) | 232 else if (TrackingKind == VMK_All) |
232 Definitions.push_back(Instr); | 233 Definitions.push_back(Instr); |
233 switch (MultiDef) { | 234 switch (MultiDef) { |
234 case MDS_Unknown: | 235 case MDS_Unknown: |
(...skipping 16 matching lines...) Expand all Loading... |
251 MultiDef = MDS_MultiDefMultiBlock; | 252 MultiDef = MDS_MultiDefMultiBlock; |
252 SingleDefNode = nullptr; | 253 SingleDefNode = nullptr; |
253 } | 254 } |
254 break; | 255 break; |
255 case MDS_MultiDefMultiBlock: | 256 case MDS_MultiDefMultiBlock: |
256 assert(SingleDefNode == nullptr); | 257 assert(SingleDefNode == nullptr); |
257 break; | 258 break; |
258 } | 259 } |
259 } | 260 } |
260 | 261 |
261 const Inst *VariableTracking::getFirstDefinition() const { | 262 const Inst *VariableTracking::getFirstDefinitionSingleBlock() const { |
262 switch (MultiDef) { | 263 switch (MultiDef) { |
263 case MDS_Unknown: | 264 case MDS_Unknown: |
264 case MDS_MultiDefMultiBlock: | 265 case MDS_MultiDefMultiBlock: |
265 return nullptr; | 266 return nullptr; |
266 case MDS_SingleDef: | 267 case MDS_SingleDef: |
267 case MDS_MultiDefSingleBlock: | 268 case MDS_MultiDefSingleBlock: |
268 assert(FirstOrSingleDefinition); | 269 assert(FirstOrSingleDefinition); |
269 return FirstOrSingleDefinition; | 270 return FirstOrSingleDefinition; |
270 } | 271 } |
271 return nullptr; | 272 return nullptr; |
272 } | 273 } |
273 | 274 |
274 const Inst *VariableTracking::getSingleDefinition() const { | 275 const Inst *VariableTracking::getSingleDefinition() const { |
275 switch (MultiDef) { | 276 switch (MultiDef) { |
276 case MDS_Unknown: | 277 case MDS_Unknown: |
277 case MDS_MultiDefMultiBlock: | 278 case MDS_MultiDefMultiBlock: |
278 case MDS_MultiDefSingleBlock: | 279 case MDS_MultiDefSingleBlock: |
279 return nullptr; | 280 return nullptr; |
280 case MDS_SingleDef: | 281 case MDS_SingleDef: |
281 assert(FirstOrSingleDefinition); | 282 assert(FirstOrSingleDefinition); |
282 return FirstOrSingleDefinition; | 283 return FirstOrSingleDefinition; |
283 } | 284 } |
284 return nullptr; | 285 return nullptr; |
285 } | 286 } |
286 | 287 |
| 288 const Inst *VariableTracking::getFirstDefinition() const { |
| 289 switch (MultiDef) { |
| 290 case MDS_Unknown: |
| 291 return nullptr; |
| 292 case MDS_MultiDefMultiBlock: |
| 293 case MDS_SingleDef: |
| 294 case MDS_MultiDefSingleBlock: |
| 295 assert(FirstOrSingleDefinition); |
| 296 return FirstOrSingleDefinition; |
| 297 } |
| 298 return nullptr; |
| 299 } |
| 300 |
287 void VariablesMetadata::init(MetadataKind TrackingKind) { | 301 void VariablesMetadata::init(MetadataKind TrackingKind) { |
288 TimerMarker T(TimerStack::TT_vmetadata, Func); | 302 TimerMarker T(TimerStack::TT_vmetadata, Func); |
289 Kind = TrackingKind; | 303 Kind = TrackingKind; |
290 Metadata.clear(); | 304 Metadata.clear(); |
291 Metadata.resize(Func->getNumVariables()); | 305 Metadata.resize(Func->getNumVariables()); |
292 | 306 |
293 // Mark implicit args as being used in the entry node. | 307 // Mark implicit args as being used in the entry node. |
294 for (Variable *Var : Func->getImplicitArgs()) { | 308 for (Variable *Var : Func->getImplicitArgs()) { |
295 constexpr Inst *NoInst = nullptr; | 309 constexpr Inst *NoInst = nullptr; |
296 CfgNode *EntryNode = Func->getEntryNode(); | 310 CfgNode *EntryNode = Func->getEntryNode(); |
297 constexpr bool IsImplicit = true; | 311 constexpr bool IsImplicit = true; |
298 Metadata[Var->getIndex()].markUse(Kind, NoInst, EntryNode, IsImplicit); | 312 Metadata[Var->getIndex()].markUse(Kind, NoInst, EntryNode, IsImplicit); |
299 } | 313 } |
300 | 314 |
301 for (CfgNode *Node : Func->getNodes()) | 315 for (CfgNode *Node : Func->getNodes()) |
302 addNode(Node); | 316 addNode(Node); |
303 } | 317 } |
304 | 318 |
305 void VariablesMetadata::addNode(CfgNode *Node) { | 319 void VariablesMetadata::addNode(CfgNode *Node) { |
306 if (Func->getNumVariables() >= Metadata.size()) | 320 if (Func->getNumVariables() > Metadata.size()) |
307 Metadata.resize(Func->getNumVariables()); | 321 Metadata.resize(Func->getNumVariables()); |
308 | 322 |
309 for (Inst &I : Node->getPhis()) { | 323 for (Inst &I : Node->getPhis()) { |
310 if (I.isDeleted()) | 324 if (I.isDeleted()) |
311 continue; | 325 continue; |
312 if (Variable *Dest = I.getDest()) { | 326 if (Variable *Dest = I.getDest()) { |
313 SizeT DestNum = Dest->getIndex(); | 327 SizeT DestNum = Dest->getIndex(); |
314 assert(DestNum < Metadata.size()); | 328 assert(DestNum < Metadata.size()); |
315 Metadata[DestNum].markDef(Kind, &I, Node); | 329 Metadata[DestNum].markDef(Kind, &I, Node); |
316 } | 330 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { | 371 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { |
358 if (Var->getIsArg()) | 372 if (Var->getIsArg()) |
359 return true; | 373 return true; |
360 if (!isTracked(Var)) | 374 if (!isTracked(Var)) |
361 return true; // conservative answer | 375 return true; // conservative answer |
362 SizeT VarNum = Var->getIndex(); | 376 SizeT VarNum = Var->getIndex(); |
363 // Conservatively return true if the state is unknown. | 377 // Conservatively return true if the state is unknown. |
364 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; | 378 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; |
365 } | 379 } |
366 | 380 |
367 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { | 381 const Inst * |
| 382 VariablesMetadata::getFirstDefinitionSingleBlock(const Variable *Var) const { |
368 assert(Kind != VMK_Uses); | 383 assert(Kind != VMK_Uses); |
369 if (!isTracked(Var)) | 384 if (!isTracked(Var)) |
370 return nullptr; // conservative answer | 385 return nullptr; // conservative answer |
371 SizeT VarNum = Var->getIndex(); | 386 SizeT VarNum = Var->getIndex(); |
372 return Metadata[VarNum].getFirstDefinition(); | 387 return Metadata[VarNum].getFirstDefinitionSingleBlock(); |
373 } | 388 } |
374 | 389 |
375 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { | 390 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { |
376 assert(Kind != VMK_Uses); | 391 assert(Kind != VMK_Uses); |
377 if (!isTracked(Var)) | 392 if (!isTracked(Var)) |
378 return nullptr; // conservative answer | 393 return nullptr; // conservative answer |
379 SizeT VarNum = Var->getIndex(); | 394 SizeT VarNum = Var->getIndex(); |
380 return Metadata[VarNum].getSingleDefinition(); | 395 return Metadata[VarNum].getSingleDefinition(); |
381 } | 396 } |
382 | 397 |
| 398 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { |
| 399 assert(Kind != VMK_Uses); |
| 400 if (!isTracked(Var)) |
| 401 return nullptr; // conservative answer |
| 402 SizeT VarNum = Var->getIndex(); |
| 403 return Metadata[VarNum].getFirstDefinition(); |
| 404 } |
| 405 |
383 const InstDefList & | 406 const InstDefList & |
384 VariablesMetadata::getLatterDefinitions(const Variable *Var) const { | 407 VariablesMetadata::getLatterDefinitions(const Variable *Var) const { |
385 assert(Kind == VMK_All); | 408 assert(Kind == VMK_All); |
386 if (!isTracked(Var)) | 409 if (!isTracked(Var)) |
387 return NoDefinitions; | 410 return NoDefinitions; |
388 SizeT VarNum = Var->getIndex(); | 411 SizeT VarNum = Var->getIndex(); |
389 return Metadata[VarNum].getLatterDefinitions(); | 412 return Metadata[VarNum].getLatterDefinitions(); |
390 } | 413 } |
391 | 414 |
392 CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { | 415 CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 if (getType() != IceType_i32 && getType() != IceType_i16 && | 546 if (getType() != IceType_i32 && getType() != IceType_i16 && |
524 getType() != IceType_i8) | 547 getType() != IceType_i8) |
525 return false; | 548 return false; |
526 // The Following checks if the signed representation of Value is between | 549 // The Following checks if the signed representation of Value is between |
527 // -Threshold/2 and +Threshold/2 | 550 // -Threshold/2 and +Threshold/2 |
528 bool largerThanThreshold = Threshold / 2 + Value >= Threshold; | 551 bool largerThanThreshold = Threshold / 2 + Value >= Threshold; |
529 return largerThanThreshold; | 552 return largerThanThreshold; |
530 } | 553 } |
531 | 554 |
532 } // end of namespace Ice | 555 } // end of namespace Ice |
OLD | NEW |