| OLD | NEW |
| 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering implementation --===// | 1 //===- subzero/src/IceTargetLowering.cpp - Basic lowering 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 } | 63 } |
| 64 | 64 |
| 65 void LoweringContext::rewind() { | 65 void LoweringContext::rewind() { |
| 66 Begin = getNode()->getInsts().begin(); | 66 Begin = getNode()->getInsts().begin(); |
| 67 Cur = Begin; | 67 Cur = Begin; |
| 68 skipDeleted(Cur); | 68 skipDeleted(Cur); |
| 69 Next = Cur; | 69 Next = Cur; |
| 70 availabilityReset(); | 70 availabilityReset(); |
| 71 } | 71 } |
| 72 | 72 |
| 73 void LoweringContext::insert(Inst *Inst) { | 73 void LoweringContext::insert(Inst *Instr) { |
| 74 getNode()->getInsts().insert(Next, Inst); | 74 getNode()->getInsts().insert(Next, Instr); |
| 75 LastInserted = Inst; | 75 LastInserted = Instr; |
| 76 } | 76 } |
| 77 | 77 |
| 78 void LoweringContext::skipDeleted(InstList::iterator &I) const { | 78 void LoweringContext::skipDeleted(InstList::iterator &I) const { |
| 79 while (I != End && I->isDeleted()) | 79 while (I != End && I->isDeleted()) |
| 80 ++I; | 80 ++I; |
| 81 } | 81 } |
| 82 | 82 |
| 83 void LoweringContext::advanceForward(InstList::iterator &I) const { | 83 void LoweringContext::advanceForward(InstList::iterator &I) const { |
| 84 if (I != End) { | 84 if (I != End) { |
| 85 ++I; | 85 ++I; |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 // the Cur.Next insertion point, and should not delete the Context.Cur | 343 // the Cur.Next insertion point, and should not delete the Context.Cur |
| 344 // instruction or advance Context.Cur. | 344 // instruction or advance Context.Cur. |
| 345 // | 345 // |
| 346 // The lowering method may look ahead in the instruction stream as desired, and | 346 // The lowering method may look ahead in the instruction stream as desired, and |
| 347 // lower additional instructions in conjunction with the current one, for | 347 // lower additional instructions in conjunction with the current one, for |
| 348 // example fusing a compare and branch. If it does, it should advance | 348 // example fusing a compare and branch. If it does, it should advance |
| 349 // Context.Cur to point to the next non-deleted instruction to process, and it | 349 // Context.Cur to point to the next non-deleted instruction to process, and it |
| 350 // should delete any additional instructions it consumes. | 350 // should delete any additional instructions it consumes. |
| 351 void TargetLowering::lower() { | 351 void TargetLowering::lower() { |
| 352 assert(!Context.atEnd()); | 352 assert(!Context.atEnd()); |
| 353 Inst *Inst = Context.getCur(); | 353 Inst *Instr = Context.getCur(); |
| 354 Inst->deleteIfDead(); | 354 Instr->deleteIfDead(); |
| 355 if (!Inst->isDeleted() && !llvm::isa<InstFakeDef>(Inst) && | 355 if (!Instr->isDeleted() && !llvm::isa<InstFakeDef>(Instr) && |
| 356 !llvm::isa<InstFakeUse>(Inst)) { | 356 !llvm::isa<InstFakeUse>(Instr)) { |
| 357 // Mark the current instruction as deleted before lowering, otherwise the | 357 // Mark the current instruction as deleted before lowering, otherwise the |
| 358 // Dest variable will likely get marked as non-SSA. See | 358 // Dest variable will likely get marked as non-SSA. See |
| 359 // Variable::setDefinition(). However, just pass-through FakeDef and | 359 // Variable::setDefinition(). However, just pass-through FakeDef and |
| 360 // FakeUse instructions that might have been inserted prior to lowering. | 360 // FakeUse instructions that might have been inserted prior to lowering. |
| 361 Inst->setDeleted(); | 361 Instr->setDeleted(); |
| 362 switch (Inst->getKind()) { | 362 switch (Instr->getKind()) { |
| 363 case Inst::Alloca: | 363 case Inst::Alloca: |
| 364 lowerAlloca(llvm::cast<InstAlloca>(Inst)); | 364 lowerAlloca(llvm::cast<InstAlloca>(Instr)); |
| 365 break; | 365 break; |
| 366 case Inst::Arithmetic: | 366 case Inst::Arithmetic: |
| 367 lowerArithmetic(llvm::cast<InstArithmetic>(Inst)); | 367 lowerArithmetic(llvm::cast<InstArithmetic>(Instr)); |
| 368 break; | 368 break; |
| 369 case Inst::Assign: | 369 case Inst::Assign: |
| 370 lowerAssign(llvm::cast<InstAssign>(Inst)); | 370 lowerAssign(llvm::cast<InstAssign>(Instr)); |
| 371 break; | 371 break; |
| 372 case Inst::Br: | 372 case Inst::Br: |
| 373 lowerBr(llvm::cast<InstBr>(Inst)); | 373 lowerBr(llvm::cast<InstBr>(Instr)); |
| 374 break; | 374 break; |
| 375 case Inst::Call: | 375 case Inst::Call: |
| 376 lowerCall(llvm::cast<InstCall>(Inst)); | 376 lowerCall(llvm::cast<InstCall>(Instr)); |
| 377 break; | 377 break; |
| 378 case Inst::Cast: | 378 case Inst::Cast: |
| 379 lowerCast(llvm::cast<InstCast>(Inst)); | 379 lowerCast(llvm::cast<InstCast>(Instr)); |
| 380 break; | 380 break; |
| 381 case Inst::ExtractElement: | 381 case Inst::ExtractElement: |
| 382 lowerExtractElement(llvm::cast<InstExtractElement>(Inst)); | 382 lowerExtractElement(llvm::cast<InstExtractElement>(Instr)); |
| 383 break; | 383 break; |
| 384 case Inst::Fcmp: | 384 case Inst::Fcmp: |
| 385 lowerFcmp(llvm::cast<InstFcmp>(Inst)); | 385 lowerFcmp(llvm::cast<InstFcmp>(Instr)); |
| 386 break; | 386 break; |
| 387 case Inst::Icmp: | 387 case Inst::Icmp: |
| 388 lowerIcmp(llvm::cast<InstIcmp>(Inst)); | 388 lowerIcmp(llvm::cast<InstIcmp>(Instr)); |
| 389 break; | 389 break; |
| 390 case Inst::InsertElement: | 390 case Inst::InsertElement: |
| 391 lowerInsertElement(llvm::cast<InstInsertElement>(Inst)); | 391 lowerInsertElement(llvm::cast<InstInsertElement>(Instr)); |
| 392 break; | 392 break; |
| 393 case Inst::IntrinsicCall: { | 393 case Inst::IntrinsicCall: { |
| 394 auto *Call = llvm::cast<InstIntrinsicCall>(Inst); | 394 auto *Call = llvm::cast<InstIntrinsicCall>(Instr); |
| 395 if (Call->getIntrinsicInfo().ReturnsTwice) | 395 if (Call->getIntrinsicInfo().ReturnsTwice) |
| 396 setCallsReturnsTwice(true); | 396 setCallsReturnsTwice(true); |
| 397 lowerIntrinsicCall(Call); | 397 lowerIntrinsicCall(Call); |
| 398 break; | 398 break; |
| 399 } | 399 } |
| 400 case Inst::Load: | 400 case Inst::Load: |
| 401 lowerLoad(llvm::cast<InstLoad>(Inst)); | 401 lowerLoad(llvm::cast<InstLoad>(Instr)); |
| 402 break; | 402 break; |
| 403 case Inst::Phi: | 403 case Inst::Phi: |
| 404 lowerPhi(llvm::cast<InstPhi>(Inst)); | 404 lowerPhi(llvm::cast<InstPhi>(Instr)); |
| 405 break; | 405 break; |
| 406 case Inst::Ret: | 406 case Inst::Ret: |
| 407 lowerRet(llvm::cast<InstRet>(Inst)); | 407 lowerRet(llvm::cast<InstRet>(Instr)); |
| 408 break; | 408 break; |
| 409 case Inst::Select: | 409 case Inst::Select: |
| 410 lowerSelect(llvm::cast<InstSelect>(Inst)); | 410 lowerSelect(llvm::cast<InstSelect>(Instr)); |
| 411 break; | 411 break; |
| 412 case Inst::Store: | 412 case Inst::Store: |
| 413 lowerStore(llvm::cast<InstStore>(Inst)); | 413 lowerStore(llvm::cast<InstStore>(Instr)); |
| 414 break; | 414 break; |
| 415 case Inst::Switch: | 415 case Inst::Switch: |
| 416 lowerSwitch(llvm::cast<InstSwitch>(Inst)); | 416 lowerSwitch(llvm::cast<InstSwitch>(Instr)); |
| 417 break; | 417 break; |
| 418 case Inst::Unreachable: | 418 case Inst::Unreachable: |
| 419 lowerUnreachable(llvm::cast<InstUnreachable>(Inst)); | 419 lowerUnreachable(llvm::cast<InstUnreachable>(Instr)); |
| 420 break; | 420 break; |
| 421 default: | 421 default: |
| 422 lowerOther(Inst); | 422 lowerOther(Instr); |
| 423 break; | 423 break; |
| 424 } | 424 } |
| 425 | 425 |
| 426 postLower(); | 426 postLower(); |
| 427 } | 427 } |
| 428 | 428 |
| 429 Context.advanceCur(); | 429 Context.advanceCur(); |
| 430 Context.advanceNext(); | 430 Context.advanceNext(); |
| 431 } | 431 } |
| 432 | 432 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 // coalescing. The idea would be to initialize the Unhandled list with the | 475 // coalescing. The idea would be to initialize the Unhandled list with the |
| 476 // set of Variables that have no register and a non-empty live range, and | 476 // set of Variables that have no register and a non-empty live range, and |
| 477 // model an infinite number of registers. Maybe use the register aliasing | 477 // model an infinite number of registers. Maybe use the register aliasing |
| 478 // mechanism to get better packing of narrower slots. | 478 // mechanism to get better packing of narrower slots. |
| 479 } | 479 } |
| 480 | 480 |
| 481 void TargetLowering::markRedefinitions() { | 481 void TargetLowering::markRedefinitions() { |
| 482 // Find (non-SSA) instructions where the Dest variable appears in some source | 482 // Find (non-SSA) instructions where the Dest variable appears in some source |
| 483 // operand, and set the IsDestRedefined flag to keep liveness analysis | 483 // operand, and set the IsDestRedefined flag to keep liveness analysis |
| 484 // consistent. | 484 // consistent. |
| 485 for (auto Inst = Context.getCur(), E = Context.getNext(); Inst != E; ++Inst) { | 485 for (auto Instr = Context.getCur(), E = Context.getNext(); Instr != E; |
| 486 if (Inst->isDeleted()) | 486 ++Instr) { |
| 487 if (Instr->isDeleted()) |
| 487 continue; | 488 continue; |
| 488 Variable *Dest = Inst->getDest(); | 489 Variable *Dest = Instr->getDest(); |
| 489 if (Dest == nullptr) | 490 if (Dest == nullptr) |
| 490 continue; | 491 continue; |
| 491 FOREACH_VAR_IN_INST(Var, *Inst) { | 492 FOREACH_VAR_IN_INST(Var, *Instr) { |
| 492 if (Var == Dest) { | 493 if (Var == Dest) { |
| 493 Inst->setDestRedefined(); | 494 Instr->setDestRedefined(); |
| 494 break; | 495 break; |
| 495 } | 496 } |
| 496 } | 497 } |
| 497 } | 498 } |
| 498 } | 499 } |
| 499 | 500 |
| 500 void TargetLowering::addFakeDefUses(const Inst *Instr) { | 501 void TargetLowering::addFakeDefUses(const Inst *Instr) { |
| 501 FOREACH_VAR_IN_INST(Var, *Instr) { | 502 FOREACH_VAR_IN_INST(Var, *Instr) { |
| 502 if (auto *Var64 = llvm::dyn_cast<Variable64On32>(Var)) { | 503 if (auto *Var64 = llvm::dyn_cast<Variable64On32>(Var)) { |
| 503 Context.insert<InstFakeUse>(Var64->getLo()); | 504 Context.insert<InstFakeUse>(Var64->getLo()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 530 } | 531 } |
| 531 | 532 |
| 532 void TargetLowering::getVarStackSlotParams( | 533 void TargetLowering::getVarStackSlotParams( |
| 533 VarList &SortedSpilledVariables, llvm::SmallBitVector &RegsUsed, | 534 VarList &SortedSpilledVariables, llvm::SmallBitVector &RegsUsed, |
| 534 size_t *GlobalsSize, size_t *SpillAreaSizeBytes, | 535 size_t *GlobalsSize, size_t *SpillAreaSizeBytes, |
| 535 uint32_t *SpillAreaAlignmentBytes, uint32_t *LocalsSlotsAlignmentBytes, | 536 uint32_t *SpillAreaAlignmentBytes, uint32_t *LocalsSlotsAlignmentBytes, |
| 536 std::function<bool(Variable *)> TargetVarHook) { | 537 std::function<bool(Variable *)> TargetVarHook) { |
| 537 const VariablesMetadata *VMetadata = Func->getVMetadata(); | 538 const VariablesMetadata *VMetadata = Func->getVMetadata(); |
| 538 llvm::BitVector IsVarReferenced(Func->getNumVariables()); | 539 llvm::BitVector IsVarReferenced(Func->getNumVariables()); |
| 539 for (CfgNode *Node : Func->getNodes()) { | 540 for (CfgNode *Node : Func->getNodes()) { |
| 540 for (Inst &Inst : Node->getInsts()) { | 541 for (Inst &Instr : Node->getInsts()) { |
| 541 if (Inst.isDeleted()) | 542 if (Instr.isDeleted()) |
| 542 continue; | 543 continue; |
| 543 if (const Variable *Var = Inst.getDest()) | 544 if (const Variable *Var = Instr.getDest()) |
| 544 IsVarReferenced[Var->getIndex()] = true; | 545 IsVarReferenced[Var->getIndex()] = true; |
| 545 FOREACH_VAR_IN_INST(Var, Inst) { | 546 FOREACH_VAR_IN_INST(Var, Instr) { |
| 546 IsVarReferenced[Var->getIndex()] = true; | 547 IsVarReferenced[Var->getIndex()] = true; |
| 547 } | 548 } |
| 548 } | 549 } |
| 549 } | 550 } |
| 550 | 551 |
| 551 // If SimpleCoalescing is false, each variable without a register gets its | 552 // If SimpleCoalescing is false, each variable without a register gets its |
| 552 // own unique stack slot, which leads to large stack frames. If | 553 // own unique stack slot, which leads to large stack frames. If |
| 553 // SimpleCoalescing is true, then each "global" variable without a register | 554 // SimpleCoalescing is true, then each "global" variable without a register |
| 554 // gets its own slot, but "local" variable slots are reused across basic | 555 // gets its own slot, but "local" variable slots are reused across basic |
| 555 // blocks. E.g., if A and B are local to block 1 and C is local to block 2, | 556 // blocks. E.g., if A and B are local to block 1 and C is local to block 2, |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 case Target_##X: \ | 863 case Target_##X: \ |
| 863 return ::X::createTargetHeaderLowering(Ctx); | 864 return ::X::createTargetHeaderLowering(Ctx); |
| 864 #include "llvm/Config/SZTargets.def" | 865 #include "llvm/Config/SZTargets.def" |
| 865 #undef SUBZERO_TARGET | 866 #undef SUBZERO_TARGET |
| 866 } | 867 } |
| 867 } | 868 } |
| 868 | 869 |
| 869 TargetHeaderLowering::~TargetHeaderLowering() = default; | 870 TargetHeaderLowering::~TargetHeaderLowering() = default; |
| 870 | 871 |
| 871 } // end of namespace Ice | 872 } // end of namespace Ice |
| OLD | NEW |