Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: src/IceCfg.cpp

Issue 1435363002: Merge fixed alloca stack adjustments into the prolog (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix rebase issues. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/IceInstX8632.cpp » ('j') | src/IceInstX8632.cpp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
499 // Emit one addition for each alloca after the first. 499 switch (BaseVariableType) {
500 for (size_t i = 0; i < Allocas.size(); ++i) { 500 case BVT_UserPointer: {
501 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); 501 Variable *BaseVariable = makeVariable(IceType_i32);
502 switch (BaseVariableType) { 502 for (size_t i = 0; i < Allocas.size(); ++i) {
Jim Stichnoth 2015/11/16 14:47:57 For better or worse, most of the Subzero code that
sehr 2015/11/16 18:42:24 Done.
503 case BVT_FramePointer: 503 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
504 case BVT_UserPointer: {
505 // Emit a new addition operation to replace the alloca. 504 // Emit a new addition operation to replace the alloca.
506 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]); 505 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]);
507 InstArithmetic *Add = 506 InstArithmetic *Add =
508 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(), 507 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(),
509 BaseVariable, AllocaOffset); 508 BaseVariable, AllocaOffset);
510 Insts.push_front(Add); 509 Insts.push_front(Add);
511 } break; 510 Alloca->setDeleted();
512 case BVT_StackPointer: { 511 }
512 Operand *AllocaSize = Ctx->getConstantInt32(TotalSize);
513 InstAlloca *CombinedAlloca =
514 InstAlloca::create(this, AllocaSize, CombinedAlignment, BaseVariable);
Jim Stichnoth 2015/11/16 14:47:57 Wow, I just realized that InstAlloca is unique amo
sehr 2015/11/16 18:42:24 Done.
515 CombinedAlloca->setKnownFrameOffset();
516 Insts.push_front(CombinedAlloca);
517 } break;
518 case BVT_StackPointer:
519 case BVT_FramePointer: {
520 for (size_t i = 0; i < Allocas.size(); ++i) {
521 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
513 // Emit a fake definition of the rematerializable variable. 522 // Emit a fake definition of the rematerializable variable.
514 Variable *Dest = Alloca->getDest(); 523 Variable *Dest = Alloca->getDest();
515 InstFakeDef *Def = InstFakeDef::create(this, Dest); 524 InstFakeDef *Def = InstFakeDef::create(this, Dest);
516 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]); 525 if (BaseVariableType == BVT_StackPointer)
526 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]);
527 else
528 Dest->setRematerializable(getTarget()->getFrameReg(), Offsets[i]);
517 Insts.push_front(Def); 529 Insts.push_front(Def);
518 } break; 530 Alloca->setDeleted();
519 } 531 }
520 Alloca->setDeleted(); 532 // Allocate the fixed area in the function prolog.
533 getTarget()->reserveFixedAllocaArea(TotalSize, CombinedAlignment);
534 } break;
521 } 535 }
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 } 536 }
545 537
546 void Cfg::processAllocas(bool SortAndCombine) { 538 void Cfg::processAllocas(bool SortAndCombine) {
547 const uint32_t StackAlignment = getTarget()->getStackAlignment(); 539 const uint32_t StackAlignment = getTarget()->getStackAlignment();
548 CfgNode *EntryNode = getEntryNode(); 540 CfgNode *EntryNode = getEntryNode();
549 // LLVM enforces power of 2 alignment. 541 // LLVM enforces power of 2 alignment.
550 assert(llvm::isPowerOf2_32(StackAlignment)); 542 assert(llvm::isPowerOf2_32(StackAlignment));
551 // Determine if there are large alignment allocations in the entry block or 543 // Determine if there are large alignment allocations in the entry block or
552 // dynamic allocations (variable size in the entry block). 544 // dynamic allocations (variable size in the entry block).
553 bool HasLargeAlignment = false; 545 bool HasLargeAlignment = false;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 // Mark the target as requiring a frame pointer. 580 // Mark the target as requiring a frame pointer.
589 if (HasLargeAlignment || HasDynamicAllocation) 581 if (HasLargeAlignment || HasDynamicAllocation)
590 getTarget()->setHasFramePointer(); 582 getTarget()->setHasFramePointer();
591 // Collect the Allocas into the two vectors. 583 // Collect the Allocas into the two vectors.
592 // Allocas in the entry block that have constant size and alignment less 584 // Allocas in the entry block that have constant size and alignment less
593 // than or equal to the function's stack alignment. 585 // than or equal to the function's stack alignment.
594 CfgVector<Inst *> FixedAllocas; 586 CfgVector<Inst *> FixedAllocas;
595 // Allocas in the entry block that have constant size and alignment greater 587 // Allocas in the entry block that have constant size and alignment greater
596 // than the function's stack alignment. 588 // than the function's stack alignment.
597 CfgVector<Inst *> AlignedAllocas; 589 CfgVector<Inst *> AlignedAllocas;
598 // Maximum alignment used for the dynamic/aligned allocas. 590 // Maximum alignment used by any alloca.
599 uint32_t MaxAlignment = StackAlignment; 591 uint32_t MaxAlignment = StackAlignment;
600 for (Inst &Instr : EntryNode->getInsts()) { 592 for (Inst &Instr : EntryNode->getInsts()) {
601 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) { 593 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
602 if (!llvm::isa<Constant>(Alloca->getSizeInBytes())) 594 if (!llvm::isa<Constant>(Alloca->getSizeInBytes()))
603 continue; 595 continue;
604 uint32_t AlignmentParam = Alloca->getAlignInBytes(); 596 uint32_t AlignmentParam = Alloca->getAlignInBytes();
605 // For default align=0, set it to the real value 1, to avoid any 597 // For default align=0, set it to the real value 1, to avoid any
606 // bit-manipulation problems below. 598 // bit-manipulation problems below.
607 AlignmentParam = std::max(AlignmentParam, 1u); 599 AlignmentParam = std::max(AlignmentParam, 1u);
608 assert(llvm::isPowerOf2_32(AlignmentParam)); 600 assert(llvm::isPowerOf2_32(AlignmentParam));
609 if (HasDynamicAllocation && AlignmentParam > StackAlignment) { 601 if (HasDynamicAllocation && AlignmentParam > StackAlignment) {
610 // If we have both dynamic allocations and large stack alignments, 602 // If we have both dynamic allocations and large stack alignments,
611 // high-alignment allocations are pulled out with their own base. 603 // high-alignment allocations are pulled out with their own base.
612 AlignedAllocas.push_back(Alloca); 604 AlignedAllocas.push_back(Alloca);
613 } else { 605 } else {
614 FixedAllocas.push_back(Alloca); 606 FixedAllocas.push_back(Alloca);
615 } 607 }
616 MaxAlignment = std::max(AlignmentParam, MaxAlignment); 608 MaxAlignment = std::max(AlignmentParam, MaxAlignment);
617 } 609 }
618 } 610 }
619 // Add instructions to the head of the entry block in reverse order. 611 // Add instructions to the head of the entry block in reverse order.
620 InstList &Insts = getEntryNode()->getInsts(); 612 InstList &Insts = getEntryNode()->getInsts();
621 if (HasDynamicAllocation && HasLargeAlignment) { 613 if (HasDynamicAllocation && HasLargeAlignment) {
622 // We are using a frame pointer, but fixed large-alignment alloca addresses, 614 // 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. 615 // do not have a known offset from either the stack or frame pointer.
624 // They grow up from a user pointer from an alloca. 616 // They grow up from a user pointer from an alloca.
625 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer); 617 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer);
618 // Fixed size allocas are addressed relative to the frame pointer.
619 sortAndCombineAllocas(FixedAllocas, StackAlignment, Insts,
620 BVT_FramePointer);
621 } else {
622 // Otherwise, fixed size allocas are addressed relative to the stack unless
623 // there are dynamic allocas.
624 AllocaBaseVariableType BasePointerType =
John 2015/11/16 14:00:02 const AllocaBaseVariableType
sehr 2015/11/16 18:42:24 Done.
625 (HasDynamicAllocation ? BVT_FramePointer : BVT_StackPointer);
626 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType);
626 } 627 }
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()) 628 if (!FixedAllocas.empty() || !AlignedAllocas.empty())
635 // No use calling findRematerializable() unless there is some 629 // No use calling findRematerializable() unless there is some
636 // rematerializable alloca instruction to seed it. 630 // rematerializable alloca instruction to seed it.
637 findRematerializable(); 631 findRematerializable();
638 } 632 }
639 633
640 namespace { 634 namespace {
641 635
642 // Helpers for findRematerializable(). For each of them, if a suitable 636 // Helpers for findRematerializable(). For each of them, if a suitable
643 // rematerialization is found, the instruction's Dest variable is set to be 637 // rematerialization is found, the instruction's Dest variable is set to be
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 } 1090 }
1097 } 1091 }
1098 // Print each basic block 1092 // Print each basic block
1099 for (CfgNode *Node : Nodes) 1093 for (CfgNode *Node : Nodes)
1100 Node->dump(this); 1094 Node->dump(this);
1101 if (isVerbose(IceV_Instructions)) 1095 if (isVerbose(IceV_Instructions))
1102 Str << "}\n"; 1096 Str << "}\n";
1103 } 1097 }
1104 1098
1105 } // end of namespace Ice 1099 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | src/IceInstX8632.cpp » ('j') | src/IceInstX8632.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698