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

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: Final code review comments 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/IceConverter.cpp » ('j') | no next file with comments »
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 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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/IceConverter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698