OLD | NEW |
1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// | 1 //===- subzero/src/IceCfg.cpp - Control flow graph 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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 // upwards from the stack pointer. | 487 // upwards from the stack pointer. |
488 Offsets.push_back(CurrentOffset); | 488 Offsets.push_back(CurrentOffset); |
489 } | 489 } |
490 // Update the running offset of the fused alloca region. | 490 // Update the running offset of the fused alloca region. |
491 CurrentOffset += Size; | 491 CurrentOffset += Size; |
492 } | 492 } |
493 // Round the offset up to the alignment granularity to use as the size. | 493 // Round the offset up to the alignment granularity to use as the size. |
494 uint32_t TotalSize = Utils::applyAlignment(CurrentOffset, CombinedAlignment); | 494 uint32_t TotalSize = Utils::applyAlignment(CurrentOffset, CombinedAlignment); |
495 // Ensure every alloca was assigned an offset. | 495 // Ensure every alloca was assigned an offset. |
496 assert(Allocas.size() == Offsets.size()); | 496 assert(Allocas.size() == Offsets.size()); |
497 Variable *BaseVariable = makeVariable(IceType_i32); | 497 |
498 Variable *AllocaDest = BaseVariable; | 498 switch (BaseVariableType) { |
499 // Emit one addition for each alloca after the first. | 499 case BVT_UserPointer: { |
500 for (size_t i = 0; i < Allocas.size(); ++i) { | 500 Variable *BaseVariable = makeVariable(IceType_i32); |
501 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); | 501 for (SizeT i = 0; i < Allocas.size(); ++i) { |
502 switch (BaseVariableType) { | 502 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); |
503 case BVT_FramePointer: | |
504 case BVT_UserPointer: { | |
505 // Emit a new addition operation to replace the alloca. | 503 // Emit a new addition operation to replace the alloca. |
506 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]); | 504 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]); |
507 InstArithmetic *Add = | 505 InstArithmetic *Add = |
508 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(), | 506 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(), |
509 BaseVariable, AllocaOffset); | 507 BaseVariable, AllocaOffset); |
510 Insts.push_front(Add); | 508 Insts.push_front(Add); |
511 } break; | 509 Alloca->setDeleted(); |
512 case BVT_StackPointer: { | 510 } |
| 511 Operand *AllocaSize = Ctx->getConstantInt32(TotalSize); |
| 512 InstAlloca *CombinedAlloca = |
| 513 InstAlloca::create(this, BaseVariable, AllocaSize, CombinedAlignment); |
| 514 CombinedAlloca->setKnownFrameOffset(); |
| 515 Insts.push_front(CombinedAlloca); |
| 516 } break; |
| 517 case BVT_StackPointer: |
| 518 case BVT_FramePointer: { |
| 519 for (SizeT i = 0; i < Allocas.size(); ++i) { |
| 520 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); |
513 // Emit a fake definition of the rematerializable variable. | 521 // Emit a fake definition of the rematerializable variable. |
514 Variable *Dest = Alloca->getDest(); | 522 Variable *Dest = Alloca->getDest(); |
515 InstFakeDef *Def = InstFakeDef::create(this, Dest); | 523 InstFakeDef *Def = InstFakeDef::create(this, Dest); |
516 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]); | 524 if (BaseVariableType == BVT_StackPointer) |
| 525 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]); |
| 526 else |
| 527 Dest->setRematerializable(getTarget()->getFrameReg(), Offsets[i]); |
517 Insts.push_front(Def); | 528 Insts.push_front(Def); |
518 } break; | 529 Alloca->setDeleted(); |
519 } | 530 } |
520 Alloca->setDeleted(); | 531 // Allocate the fixed area in the function prolog. |
| 532 getTarget()->reserveFixedAllocaArea(TotalSize, CombinedAlignment); |
| 533 } break; |
521 } | 534 } |
522 Operand *AllocaSize = Ctx->getConstantInt32(TotalSize); | |
523 switch (BaseVariableType) { | |
524 case BVT_FramePointer: { | |
525 // Adjust the return of the alloca to the top of the returned region. | |
526 AllocaDest = makeVariable(IceType_i32); | |
527 InstArithmetic *Add = InstArithmetic::create( | |
528 this, InstArithmetic::Add, BaseVariable, AllocaDest, AllocaSize); | |
529 Insts.push_front(Add); | |
530 } break; | |
531 case BVT_StackPointer: { | |
532 // Emit a fake use to keep the Alloca live. | |
533 InstFakeUse *Use = InstFakeUse::create(this, AllocaDest); | |
534 Insts.push_front(Use); | |
535 } break; | |
536 case BVT_UserPointer: | |
537 break; | |
538 } | |
539 // And insert the fused alloca. | |
540 InstAlloca *CombinedAlloca = | |
541 InstAlloca::create(this, AllocaSize, CombinedAlignment, AllocaDest); | |
542 CombinedAlloca->setKnownFrameOffset(); | |
543 Insts.push_front(CombinedAlloca); | |
544 } | 535 } |
545 | 536 |
546 void Cfg::processAllocas(bool SortAndCombine) { | 537 void Cfg::processAllocas(bool SortAndCombine) { |
547 const uint32_t StackAlignment = getTarget()->getStackAlignment(); | 538 const uint32_t StackAlignment = getTarget()->getStackAlignment(); |
548 CfgNode *EntryNode = getEntryNode(); | 539 CfgNode *EntryNode = getEntryNode(); |
549 // LLVM enforces power of 2 alignment. | 540 // LLVM enforces power of 2 alignment. |
550 assert(llvm::isPowerOf2_32(StackAlignment)); | 541 assert(llvm::isPowerOf2_32(StackAlignment)); |
551 // Determine if there are large alignment allocations in the entry block or | 542 // Determine if there are large alignment allocations in the entry block or |
552 // dynamic allocations (variable size in the entry block). | 543 // dynamic allocations (variable size in the entry block). |
553 bool HasLargeAlignment = false; | 544 bool HasLargeAlignment = false; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 // Mark the target as requiring a frame pointer. | 579 // Mark the target as requiring a frame pointer. |
589 if (HasLargeAlignment || HasDynamicAllocation) | 580 if (HasLargeAlignment || HasDynamicAllocation) |
590 getTarget()->setHasFramePointer(); | 581 getTarget()->setHasFramePointer(); |
591 // Collect the Allocas into the two vectors. | 582 // Collect the Allocas into the two vectors. |
592 // Allocas in the entry block that have constant size and alignment less | 583 // Allocas in the entry block that have constant size and alignment less |
593 // than or equal to the function's stack alignment. | 584 // than or equal to the function's stack alignment. |
594 CfgVector<Inst *> FixedAllocas; | 585 CfgVector<Inst *> FixedAllocas; |
595 // Allocas in the entry block that have constant size and alignment greater | 586 // Allocas in the entry block that have constant size and alignment greater |
596 // than the function's stack alignment. | 587 // than the function's stack alignment. |
597 CfgVector<Inst *> AlignedAllocas; | 588 CfgVector<Inst *> AlignedAllocas; |
598 // Maximum alignment used for the dynamic/aligned allocas. | 589 // Maximum alignment used by any alloca. |
599 uint32_t MaxAlignment = StackAlignment; | 590 uint32_t MaxAlignment = StackAlignment; |
600 for (Inst &Instr : EntryNode->getInsts()) { | 591 for (Inst &Instr : EntryNode->getInsts()) { |
601 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) { | 592 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) { |
602 if (!llvm::isa<Constant>(Alloca->getSizeInBytes())) | 593 if (!llvm::isa<Constant>(Alloca->getSizeInBytes())) |
603 continue; | 594 continue; |
604 uint32_t AlignmentParam = Alloca->getAlignInBytes(); | 595 uint32_t AlignmentParam = Alloca->getAlignInBytes(); |
605 // For default align=0, set it to the real value 1, to avoid any | 596 // For default align=0, set it to the real value 1, to avoid any |
606 // bit-manipulation problems below. | 597 // bit-manipulation problems below. |
607 AlignmentParam = std::max(AlignmentParam, 1u); | 598 AlignmentParam = std::max(AlignmentParam, 1u); |
608 assert(llvm::isPowerOf2_32(AlignmentParam)); | 599 assert(llvm::isPowerOf2_32(AlignmentParam)); |
609 if (HasDynamicAllocation && AlignmentParam > StackAlignment) { | 600 if (HasDynamicAllocation && AlignmentParam > StackAlignment) { |
610 // If we have both dynamic allocations and large stack alignments, | 601 // If we have both dynamic allocations and large stack alignments, |
611 // high-alignment allocations are pulled out with their own base. | 602 // high-alignment allocations are pulled out with their own base. |
612 AlignedAllocas.push_back(Alloca); | 603 AlignedAllocas.push_back(Alloca); |
613 } else { | 604 } else { |
614 FixedAllocas.push_back(Alloca); | 605 FixedAllocas.push_back(Alloca); |
615 } | 606 } |
616 MaxAlignment = std::max(AlignmentParam, MaxAlignment); | 607 MaxAlignment = std::max(AlignmentParam, MaxAlignment); |
617 } | 608 } |
618 } | 609 } |
619 // Add instructions to the head of the entry block in reverse order. | 610 // Add instructions to the head of the entry block in reverse order. |
620 InstList &Insts = getEntryNode()->getInsts(); | 611 InstList &Insts = getEntryNode()->getInsts(); |
621 if (HasDynamicAllocation && HasLargeAlignment) { | 612 if (HasDynamicAllocation && HasLargeAlignment) { |
622 // We are using a frame pointer, but fixed large-alignment alloca addresses, | 613 // We are using a frame pointer, but fixed large-alignment alloca addresses, |
623 // do not have a known offset from either the stack or frame pointer. | 614 // do not have a known offset from either the stack or frame pointer. |
624 // They grow up from a user pointer from an alloca. | 615 // They grow up from a user pointer from an alloca. |
625 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer); | 616 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer); |
| 617 // Fixed size allocas are addressed relative to the frame pointer. |
| 618 sortAndCombineAllocas(FixedAllocas, StackAlignment, Insts, |
| 619 BVT_FramePointer); |
| 620 } else { |
| 621 // Otherwise, fixed size allocas are addressed relative to the stack unless |
| 622 // there are dynamic allocas. |
| 623 const AllocaBaseVariableType BasePointerType = |
| 624 (HasDynamicAllocation ? BVT_FramePointer : BVT_StackPointer); |
| 625 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType); |
626 } | 626 } |
627 // Otherwise, fixed size allocas are always addressed relative to the stack | |
628 // unless there are dynamic allocas. | |
629 // TODO(sehr): re-enable frame pointer and decrementing addressing. | |
630 AllocaBaseVariableType BasePointerType = | |
631 (HasDynamicAllocation ? BVT_UserPointer : BVT_StackPointer); | |
632 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType); | |
633 | |
634 if (!FixedAllocas.empty() || !AlignedAllocas.empty()) | 627 if (!FixedAllocas.empty() || !AlignedAllocas.empty()) |
635 // No use calling findRematerializable() unless there is some | 628 // No use calling findRematerializable() unless there is some |
636 // rematerializable alloca instruction to seed it. | 629 // rematerializable alloca instruction to seed it. |
637 findRematerializable(); | 630 findRematerializable(); |
638 } | 631 } |
639 | 632 |
640 namespace { | 633 namespace { |
641 | 634 |
642 // Helpers for findRematerializable(). For each of them, if a suitable | 635 // Helpers for findRematerializable(). For each of them, if a suitable |
643 // rematerialization is found, the instruction's Dest variable is set to be | 636 // rematerialization is found, the instruction's Dest variable is set to be |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 } | 1089 } |
1097 } | 1090 } |
1098 // Print each basic block | 1091 // Print each basic block |
1099 for (CfgNode *Node : Nodes) | 1092 for (CfgNode *Node : Nodes) |
1100 Node->dump(this); | 1093 Node->dump(this); |
1101 if (isVerbose(IceV_Instructions)) | 1094 if (isVerbose(IceV_Instructions)) |
1102 Str << "}\n"; | 1095 Str << "}\n"; |
1103 } | 1096 } |
1104 | 1097 |
1105 } // end of namespace Ice | 1098 } // end of namespace Ice |
OLD | NEW |