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

Side by Side Diff: src/IceCfgNode.cpp

Issue 682983004: Subzero: Decorate the text asm output with register availability info. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Refactor LiveIn/LiveOut printing into a common routine Created 6 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
OLDNEW
1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) 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 // This file implements the CfgNode class, including the complexities 10 // This file implements the CfgNode class, including the complexities
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 } 749 }
750 750
751 // If this node contains only deleted instructions, and ends in an 751 // If this node contains only deleted instructions, and ends in an
752 // unconditional branch, contract the node by repointing all its 752 // unconditional branch, contract the node by repointing all its
753 // in-edges to its successor. 753 // in-edges to its successor.
754 void CfgNode::contractIfEmpty() { 754 void CfgNode::contractIfEmpty() {
755 if (InEdges.size() == 0) 755 if (InEdges.size() == 0)
756 return; 756 return;
757 Inst *Branch = NULL; 757 Inst *Branch = NULL;
758 for (Inst *I : Insts) { 758 for (Inst *I : Insts) {
759 if (!I->isDeleted() && !I->isUnconditionalBranch()) 759 if (I->isUnconditionalBranch())
jvoung (off chromium) 2014/10/31 16:56:42 This doesn't seem to check anymore if the Uncondit
Jim Stichnoth 2014/11/01 14:49:40 Ouch, done. I should try to make InstList into a
760 Branch = I;
761 else if (!I->isDeleted() && !I->isRedundantAssign())
760 return; 762 return;
761 Branch = I;
762 } 763 }
763 Branch->setDeleted(); 764 Branch->setDeleted();
764 assert(OutEdges.size() == 1); 765 assert(OutEdges.size() == 1);
765 // Repoint all this node's in-edges to this node's successor. 766 // Repoint all this node's in-edges to this node's successor.
766 for (CfgNode *Pred : InEdges) { 767 for (CfgNode *Pred : InEdges) {
767 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E; 768 for (auto I = Pred->OutEdges.begin(), E = Pred->OutEdges.end(); I != E;
768 ++I) { 769 ++I) {
769 if (*I == this) { 770 if (*I == this) {
770 *I = OutEdges[0]; 771 *I = OutEdges[0];
771 OutEdges[0]->InEdges.push_back(Pred); 772 OutEdges[0]->InEdges.push_back(Pred);
(...skipping 19 matching lines...) Expand all
791 // (currently not the case for x86 lowering). 792 // (currently not the case for x86 lowering).
792 for (Inst *I : Insts) { 793 for (Inst *I : Insts) {
793 if (!I->isDeleted()) { 794 if (!I->isDeleted()) {
794 Target->doBranchOpt(I, NextNode); 795 Target->doBranchOpt(I, NextNode);
795 } 796 }
796 } 797 }
797 } 798 }
798 799
799 // ======================== Dump routines ======================== // 800 // ======================== Dump routines ======================== //
800 801
802 namespace {
803
804 // Helper function for emit().
805 void emitRegisterUsage(Ostream &Str, Cfg *Func, const CfgNode *Node,
jvoung (off chromium) 2014/10/31 16:56:42 Func can be const?
Jim Stichnoth 2014/11/01 14:49:40 Done.
806 bool IsLiveIn, std::vector<SizeT> &LiveRegCount) {
807 Liveness *Liveness = Func->getLiveness();
808 const LivenessBV *Live;
809 if (IsLiveIn) {
810 Live = &Liveness->getLiveIn(Node);
811 Str << "\t\t\t\t# LiveIn=";
812 } else {
813 Live = &Liveness->getLiveOut(Node);
814 Str << "\t\t\t\t# LiveOut=";
815 }
816 if (!Live->empty()) {
817 bool First = true;
818 for (SizeT i = 0; i < Live->size(); ++i) {
819 if ((*Live)[i]) {
820 Variable *Var = Liveness->getVariable(i, Node);
821 if (Var->hasReg()) {
822 if (IsLiveIn)
823 ++LiveRegCount[Var->getRegNum()];
824 if (!First)
825 Str << ",";
826 First = false;
827 Var->emit(Func);
828 }
829 }
830 }
831 }
832 Str << "\n";
833 }
834
835 } // end of anonymous namespace
836
801 void CfgNode::emit(Cfg *Func) const { 837 void CfgNode::emit(Cfg *Func) const {
802 Func->setCurrentNode(this); 838 Func->setCurrentNode(this);
803 Ostream &Str = Func->getContext()->getStrEmit(); 839 Ostream &Str = Func->getContext()->getStrEmit();
840 Liveness *Liveness = Func->getLiveness();
841 bool DecorateAsm = Liveness && Func->getContext()->getFlags().DecorateAsm;
804 if (Func->getEntryNode() == this) { 842 if (Func->getEntryNode() == this) {
805 Str << Func->getContext()->mangleName(Func->getFunctionName()) << ":\n"; 843 Str << Func->getContext()->mangleName(Func->getFunctionName()) << ":\n";
806 } 844 }
807 Str << getAsmName() << ":\n"; 845 Str << getAsmName() << ":\n";
808 if (Func->useIntegratedAssembler()) { 846 if (Func->useIntegratedAssembler()) {
809 Assembler *Asm = Func->getAssembler<Assembler>(); 847 Assembler *Asm = Func->getAssembler<Assembler>();
810 Asm->BindCfgNodeLabel(getIndex()); 848 Asm->BindCfgNodeLabel(getIndex());
811 } 849 }
850 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters());
851 if (DecorateAsm)
852 emitRegisterUsage(Str, Func, this, true, LiveRegCount);
853
812 for (InstPhi *Phi : Phis) { 854 for (InstPhi *Phi : Phis) {
813 if (Phi->isDeleted()) 855 if (Phi->isDeleted())
814 continue; 856 continue;
815 // Emitting a Phi instruction should cause an error. 857 // Emitting a Phi instruction should cause an error.
816 Inst *Instr = Phi; 858 Inst *Instr = Phi;
817 Instr->emit(Func); 859 Instr->emit(Func);
818 } 860 }
819 for (Inst *I : Insts) { 861 for (Inst *I : Insts) {
820 if (I->isDeleted()) 862 if (I->isDeleted())
821 continue; 863 continue;
864 if (I->isRedundantAssign()) {
865 Variable *Dest = I->getDest();
866 if (DecorateAsm && Dest->hasReg() && !I->isLastUse(I->getSrc(0)))
867 ++LiveRegCount[Dest->getRegNum()];
868 continue;
869 }
822 if (Func->useIntegratedAssembler()) { 870 if (Func->useIntegratedAssembler()) {
823 I->emitIAS(Func); 871 I->emitIAS(Func);
824 } else { 872 } else {
825 I->emit(Func); 873 I->emit(Func);
874 if (DecorateAsm) {
875 // Add end-of-live-range comment.
876 bool First = true;
877 Inst *Instr = I;
jvoung (off chromium) 2014/10/31 16:56:42 Can this be factored out into a function too? At
Jim Stichnoth 2014/11/01 14:49:40 Done.
878 Variable *Dest = Instr->getDest();
879 if (Dest && Dest->hasReg())
880 ++LiveRegCount[Dest->getRegNum()];
881 for (SizeT I = 0; I < Instr->getSrcSize(); ++I) {
882 Operand *Src = Instr->getSrc(I);
883 SizeT NumVars = Src->getNumVars();
884 for (SizeT J = 0; J < NumVars; ++J) {
885 const Variable *Var = Src->getVar(J);
886 if (Var->hasReg()) {
887 if (Instr->isLastUse(Var) &&
888 --LiveRegCount[Var->getRegNum()] == 0) {
889 if (First)
890 Str << " \t# END=";
891 else
892 Str << ",";
893 Var->emit(Func);
894 First = false;
895 }
896 }
897 }
898 }
899 }
826 Str << "\n"; 900 Str << "\n";
827 } 901 }
828 // Update emitted instruction count, plus fill/spill count for 902 // Update emitted instruction count, plus fill/spill count for
829 // Variable operands without a physical register. 903 // Variable operands without a physical register.
830 if (uint32_t Count = I->getEmitInstCount()) { 904 if (uint32_t Count = I->getEmitInstCount()) {
831 Func->getContext()->statsUpdateEmitted(Count); 905 Func->getContext()->statsUpdateEmitted(Count);
832 if (Variable *Dest = I->getDest()) { 906 if (Variable *Dest = I->getDest()) {
833 if (!Dest->hasReg()) 907 if (!Dest->hasReg())
834 Func->getContext()->statsUpdateFills(); 908 Func->getContext()->statsUpdateFills();
835 } 909 }
836 for (SizeT S = 0; S < I->getSrcSize(); ++S) { 910 for (SizeT S = 0; S < I->getSrcSize(); ++S) {
837 if (Variable *Src = llvm::dyn_cast<Variable>(I->getSrc(S))) { 911 if (Variable *Src = llvm::dyn_cast<Variable>(I->getSrc(S))) {
838 if (!Src->hasReg()) 912 if (!Src->hasReg())
839 Func->getContext()->statsUpdateSpills(); 913 Func->getContext()->statsUpdateSpills();
840 } 914 }
841 } 915 }
842 } 916 }
843 } 917 }
918 if (DecorateAsm)
919 emitRegisterUsage(Str, Func, this, false, LiveRegCount);
844 } 920 }
845 921
846 void CfgNode::dump(Cfg *Func) const { 922 void CfgNode::dump(Cfg *Func) const {
847 Func->setCurrentNode(this); 923 Func->setCurrentNode(this);
848 Ostream &Str = Func->getContext()->getStrDump(); 924 Ostream &Str = Func->getContext()->getStrDump();
849 Liveness *Liveness = Func->getLiveness(); 925 Liveness *Liveness = Func->getLiveness();
850 if (Func->getContext()->isVerbose(IceV_Instructions)) { 926 if (Func->getContext()->isVerbose(IceV_Instructions)) {
851 Str << getName() << ":\n"; 927 Str << getName() << ":\n";
852 } 928 }
853 // Dump list of predecessor nodes. 929 // Dump list of predecessor nodes.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 if (!First) 989 if (!First)
914 Str << ", "; 990 Str << ", ";
915 First = false; 991 First = false;
916 Str << "%" << I->getName(); 992 Str << "%" << I->getName();
917 } 993 }
918 Str << "\n"; 994 Str << "\n";
919 } 995 }
920 } 996 }
921 997
922 } // end of namespace Ice 998 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfg.cpp ('k') | src/IceClFlags.h » ('j') | src/llvm2ice.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698