Chromium Code Reviews| 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 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 // do not have a known offset from either the stack or frame pointer. | 623 // do not have a known offset from either the stack or frame pointer. |
| 624 // They grow up from a user pointer from an alloca. | 624 // They grow up from a user pointer from an alloca. |
| 625 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer); | 625 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer); |
| 626 } | 626 } |
| 627 // Otherwise, fixed size allocas are always addressed relative to the stack | 627 // Otherwise, fixed size allocas are always addressed relative to the stack |
| 628 // unless there are dynamic allocas. | 628 // unless there are dynamic allocas. |
| 629 // TODO(sehr): re-enable frame pointer and decrementing addressing. | 629 // TODO(sehr): re-enable frame pointer and decrementing addressing. |
| 630 AllocaBaseVariableType BasePointerType = | 630 AllocaBaseVariableType BasePointerType = |
| 631 (HasDynamicAllocation ? BVT_UserPointer : BVT_StackPointer); | 631 (HasDynamicAllocation ? BVT_UserPointer : BVT_StackPointer); |
| 632 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType); | 632 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType); |
| 633 | |
| 634 if (!FixedAllocas.empty() || !AlignedAllocas.empty()) | |
| 635 // No use calling findRematerializable() unless there is some | |
| 636 // rematerializable alloca instruction to seed it. | |
| 637 findRematerializable(); | |
| 638 } | |
| 639 | |
| 640 /// Scan the function to find additional rematerializable variables. This is | |
| 641 /// possible when the source operand of an InstAssignment is a rematerializable | |
| 642 /// variable, or the same for a pointer-type InstCast::Bitcast, or when an | |
| 643 /// InstArithmetic is an add of a rematerializable variable and an immediate. | |
| 644 /// Note that InstAssignment instructions and pointer-type InstCast::Bitcast | |
| 645 /// instructions generally only come about from the IceConverter's treatment of | |
| 646 /// inttoptr, ptrtoint, and bitcast instructions. TODO(stichnot): Consider | |
| 647 /// other possibilities, however unlikely, such as InstArithmetic::Sub, or | |
| 648 /// commutativity. | |
| 649 void Cfg::findRematerializable() { | |
| 650 // Scan the instructions in order, and repeat until no new opportunities are | |
| 651 // found. It may take more than one iteration because a variable's defining | |
| 652 // block may happen to come after a block where it is used, depending on the | |
| 653 // CfgNode linearization order. | |
| 654 bool FoundNewAssignment; | |
| 655 do { | |
| 656 FoundNewAssignment = false; | |
| 657 for (CfgNode *Node : getNodes()) { | |
| 658 // No need to process Phi instructions. | |
| 659 for (Inst &Instr : Node->getInsts()) { | |
| 660 if (Instr.isDeleted()) | |
| 661 continue; | |
| 662 Variable *Dest = Instr.getDest(); | |
| 663 if (Dest == nullptr) | |
| 664 continue; | |
| 665 if (Dest->isRematerializable()) | |
| 666 continue; | |
| 667 if (auto *Arith = llvm::dyn_cast<InstArithmetic>(&Instr)) { | |
| 668 // Just look at Add for now. | |
| 669 if (Arith->getOp() == InstArithmetic::Add) { | |
| 670 // Assume "v+10" for now, don't bother considering "10+v". | |
| 671 if (auto *Src0Var = llvm::dyn_cast<Variable>(Arith->getSrc(0))) { | |
| 672 if (Src0Var->isRematerializable()) { | |
|
John
2015/11/12 20:43:14
soooo many nest levels. My brain hurts... :(
Jim Stichnoth
2015/11/12 21:02:44
I hear you... Unfortunately, the "best" order for
John
2015/11/12 21:11:39
I would create small helper functions, e.g.,
if (
Jim Stichnoth
2015/11/13 01:18:47
OK thanks. I split it into helper calls. PTAL.
| |
| 673 if (auto *Src1Imm = | |
| 674 llvm::dyn_cast<ConstantInteger32>(Arith->getSrc(1))) { | |
| 675 Dest->setRematerializable(Src0Var->getRegNum(), | |
| 676 Src0Var->getStackOffset() + | |
| 677 Src1Imm->getValue()); | |
| 678 FoundNewAssignment = true; | |
| 679 } | |
| 680 } | |
| 681 } | |
| 682 } | |
| 683 continue; | |
| 684 } // end of InstArithmetic | |
| 685 if (auto *Assign = llvm::dyn_cast<InstAssign>(&Instr)) { | |
| 686 if (auto *Src0Var = llvm::dyn_cast<Variable>(Assign->getSrc(0))) { | |
| 687 if (Src0Var->isRematerializable()) { | |
| 688 Dest->setRematerializable(Src0Var->getRegNum(), | |
| 689 Src0Var->getStackOffset()); | |
| 690 FoundNewAssignment = true; | |
| 691 } | |
| 692 } | |
| 693 continue; | |
| 694 } // end of InstAssign | |
| 695 if (auto *Cast = llvm::dyn_cast<InstCast>(&Instr)) { | |
| 696 if (Cast->getCastKind() == InstCast::Bitcast) { | |
| 697 if (auto *Src0Var = llvm::dyn_cast<Variable>(Cast->getSrc(0))) { | |
| 698 if (Src0Var->isRematerializable() && | |
| 699 Src0Var->getType() == Dest->getType()) { | |
| 700 Dest->setRematerializable(Src0Var->getRegNum(), | |
| 701 Src0Var->getStackOffset()); | |
| 702 FoundNewAssignment = true; | |
| 703 } | |
| 704 } | |
| 705 } | |
| 706 } // end of InstCast | |
| 707 } | |
| 708 } | |
| 709 } while (FoundNewAssignment); | |
| 633 } | 710 } |
| 634 | 711 |
| 635 void Cfg::doAddressOpt() { | 712 void Cfg::doAddressOpt() { |
| 636 TimerMarker T(TimerStack::TT_doAddressOpt, this); | 713 TimerMarker T(TimerStack::TT_doAddressOpt, this); |
| 637 for (CfgNode *Node : Nodes) | 714 for (CfgNode *Node : Nodes) |
| 638 Node->doAddressOpt(); | 715 Node->doAddressOpt(); |
| 639 } | 716 } |
| 640 | 717 |
| 641 void Cfg::doNopInsertion() { | 718 void Cfg::doNopInsertion() { |
| 642 if (!Ctx->getFlags().shouldDoNopInsertion()) | 719 if (!Ctx->getFlags().shouldDoNopInsertion()) |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 900 OstreamLocker L(Ctx); | 977 OstreamLocker L(Ctx); |
| 901 Ostream &Str = Ctx->getStrEmit(); | 978 Ostream &Str = Ctx->getStrEmit(); |
| 902 IceString MangledName = Ctx->mangleName(getFunctionName()); | 979 IceString MangledName = Ctx->mangleName(getFunctionName()); |
| 903 const Assembler *Asm = getAssembler<>(); | 980 const Assembler *Asm = getAssembler<>(); |
| 904 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); | 981 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
| 905 | 982 |
| 906 emitTextHeader(MangledName, Ctx, Asm); | 983 emitTextHeader(MangledName, Ctx, Asm); |
| 907 deleteJumpTableInsts(); | 984 deleteJumpTableInsts(); |
| 908 if (Ctx->getFlags().getDecorateAsm()) { | 985 if (Ctx->getFlags().getDecorateAsm()) { |
| 909 for (Variable *Var : getVariables()) { | 986 for (Variable *Var : getVariables()) { |
| 910 if (Var->getStackOffset()) { | 987 if (Var->getStackOffset() && !Var->isRematerializable()) { |
| 911 Str << "\t" << Var->getSymbolicStackOffset(this) << " = " | 988 Str << "\t" << Var->getSymbolicStackOffset(this) << " = " |
| 912 << Var->getStackOffset() << "\n"; | 989 << Var->getStackOffset() << "\n"; |
| 913 } | 990 } |
| 914 } | 991 } |
| 915 } | 992 } |
| 916 for (CfgNode *Node : Nodes) { | 993 for (CfgNode *Node : Nodes) { |
| 917 if (NeedSandboxing && Node->needsAlignment()) { | 994 if (NeedSandboxing && Node->needsAlignment()) { |
| 918 Str << "\t" << Asm->getAlignDirective() << " " | 995 Str << "\t" << Asm->getAlignDirective() << " " |
| 919 << Asm->getBundleAlignLog2Bytes() << "\n"; | 996 << Asm->getBundleAlignLog2Bytes() << "\n"; |
| 920 } | 997 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 994 } | 1071 } |
| 995 } | 1072 } |
| 996 // Print each basic block | 1073 // Print each basic block |
| 997 for (CfgNode *Node : Nodes) | 1074 for (CfgNode *Node : Nodes) |
| 998 Node->dump(this); | 1075 Node->dump(this); |
| 999 if (isVerbose(IceV_Instructions)) | 1076 if (isVerbose(IceV_Instructions)) |
| 1000 Str << "}\n"; | 1077 Str << "}\n"; |
| 1001 } | 1078 } |
| 1002 | 1079 |
| 1003 } // end of namespace Ice | 1080 } // end of namespace Ice |
| OLD | NEW |