| 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 |