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 |