Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

nodes.h

Go to the documentation of this file.
00001 #include "misc.h"
00002 #include "timerange.h" 
00003 
00004 // #include "segment.h"
00005 
00006 #ifndef NODES_H
00007 #define NODES_H
00008 
00009 #include "instr.h"
00010 #include "var_access.h"
00011 #include "vars.h"
00012 #include "labels.h"
00013 #include "directives.h"
00014 #include "stringlist.h"
00015 
00016 #include <vector>
00017 #include <string>
00018 
00019 typedef enum NEXT_ASM_TOKEN_TYPE { OPCODE, OPERAND };
00020 
00021 class CCDGNode;
00022 class CGuestInfo;
00023 class CFG_Node;
00024 class CPred;
00025 class CCode;
00026 class Infinite_Nodes;
00027 class CLoop;
00028 
00034 class CCDGNodeList {
00036   CCDGNode * Node;
00038   char Name[STR_SIZE];
00040   NODE_TYPE Type;
00042   CCDGNodeList * Next, * Prev;
00044   TRUTH_VALUE_TYPE TV;
00046   int Trunc;
00048   CFG_Node * Parent;
00049  public:
00051   CCDGNodeList() { 
00052     Node = NULL; Next = Prev = NULL; TV = TV_A; Trunc = 0; 
00053     Name[0] = '\0'; Parent = NULL;
00054   }
00056   CCDGNodeList(CCDGNode * node, TRUTH_VALUE_TYPE tv, int trunc=0);
00059   CCDGNodeList(char * name, NODE_TYPE type, TRUTH_VALUE_TYPE tv);
00061   CCDGNodeList(CCDGNodeList * orig);
00064   CCDGNodeList * Copy_Subgraph();
00072   CCDGNodeList * Add_Node(CCDGNode * p, TRUTH_VALUE_TYPE tv, int trunc=0);
00073   
00074   CCDGNodeList * Add_Node(char * name, NODE_TYPE type, TRUTH_VALUE_TYPE tv);
00075   CCDGNodeList * Add_Node(char * start, bool before);
00076   CCDGNodeList * Add_NodeList(CCDGNodeList * nl);
00077   CCDGNodeList * Insert_Node(CCDGNode * new_node, CCDGNode * ref, bool before,
00078                  TRUTH_VALUE_TYPE tv=TV_ANY);
00080 
00088   void Set_Next(CCDGNodeList * next) { 
00089       Next = next; 
00090   }
00091 
00095   CCDGNodeList * Get_Next() { return Next; };
00097   CCDGNodeList * Advance_To_Next_Guest(CGuestInfo * cur_gst, 
00098                        GUEST_STATE_TYPE & which_guest, 
00099                        CCDGNode * * nxt_gst_node, 
00100                        bool skip_all_preds,
00101                        bool skip_ABL_pred);
00102   
00103   void Set_Prev(CCDGNodeList * prev) { Prev = prev; }
00104   CCDGNodeList * Get_Prev() { return Prev; };
00105   
00106   CCDGNode * Get_Node() { if (this) return Node; else return NULL; };
00107   void Set_Node(CCDGNode * node) { Node = node; };
00108   char * Get_Name() { return Name; };
00109   CCDGNodeList * Get_Last();
00110   NODE_TYPE Get_Type() { return Type; };
00111   TRUTH_VALUE_TYPE Get_TV() { return TV; };
00112 
00116   void Append_Suffix_To_Names(char * str);
00117   
00118   void Set_Trunc(int trunc) { Trunc = trunc; }
00119   int Get_Trunc() { return Trunc; }
00120   
00123   CInstr * MakeNormOp(int instrclass,long best,long worst,char *oper1=NULL,char *oper2=NULL, char *oper3=NULL);
00124   CCDGNodeList * Remove_Node(int number);
00125   CCDGNodeList * Remove_Node(CCDGNode * p);
00126   bool Already_Contains(CCDGNode * node);
00127   CCDGNode * Find_Node(const char * name, NODE_TYPE type, bool dir_forward=true);
00128   CCDGNode * Find_Nodes_Branching_Here(char * name, CCDGNodeList * * nodelist, 
00129                        bool find_all);
00130   CCDGNode * Find_Nodes_Branching_Here(CCDGNode * node, CCDGNodeList
00131                        * * nodelist, bool find_all);
00132 
00133   int Num_Nodes_Branching_Here(char * name);
00134   int Num_Nodes_Branching_Here(CCDGNode * node);
00135   CCDGNode * Process_Multiple_Merge_Points(CCDGNode * node);
00136 
00137   CCDGNode * Find_Node_Before_Inc(const char * name, NODE_TYPE type, 
00138                   CCDGNodeList * end_lp);
00139   CCDGNode * Find_Node_Skipping_Here( void );
00140 
00141   void Extract_Dirs(char * asm_filename);
00142   void Label_Nodes();
00143   void Find_Vars();
00144   void Virtualize_Registers();
00145   
00146   void Gen_Jitter_Plots(char * base_filename);
00147   void Gen_Graphs();
00148   void Plot_Segments(char * base_filename);
00149   void Gen_GnuPlot_Driver(char * orig_filename, PLOT_TYPE plot);
00150   void Gen_Code(char * orig_filename);
00151   
00152   bool Verify_Jumps_Can_Be_Ignored(CCDGNode * ret_node);
00153 
00159   CCDGNodeList * Build_CDGs_From_Flat_Code();
00160 
00161   void Build_CFGs_From_Flat_Code();
00162   void Add_Exit(CCDGNodeList * exit);
00163   //  CCDGNodeList * Build_CDGs_From_CFGs();
00164   CCDGNodeList * Build_CDGs_via_CFGs() __attribute__ ((deprecated));
00165   CCDGNode * Find_Common_Ancestor();
00166 
00167   void Do_STA(bool include_guest=TRUE);
00168   void Find_Segments(long max_jitter);
00169   void Pad_Jitter(bool pad_host, bool pad_guest);
00170   void Find_Blocking_IO_Loops();
00171   void Pad_Leaving_Loop_Intact(long cocall_period,
00172                    bool look_for_unique_loop, 
00173                    char* loop_name_passed);
00174   void Prepare_Pad_And_Transform_Loop(CCDGNode* cur_node, long cocall_period,
00175                       CPred* final_pred, bool loop_specific_code);
00176 
00177   void Reallocate_Regs(REALLOC_TYPE realloc_method);
00178   void Convert_PC_Relative_Branches();
00179   void Convert_Local_Labels_And_Branches();
00180 
00181   CCDGNodeList * Guard(int reg, int bit, bool exec_condition);
00182   CCDGNodeList * New_Guard(int reg, int bit, bool exec_condition);
00183   CCDGNodeList * Add_NodeList(char * start, bool before);
00184   
00185   void Pr_Info(); 
00186   void Pr_Name();
00187   void Pr_Type();
00188   
00189   void Output_Debug();
00190   void Output_Debug_Names();
00191   void Print_Directives();
00192   void Set_Visited (bool v);
00193   long Count_Instrs();
00194   
00202   CCDGNodeList * Build_CDGs_via_CFGs(char * filename);
00203   CCDGNode * Get_Node_With_Label(char *label);
00204 
00208   void Handle_Start();
00209   void Handle_Default();
00210 
00212 
00216   void Handle_Ctrans();
00217   void Handle_Utrans();
00218   void Handle_Skip();
00219   void Handle_Utrans_Routine();
00220   CCDGNodeList * Handle_Utrans_Return();
00222 
00223   void Set_Parent(CFG_Node *p_parent)
00224   {   Parent=p_parent;     
00225   }
00226   CFG_Node * Get_Parent()
00227   {   return Parent;  
00228   }
00229 
00230 
00236   CFG_Node * Build_CFG_Node_Tree(int *n,CFG_Node *parent,CFG_Node *prev);
00237 
00239   void Set_Name(char * p_name);
00240 
00241   /* 
00242      void Build_CFG_VCG(char * filename);     
00243      void Build_CFG_VCG(ofstream &vcg_stream, int i);
00244   */
00245   void Fix_Call_Nodes();
00246   void Fix_Branch_Targets();
00247   void Fix_Short_Branches();
00248 
00249   void Open_CFG_VCG_File(char * CFG_VCG_filename);
00250   void Add_To_CFG_VCG_File(char * CFG_VCG_filename);
00251   void Close_CFG_VCG_File(char * CFG_VCG_filename);
00252   void Build_CFG_VCG_File(int i, char * CFG_VCG_filename);
00253   void Build_CFG_VCG_File(int i, bool f, char * CFG_VCG_filename);
00254 
00255   // these functions don't seem to be implemented anywhere:  
00256   // void Open_CFG_File();
00257   // void Add_To_CFG_File();
00258   // void CCDGNodeList :: Close_CFG_File();
00259 
00260   void Build_CFG_VCG(int i);
00261   void Build_CFG_VCG(int i, bool f);
00262   //void Open_CFG_VCG_File(char * CFG_VCG_filename);
00263   //void Add_To_CFG_VCG_File(char * CFG_VCG_filename);
00264   //void Close_CFG_VCG_File(char * CFG_VCG_filename);
00265   //void Build_CFG_VCG_File(int i, char * CFG_VCG_filename);
00266   //void Build_CFG_VCG_File(int i, bool f, char * CFG_VCG_filename);
00267   CCDGNodeList * Build_CDGs_for_Proc(CCDGNodeList * proc, CCDGNodeList * recent_nodes_end, CCDGNodeList * exit);
00268   CCDGNodeList * Build_CFGs_and_CDGs(CCDGNodeList * recent_procs, 
00269                      char * source_filename);
00270 
00274   CCDGNodeList * Add_Exit_Node();
00275 
00276   char * Get_Function_Name();
00277 
00278   CCDGNodeList * Compute_Code_End(bool begin);
00279   void Fix_Infinite_Blocks(CCDGNodeList * start, CCDGNodeList * exit);
00280   Infinite_Nodes * Get_Infinite_Nodes();
00281   void Reset_Infinite_Nodes();
00282   void Embed_CSource(); 
00283 
00284 };
00285 
00286 CCDGNodeList * Add_Node(CCDGNodeList * recent_nodes, char * start, bool before);
00287 
00288 
00290 class CCDGNode {
00291 public:
00292   std::string* Pre_Comments;
00293   std::string* Post_Comments;
00294 
00304   void Calculate_Segment_Times();
00305 
00306 private:
00308   bool SegTimeVisited; 
00309 
00313   CTimeRange StartTimeFromSegmentStart;
00314 
00318   CTimeRange EndTimeFromSegmentStart;
00319 
00320 
00322 
00323 
00324 protected:
00326   char Name[STR_SIZE];
00328   CStringList * Aliases; 
00330   int HorG;
00332   CTimeRange Duration;
00334   CTimeRange Start, End;
00335 
00336 
00337 
00338 
00340   CLabelCell * Label;
00342   bool RT;
00344   long TargetTime;
00346   NODE_TYPE Type;
00348   INT_OVHD_TYPE IntOvhdType;
00350   int SerNum;
00352   CCDGNode * Parent;
00354   CProc * Procedure;
00356   CCDGNodeList * Children;
00358   bool Visited;
00360   bool DFS_Visited;
00362   int HorPos;
00364   CRegAccess RegDef, RegUse;
00366   CDir * PrecedingDirs, * FollowingDirs;
00368   CCDGNode * Copy;
00370   int Size;
00372   int SubgraphSize;
00374   vector<string> CSourceLines; 
00375  public:
00376   CCDGNode();
00377   virtual ~CCDGNode() {};
00378   CCDGNode(CCDGNode &orig, CCDGNode &parent);
00379   CCDGNode * Copy_Derived(CCDGNode &parent);
00380   //    CCDGNode * Copy_w_Derived_Info();
00381   
00382   CCDGNode(char * name);
00383   bool Check(void);
00384   void Add_Aliases(CLabelList * alias_list);
00385   CStringList * Get_Aliases() { return Aliases; };
00386   void PreTraverse_C_C(char * (*func) (char *, const char *), 
00387                const char * char_arg);  
00388   void TraverseMethod_V_N(void (*func) (CCDGNode *), bool pre);
00389   void TraverseMethod_V_N_N(void (*func) (CCDGNode *, CCDGNode *), 
00390                 CCDGNode * node_arg, bool pre);
00391   
00392   void Set_Name(char * name) { 
00393     assert(strlen(name)<STR_SIZE); 
00394     strcpy(Name, name); 
00395   };
00396   char * Get_Name() { return Name; };
00397   char * Get_Type_String() {
00398     return NodeType_Names[(this && Type)? Type : UNINIT];
00399   }; 
00400   void Print_Name_And_Type(ostream  &s) {
00401     if (this)
00402       s << Get_Name() << " " << Get_Type_String() << " "
00403     << (int) this << " ";
00404     else
00405       s << "Null Pointer ";
00406   };
00407   void Append_Suffix_To_Name(char * str);
00408   void Append_Suffix_To_Name_For_Subgraph(const char * str);
00409   void Append_Numbered_Suffix_To_Name(char * str, int n);
00410   
00411   void Find_Blocking_IO_Loops();
00412   // This function identifies each blocking I/O loops in the subgraph rooted
00413   // by this node and sets its IsBlockingIOLoop flag.
00414 
00415   void Fix_Branch_Targets();
00416   void Fix_Short_Branches();
00417 
00418   void Label_Node(float * next_section);
00419   void Label_This_Node(CCDGNode * prev_node);
00420   void Append_LabelCell(TRUTH_VALUE_TYPE tv, float section, float section_end);
00421   void Set_Label(char * label) { Label = new CLabelCell(label); };
00422   CLabelCell * Get_Label() { return Label; };
00423   
00424   int Get_Size() { // Return size of node in bytes
00425     //    Set_Size(); // always have a fresh version of Size
00426     return Size; 
00427   };
00428   int Get_SubgraphSize() { // Return size of subgraph rooted by this node in bytes
00429     Set_Size(); // Always have a fresh version.  This also sets SubgraphSize.
00430     return SubgraphSize;
00431   }
00432   virtual void Set_Size(void);  // function to calculate node size, is
00433   // overridden by derived classes.
00434 
00435   void Set_Size(int s) { Size = s; };
00436   
00437   CCDGNode * Get_Parent() { return Parent; };
00438   void Set_Parent(CCDGNode * parent) { Parent = parent; }; 
00439   
00440   void Add_Child(CCDGNode * child, TRUTH_VALUE_TYPE tv, int hg_select=INVALID);
00441   void Add_Children(CCDGNodeList * children, TRUTH_VALUE_TYPE tv, int hg_select=INVALID);
00442   void Add_Child(char * name, NODE_TYPE type, TRUTH_VALUE_TYPE tv);
00443   CCDGNode * Clone_Child(CCDGNode * orig_child, CCDGNode * ref, POS_TYPE pos, 
00444              TRUTH_VALUE_TYPE tv=TV_A);
00445   bool Insert_Child(CCDGNode * new_child, CCDGNode * ref, bool before);
00446   void Insert_Children(CCDGNodeList * new_children, CCDGNode * ref, bool before);
00447   void Insert_Padding_Children(char * name_base, long cycles, TRUTH_VALUE_TYPE side, 
00448                    bool delay_loop_ok);
00449 
00450   CCDGNodeList * Get_Children() { return Children; }
00451   CCDGNodeList * Get_First_Child(TRUTH_VALUE_TYPE tv=TV_ANY);
00452   CCDGNodeList * Get_Last_Child(TRUTH_VALUE_TYPE tv=TV_ANY, 
00453                 int hg_sel=INVALID);
00454   bool Remove_Child(CCDGNode * victim);
00455   bool Move_Child(CCDGNode * mover, bool to_end);
00456   //    CCDGNodeList * Get_Last_Child();
00457   void Find_Children(CCDGNodeList * n);
00458   bool Copy_And_Integrate_Subgraph(int target_time, CCDGNodeList * new_code,
00459                    int seg_num);
00460 
00461   CCDGNode * Find_Common_Ancestor(CCDGNode * n);
00462   bool Has_Ancestor(CCDGNode * n);
00463   TRUTH_VALUE_TYPE Find_Childs_TV(CCDGNode * n);
00464   void Pr_Children(); 
00465   int Get_Num_Children(TRUTH_VALUE_TYPE tv); // This function returns the 
00466   // number of children of a given truth value for this node. Use TV_ANY
00467   // to count the total number of children.
00468   CCDGNode * Get_Older_Sibling(bool in_same_loop=FALSE);
00469   CCDGNode * Get_Younger_Sibling(bool same_parent=FALSE);
00470   CCDGNode * Get_Older_Sibling(bool same_parent, int h_or_g, bool RT);
00471   CCDGNode * Get_Sibling_At(CTimeRange * t);
00472   CLoop * Get_Enclosing_Loop();
00473   bool Reaches(CCDGNode * that);
00474   bool Dominates(CCDGNode * that);
00475 
00476   TRUTH_VALUE_TYPE Find_TV() { return Get_Parent()->Find_Childs_TV(this); };
00477 
00478   CProc * Get_Procedure() { return Procedure; };
00479   void Set_Procedure(CProc * p);
00480   void Set_Procedure_For_Subgraph(CProc * p);
00481 
00482   int Get_SerNum() { return SerNum; };
00483   CTimeRange * Get_Start() { return &Start; };
00484   CTimeRange * Get_End() { 
00485     assert (Duration.Get_Worst() != INVALID);
00486     assert (Duration.Get_Worst() != UNKNOWN);
00487     End = Start + Duration; 
00488     --End; 
00489     return &End; 
00490   };
00491   CCDGNode * Split(long when);
00492   void Set_Start(CTimeRange tr) { Start = tr; };
00493   
00494   void Set_TargetTime(long cy) { TargetTime = cy; };
00495   long Get_TargetTime() { return TargetTime; };
00496     
00497   CTimeRange * Get_Duration(bool include_unknown_loop_iter=FALSE) {
00498      return &Duration; 
00499   }
00500      
00501   void Mark_as_Host() { HorG = HOST; };
00502   void Mark_as_Guest() { HorG = GUEST; };
00503   void Mark_Subgraph_as_Guest();
00504   void Mark_HorG(int which) { HorG = which; };
00505   int Get_HorG() { return HorG; };
00506   bool Is_Host() { return (HorG == HOST); };
00507   bool Is_Guest() { return (HorG == GUEST); };
00508   bool Is_Program_Halt();
00509 
00510   void Mark_as_RT() { RT = TRUE; };
00511   void Mark_as_NRT() { RT = FALSE; };
00512   bool Get_RT() { return RT; };
00513   bool Is_RT() { return (RT == TRUE); };
00514   bool Is_NRT() { return (RT == FALSE); };
00515 
00516   bool Ends_In_Uncond_Branch(); // returns true if this node is a CCode
00517   // which ends in an unconditional branch
00518     
00519   CDir * Get_PrecedingDirs() { return PrecedingDirs; };
00520   CDir * Get_FollowingDirs() { return FollowingDirs; };
00521     
00522   void Add_PrecedingDir(char * text);
00523   void Add_FollowingDir(char * text);
00524   
00525   void Add_PrecedingDir(CDir *Directive);
00526   void Add_FollowingDir(CDir *Directive);
00527   
00528   INT_OVHD_TYPE Get_IntOvhdType() { return IntOvhdType; };
00529   void Set_IntOvhdType(INT_OVHD_TYPE ov) { IntOvhdType = ov; };
00530   void Mark_If_Discrete_Guest();
00531   
00532   void Gen_Graph(ofstream &ostream, int level);
00533   
00534   void Output_Debug(ostream &stream, bool do_full=TRUE);
00535   void Output_Code(ostream &stream);
00536   void Output_VCG(ostream &stream);
00537   
00538   void Pr_Info();
00539   void Pr_Name(bool t);
00540   
00541   NODE_TYPE Get_Type() { return Type;}
00542   void Set_Type(NODE_TYPE type) { Type = type; }
00543   void Pr_Type();
00544   
00545   void Set_Visited(bool v) { Visited = v; };
00546   bool Get_Visited() { return Visited; };
00547   
00548   bool Is_DFS_Visited() { return DFS_Visited; };
00549   void Set_DFS_Visited() { DFS_Visited = true; }
00550 
00551   void Set_HorPos(int hp) { HorPos = hp; };
00552   int Get_HorPos() { return HorPos; };
00553   
00554   void Calculate_Node_Duration(bool include_guests=TRUE);
00555 
00561   void Calculate_Node_Start(CTimeRange * par_start, bool include_guests=TRUE);
00562   
00563   void Find_Hosts(CTimeRange * Target, CGuestInfo * RII);
00564   void Delete_Following_Guests();
00565   void Delete_This_And_Following_Guests( void );
00566   CLoop * Find_First_Loop(long t_start, long t_stop);
00567   
00568   void Summarize_Register_DefUse_Info();
00569   void Find_Vars();
00570   bool Always_Defined(int reg);
00571   CRegAccess * Get_RegDef() { 
00572     //      assert(!registers_virtualized); 
00573     return &RegDef; 
00574   }
00575   CRegAccess * Get_RegUse() {
00576     //    assert(!registers_virtualized); 
00577     return &RegUse; 
00578   }
00579   CVar * Find_Prev_Ref(int reg,  CInstr * instr, bool local_instr, 
00580                bool look_across_loop_back, bool skip_this_node);
00581   void Analyze_Instruction(CInstr * instr);
00582   
00583   int Get_NumInstrs();
00584   long Pad(long padding_needed);
00585   void Set_Node_Jump_Target(char * target);
00586   void Insert_Padding(char * name_base, long cycles, bool pad_before, 
00587               bool delay_loop_ok);
00588   CCDGNodeList * Create_Padding_Nodes(char * name, long amount);
00589   CCDGNode * Get_Copy() { return Copy; };
00590   CCDGNode * Get_Copy(CCDGNode * parent);
00591   CCDGNode * Get_Last_Copy();
00592   CCDGNodeList * Guard(int reg, int bit, bool skip_if_set, int cond_br_type);
00593   CCDGNode * Find_FSM_Loop();  // look for an infinite loop holding an FSM
00594 
00595   void Debug_Final_Step(int n,CCDGNode * parent, TRUTH_VALUE_TYPE tv);
00596 
00602   CCDGNode * Get_Sibling_Before(CCDGNode * node, bool before);
00603 
00604   void Embed_CSource(); 
00605 
00606 };
00607 
00608 extern void Find_Blocking_IO_Loop(CCDGNode * n);
00609 extern CCDGNode * Create_Padding_Node(char * name, long amount);
00610 
00611 extern CCDGNode * Create_Derived_CDGNode(NODE_TYPE type, char * name);
00612 
00613 class CSegmentList;
00614 class CPred;
00615 class CCall;
00616 
00620 class CCode : public CCDGNode {
00622   CInstr * Instr;
00624   int NumInstrs;
00627   CCode * Pred[MAX_PREDECESSORS], * Succ[MAX_SUCCESSORS];
00629   CCDGNodeList * node_list;
00631   bool Infinite_Block;
00633   bool Visited;
00634 public:
00635   CCode() : CCDGNode() {
00636     this->Set_Type(CODE); 
00637     Instr = NULL;
00638     NumInstrs = 0;
00639     for (int i=0; i<MAX_PREDECESSORS; i++)
00640       Pred[i] = NULL;
00641     for (int i=0; i<MAX_SUCCESSORS; i++)
00642       Succ[i] = NULL;
00643     Infinite_Block=true;
00644     Visited=false;
00645   };
00646   CCode(char * name) : CCDGNode(name) { 
00647     this->Set_Type(CODE); 
00648     Instr = NULL;
00649     NumInstrs = 0;
00650     if (trace_const)
00651       cout << " Code ";
00652     for (int i=0; i<MAX_PREDECESSORS; i++)
00653       Pred[i] = NULL;
00654     for (int i=0; i<MAX_SUCCESSORS; i++)
00655       Succ[i] = NULL;
00656     Infinite_Block=true;
00657     Visited=false;
00658   };
00659   CCode(const CCode & orig, CCDGNode &Parent);
00660   ~CCode();
00661   
00662   // instruction manipulation
00663   void Add_Instr_Frag(char * instr_frag);
00664   void Add_Instr(CInstr * instr);
00665   CInstr * Get_Instr() { return Instr; };
00666   void Set_Instr(CInstr * instr) { Instr = instr; };
00667   CInstr * Get_Last_Instr() { return Instr ? Instr->Get_Last() : NULL; };
00668   int Get_NumInstrs() { return NumInstrs; };
00669   void Set_NumInstrs();
00670   void Set_NumInstrs(int n) { NumInstrs = n; };
00671   void Inc_NumInstrs() { 
00672     NumInstrs++; 
00673     ((CCDGNode *)this)->Calculate_Node_Duration(); 
00674   };
00675   CVar * Find_Prev_Ref(int reg,  CInstr * instr, bool local_instr, 
00676                bool look_across_loop_back);
00677   void Prepend_Instr(CInstr * instr) {
00678     assert (instr);
00679     Instr->Set_Prev(instr);
00680     instr->Set_Next(Instr);
00681     Instr = instr;
00682     if (!Instr->Is_Pseudo())
00683       NumInstrs++;
00684     instr->Set_Node((CCDGNode *)this);
00685     // do def-use?
00686   };
00687 
00688   void Make_Jump_Node(char * target, char * node_name_root);
00689   CCDGNode * Split(long when, bool when_is_offset=false);
00690   CCode * Split_After_Byte(int where);
00691   CPred * Split_Off_Cond_Branch();
00692   CCode * Split_Off_Uncond_Branch();
00693   bool Contains_Call( void );
00694   CCall * Split_Off_Call( void );
00695   void Set_Size(void);
00696   CTimeRange * Get_Duration(bool include_unknown_loop_iter) ;
00697   void Output_Code(ostream &stream);
00698   void Output_VCG(ostream &stream);
00699   void Make_Loop_Control_Var_Fuser(CLoop * guest_loop, CLoop * host_loop);
00700   
00701   CCode * Get_Next_Pred(CCode * cur);
00702   CCode * Get_Next_Succ(CCode * cur);
00703   CCode * Get_Next_Succ(CCode * cur, bool value);
00704   
00705   bool Add_Pred(CCode * p); 
00706   bool Add_Succ(CCode * p); 
00707   void Clear_Pred_Succ();
00708   void Set_Is_Infinite_Block()
00709     {   Infinite_Block=true;
00710     }
00711   void Reset_Is_Infinite_Block()
00712     {   Infinite_Block=false;
00713     }
00714   bool Is_Infinite_Block()
00715     {   return Infinite_Block;
00716     }
00717   void Set_Visited()
00718     {   Visited=true;
00719     }
00720   void Reset_Visited()
00721     {   Visited=false;
00722     }
00723   bool Is_Visited()
00724     {   return Visited;
00725     }
00726   bool Is_Succ_Empty();
00727 
00731   bool Is_Succ_Present(CCode *node);
00732 
00733   void Set_Node_List(CCDGNodeList *p_node_list)
00734     {   node_list=p_node_list;
00735     }
00736   CCDGNodeList *Get_Node_List()
00737     {   return node_list;
00738     }
00739   bool Has_2_Succ()
00740     {   CCode * next1 , * next2;
00741     next1 = Get_Next_Succ(NULL);
00742     if(next1)
00743       next2 = Get_Next_Succ(next1);
00744     if(next1 && next2)
00745       return true;
00746     return false;
00747     };
00748   bool Has_Succ(CCode * node)
00749     {   CCode * next=NULL;
00750     while((next=Get_Next_Succ(next))!=NULL)
00751       if(next==node)
00752     return true;
00753     return false;
00754     };
00755 
00762   void DFS_Search(bool is_start);
00763   void Mark_Infinite_Blocks();
00764 };
00765 
00766 class CPred : public CCDGNode {
00768   CInstr * Branch;
00770   int ClosesLoop;
00772   long TruncDuration;
00774   int NumPadNodes;
00775 public:
00776   CPred() : CCDGNode() {
00777     Branch = NULL;
00778     ClosesLoop = 0;
00779     TruncDuration = INVALID;
00780     NumPadNodes = 0;
00781   };
00782     CPred(char * name) : CCDGNode(name) { 
00783         this->Set_Type(PRED); 
00784         //      Branch[0] = '\0'; 
00785         Branch = new CInstr;
00786         ClosesLoop = 0;
00787         NumPadNodes = 0;
00788         if (trace_const)
00789             cout << " CPred ";
00790     };
00791     CPred(const CPred &orig, CCDGNode &parent);
00792     ~CPred();
00793 
00794     void Set_Size(void);
00795     int Get_Child_Subgraph_Size(TRUTH_VALUE_TYPE tv);
00796     void Set_Branch(char * branch);
00797     void Set_Branch(CInstr * branch) { 
00798       Branch = branch; 
00799       Branch->Set_Node(this);
00800       if (branch->Get_IS_Index() != INVALID_UC)
00801         Set_Size();
00802     };
00803     CInstr * Get_Branch() { return Branch; };
00804     void Set_ClosesLoop(int closes_loop) { ClosesLoop = closes_loop; };
00805     int Get_ClosesLoop() { return ClosesLoop; };
00806     void Add_Loop_To_Close(CCDGNode * child, TRUTH_VALUE_TYPE tv);
00807 
00808     void Extend_Segment(CSegmentList * seg, long max_jitter);
00809     void Set_TruncDuration(long t) { TruncDuration = t; };
00810     long Get_TruncDuration() { return TruncDuration; };
00811 
00812     CTimeRange Get_Duration(TRUTH_VALUE_TYPE tv);
00813     CTimeRange * Get_Duration() { return ((CCDGNode *) this)->Get_Duration(); };
00814     void Calculate_Node_Duration(bool include_guests=TRUE);
00815     CTimeRange Calculate_Node_Duration(TRUTH_VALUE_TYPE tv, 
00816                        bool include_guests=TRUE);
00817 
00818     CVar * Find_Prev_Ref(int reg,  CInstr * instr, bool local_instr, 
00819                  bool look_across_loop_back);
00820     long Pad(long padding_needed);
00821     void Pad(long padding_needed, TRUTH_VALUE_TYPE tv);
00822     int Get_New_Pad_Number();
00823 
00824     void Output_Code(ostream &stream);
00825     // Generate code for this CPred, including all children.
00826     void Output_Child_Code(ostream &stream, TRUTH_VALUE_TYPE tv, CCDGNode * start);
00827     // Generate code for all children of this CPred with a truth value of tv beginning
00828     // with node TV. Does NOT print out the CPred branch instruction.
00829     void Output_VCG(ostream &stream);
00830 };
00831 
00833 class CMultiPred : public CCDGNode {
00835   char Branch[STR_SIZE];
00837   int ClosesLoop;
00838  public:
00839   CMultiPred(char * name) : CCDGNode(name) { 
00840     this->Set_Type(MULTIPRED); 
00841     Branch[0] = '\0'; 
00842     ClosesLoop = 0;
00843     if (trace_const)
00844       cout << " Pred ";
00845   };
00846   ~CMultiPred();
00847     void Set_Size(void);
00848   void Set_Branch(char * branch) { 
00849     assert (strlen(branch) < STR_SIZE);
00850     strcpy(Branch, branch); 
00851   };
00852   char * Get_Branch() { return Branch; };
00853   void Set_ClosesLoop(int closes_loop) { ClosesLoop = closes_loop; };
00854   int Get_ClosesLoop() { return ClosesLoop; };
00855 };
00856 
00857 class CLTXList;
00858 class CHostInfo;
00860 class CLoop : public CCDGNode {
00862   int IterCount; 
00864   CTimeRange IterPeriod; 
00867   CInstr * LCB; 
00869   CVar * InductionVar;
00872   CInstr * CompareInstr;
00874   CLTXList * Transforms;
00876   bool IsBlockingIOLoop;
00878   int LIV_InitialValue;
00880   int LIV_Delta;
00882   int LIV_FinalValue;
00883 public:
00884   CLoop() : CCDGNode() {
00885     IterCount = INVALID;
00886     InductionVar = NULL;
00887     CompareInstr = NULL;
00888     Transforms = NULL;
00889     LCB = NULL;
00890     IsBlockingIOLoop = false;
00891     LIV_InitialValue = LIV_Delta = LIV_FinalValue = 0;
00892   }
00893   CLoop(char * name) : CCDGNode(name) { 
00894     if (trace_const)
00895       cout << " CLoop "; 
00896     this->Set_Type(LOOP); 
00897     IterCount = INVALID;
00898     CompareInstr = NULL;
00899     Transforms = NULL;
00900     LCB = NULL;
00901     IsBlockingIOLoop = false;
00902   }
00903   CLoop(const CLoop & orig, CCDGNode &parent);
00904   ~CLoop();
00905   CLoop * Copy_Only_Node(void);
00906   void Adopt_Children(CCDGNode * first, CCDGNode * last);
00907   void Set_Size(void);
00908 
00909   bool Iteration_Info_Valid();
00910   CTimeRange * Get_Duration(bool include_unknown_loop_iter=FALSE) {
00911     return &Duration;
00912   }
00913   
00914   void Set_IterCount(int count) { IterCount = count; };
00915   int Get_IterCount() { return IterCount; };
00916   void Set_Iterations(int count);
00917   CTimeRange * Get_IterPeriod() { return &IterPeriod; };
00918   int Get_IterPeriod_w_LCB(void) { 
00919     if (!LCB) 
00920       Get_LCB(); // initialize it!
00921     return IterPeriod.Get_Worst() - LCB->Get_Duration()->Get_Worst(); 
00922   };
00923   void Extend_Segment(CSegmentList * seg, long max_jitter);
00924   void Gen_Jitter_Plot(ofstream & plot_stream);
00925   CVar * Find_Prev_Ref(int reg,  CInstr * instr, bool local_instr, bool look_across_loop_back);
00926 
00927   void Find_Control_Info();
00928   void Print_Control_Info(ostream & stream);
00929   CInstr * Get_CompareInstr(void) { return CompareInstr; };
00930   CInstr * Get_LCB(void);
00931   CPred * Get_LoopClosingPredicate(void);
00932   void Calculate_Node_Duration(bool include_guests=true);
00933   void Find_Hosts(CTimeRange * Target, CGuestInfo * RII);
00934   
00935   CLTXList * Get_Transforms() { return Transforms; };
00936   void Add_Transform(CHostInfo * ltx);
00937   void Update_Remaining_Transformations(CHostInfo * cur_ltx, 
00938                     CCDGNode * new_loop);
00939   
00940   long Pad(long padding_needed);
00941   void Peel_Iteration(POS_TYPE pos);
00942   CLoop * Split(int iteration);
00943   void Make_Guarded(CInstr * guard_instr, bool invert);
00944   CLoop * Make_Guarded_Copy( void );
00945   void Fuse_Loop_Control(CLoop * guest_loop);
00946   void Output_Code(ostream &stream);
00947   
00948   bool Get_IsBlockingIOLoop();
00949   void Set_IsBlockingIOLoop(bool b);
00950 
00951   bool Copy_And_Integrate_Subgraph(int t, CCDGNodeList * new_code, int seg_num);
00952 };
00953 
00955 class CIrrLoop : public CCDGNode {
00956   int IterCount;
00957   int InductionVar;
00958  public:
00959   CIrrLoop(char * name) : CCDGNode(name) { 
00960     if (trace_const)
00961       cout << " CIrrLoop "; 
00962     this->Set_Type(IRRLOOP); 
00963     IterCount = -1;
00964   }
00965   ~CIrrLoop();
00966   void Set_Size(void);
00967   void Set_IterCount(int count) { IterCount = count; };
00968   int Get_IterCount() { return IterCount; };
00969 };
00970 
00971 // class CVar;
00973 class CProc : public CCDGNode {
00975   CSegmentList * Segments;
00978   CCDGNodeList * Nodes; 
00980   int NumInstrs;
00982   CVar HostVars, GuestVars;
00984   CRegAccess HostRegs, GuestRegs;
00986   long BestCaseAdjust;
00988   int FrameSize;
00990   THREAD_TYPE ThreadType;    
00992   PROC_TYPE ProcedureType; 
00994   bool BranchesStale;  
00996   bool STAStale;
00998   bool DFAStale;         
01000   bool LabelsStale;      
01002   bool Integrating;      
01003  
01004  public:
01005   CProc(char * name);
01006   ~CProc();
01007   void Gen_Jitter_Plot(char * filename);
01008   void Gen_Segment_Plot(char * filename);
01009   void Gen_Graph(char * filename);
01010   void Pad_Jitter(bool pad_host, bool pad_guest);
01011   void Set_Size(void);
01012 
01013   bool Get_BranchesStale(void);  
01014   bool Get_STAStale(void);       
01015   bool Get_DFAStale(void);       
01016   bool Get_LabelsStale(void);    
01017 
01018   void Set_BranchesStale(bool val);  
01019   void Set_STAStale(bool val);       
01020   void Set_DFAStale(bool val);       
01021   void Set_LabelsStale(bool val);    
01022   void Set_Integrating(bool val);
01023   bool Get_Integrating();
01024 
01025 
01026   CRegAccess * Get_Regs(int which) {
01027     switch (which) {
01028     case HOST: 
01029       return &HostRegs; break;
01030     case GUEST: 
01031       return &GuestRegs; break;
01032     default: 
01033             assert(0);
01034     };
01035     return NULL;
01036   };
01037   
01038   void Create_Var_File();
01039   CVar * Get_Vars(int which) { 
01040     switch (which) {
01041     case HOST: 
01042       return &HostVars; 
01043       break;
01044     case GUEST: 
01045       return &GuestVars; 
01046       break;
01047     default: 
01048       assert(0);
01049       break;
01050     };
01051     return NULL;
01052   };
01053   int Count_Vars(int which);
01054   void Print_Interference_Matrix(int which);
01055   //    int Count_Regs(int which, bool include_system);
01056   void Label_Procedure(void);
01057   void Find_Segments(long max_jitter);
01058   CSegmentList * Get_Segments() { return Segments; };
01059   void Set_Nodes(CCDGNodeList * n) { Nodes = n; };
01060   CCDGNodeList * Get_Nodes() { return Nodes; }; // List of Nodes in the procedure
01061   CLoop * Get_Next_Loop(CLoop * prev_loop, int h_or_g);
01062   
01063   void Set_NumInstrs(int n) { NumInstrs = n; };
01064   int Get_NumInstrs() { return NumInstrs; };
01065   
01066   void Do_STA(bool include_guest=TRUE);
01067   void Set_BestCaseAdjust(long t) { BestCaseAdjust = t; };
01068   void Add_To_BestCaseAdjust(long t) { BestCaseAdjust += t; };
01069   long Get_BestCaseAdjust() { 
01070     // HACK - watch out for rescheduling
01071     if (resched_often) 
01072       return 0; 
01073     else 
01074       return BestCaseAdjust; 
01075   };
01076   
01077   void QND_Save_Callee_Saved_Regs();
01078   void QND_Restore_Callee_Saved_Regs();
01079   void Set_FrameSize(int s) { FrameSize = s; };
01080   int  Get_FrameSize(void) { return FrameSize; };
01081   THREAD_TYPE Get_ThreadType(){ return ThreadType; }
01082   PROC_TYPE  Get_ProcedureType(){ return ProcedureType; }
01083   void Set_ThreadType(THREAD_TYPE type){ ThreadType = type; } 
01084   void Set_ProcedureType(PROC_TYPE type){ ProcedureType = type; }
01085   void Find_Interference(int which);
01086   void Reallocate_Regs_AVR_QND();
01087   void Reallocate_Regs_Alpha_QND();
01088   void Color_Registers();
01089   //    int Reassign_Var(CVar * fresh, CVar * stale);
01090   void Output_Code(ostream &stream);
01091   void Output_Code(char * fname);
01092   void Pad_Blocking_Loops_To_CoCallPeriod(long cocall_period, 
01093                        bool look_for_unique_loop, 
01094                        char* loop_name_passed);
01095 };
01096 
01100 class CCall : public CCDGNode {
01102   CInstr * Branch;
01103 
01105   CVar* DefVar[MAX_REG+1]; 
01106 
01108   CVar* UseVar[MAX_REG+1];
01109 
01110  public:
01111   CCall(char * name);
01112   ~CCall();
01113 
01114 
01121   CCall(CCode * code);
01122 
01123   void Set_Size(void);
01124     
01125   void Set_Branch(char * branch);
01126   void Set_Branch(CInstr * branch) { Branch = branch; Branch->Set_Node(this); };
01127   CInstr * Get_Branch() { return Branch; }
01128   CVar * Find_Prev_Ref(int reg,  CInstr * instr, bool local_instr, 
01129                bool look_across_loop_back);
01130   CVar * Find_DefVar(int reg) {
01131     for (int i = 0; i <= MAX_REG; i++)
01132       if (DefVar[i] && (DefVar[i]->Get_RegNumber() == reg))
01133         return DefVar[i];
01134     return NULL;
01135   }
01136   void Add_DefVar(CVar * var) {
01137     for (int i = 0; i <= MAX_REG; i++)
01138       if (DefVar[i] == NULL) {
01139     DefVar[i] = var;
01140     return;
01141       }
01142     // error, too many vars to fit in set
01143     assert(0);
01144   }
01145   
01146   CVar * Find_UseVar(int reg) {
01147     for (int i = 0; i <= MAX_REG; i++)
01148       if (UseVar[i] && (UseVar[i]->Get_RegNumber() == reg))
01149         return UseVar[i];
01150     return NULL;
01151   }
01152   void Add_UseVar(CVar * var) {
01153     for (int i = 0; i <= MAX_REG; i++)
01154       if (UseVar[i] == NULL) {
01155     UseVar[i] = var;
01156     return;
01157       }
01158     // error, too many vars to fit in set
01159     assert(0);
01160   }
01161   void Output_Code(ostream &stream);
01162   void Output_VCG(ostream &stream); 
01163 };
01164 
01165 
01166 CCDGNodeList * Parse_File(char * filename);
01167 CCDGNodeList * Build_CDGs(CCDGNodeList * nodes);
01168 
01169 extern char NodeType_Names[][10];
01170 
01171 #endif // NODES_H
01172 
01173 

Generated on Sat May 8 14:08:33 2004 for Thrint by doxygen 1.3.6