00001 #include "misc.h"
00002 #include "timerange.h"
00003
00004
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
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
00243
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
00256
00257
00258
00259
00260 void Build_CFG_VCG(int i);
00261 void Build_CFG_VCG(int i, bool f);
00262
00263
00264
00265
00266
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
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
00413
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() {
00425
00426 return Size;
00427 };
00428 int Get_SubgraphSize() {
00429 Set_Size();
00430 return SubgraphSize;
00431 }
00432 virtual void Set_Size(void);
00433
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
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);
00466
00467
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();
00517
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
00573 return &RegDef;
00574 }
00575 CRegAccess * Get_RegUse() {
00576
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();
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
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
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
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
00826 void Output_Child_Code(ostream &stream, TRUTH_VALUE_TYPE tv, CCDGNode * start);
00827
00828
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();
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
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
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; };
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
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
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
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
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