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 |