Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

op_scheduler.H

Go to the documentation of this file.
00001 //
00002 // File:
00003 //
00004 //      op_scheduler.H
00005 //
00006 // Purpose:
00007 //
00008 //      Defines class structure for an implementation of
00009 //      operation scheduling. 
00010 //
00011 // Author:
00012 //
00013 //      Mark C. Toburen
00014 //
00015 // History:
00016 //
00017 //      02/15/02 - Created.
00018 //
00019 
00020 #ifndef _OP_SCHEDULER_H_
00021 #define _OP_SCHEDULER_H_
00022 
00023 #include <stl.h>
00024 #include "TinkerKnobs.H"
00025 #include "dag.H"
00026 #include "machine.h"
00027 #include "chains.H"
00028 #include "opList.H"
00029 #include "rdef.H"
00030 
00031 #define UNSCHEDULED            -1 // Marks an Op as unscheduled
00032 #define RENAMING_CONFLICT       1 // Marks Ops that can't be renamed
00033 #define NO_RENAMING_CONFLICT    0 // Marks Ops that can be renamed
00034 
00035 class op_scheduler {
00036 
00037 protected:
00038 
00039    // Pointers, etc to hold the prioritized op list of the current region being scheduled
00040    typedef vector <BigListElement>::iterator ListIterator;
00041    vector <BigListElement> *List;
00042    ListIterator ListHead, ListTail, ListPtr, Op;
00043    int ListCount;
00044 
00045    // Miscellaneous global variables used during scheduling
00046    int *operand_ready_times, current_block_int;
00047    legoOp *current_before_op;
00048    regionList *Children;
00049    vector <legoRegion *> ScheduleList;
00050    map <int, int> ScheduleTimes;
00051 
00052    // Pointers to the current region being scheduled, its DDG, the Machine model, and knobs
00053    legoRegion *Region;
00054    dag *DDG;
00055    machine *Machine;
00056    knobs *Knobs;
00057 
00058    // OpSched Knobs
00059    char *TreeTraversal;
00060    int PlayDoh,
00061        BypassLatency,
00062        CodeGen,
00063        NoSpeculation,
00064        AllowPBRSpeculation,
00065        AllowLoadSpeculation,
00066        AllowOnlySafeSpeculation,
00067        AllowDownwardCodeMotion,
00068        AllowMultiWayBR;
00069 
00070    // *********************************************************************************************
00071    // Renaming Functions
00072    //    - taken from list scheduler
00073    // *********************************************************************************************
00074 
00075    // HZ: Rename the dst reg of the op.
00076    // Based on the following conditions to decide which renaming scheme will be
00077    // used: 
00078    //      whether there are any uses of the dsts of the op that are outside
00079    //      of treegion, or there are any uses that are not descedant of the
00080    //      BB where the op resides in. => variable UseOutsideTreeOrNotDom
00081    // If UseOutsideTreeOrNotDom is false, the SimpleRename is used.
00082    // If UseOutsideTreeOrNotDom is true, more conditions need to be checked to
00083    // determine either SimpleRenameWithCopy or GlobalRename to be used:
00084    //     -Check whether Merge problem exists. If not, the global rename is
00085    //      used. 
00086    //     -If there is Merge Problem, add a copy op if the op
00087    //      has at least one use that it dominates and there is no use preceeds
00088    //      the op.
00089    //     -Otherwise, return RENAMING_CONFLICT.
00090    // For the input Hazardous, if set, the Merge problem is assumed to exist. So
00091    // the SimpleRenameWithCopy is favored. 
00092    //
00093    // Doubtful point: (future work on DDG & scheduler) DDG analysis of FICT
00094    int Rename(legoOp *op, int RegNum, legoRegion *proc_ptr, int Final_Pass,
00095               int IncMaxRegNum, int Hazardous);
00096 
00097    // HZ: Simple rename of the dsts of the op
00098    // If IncMaxRegNum == 1, rename the dsts of the op starting from reg no (++MaxRegNum)
00099    // If IncMaxRegNum == 0, rename the dsts of the op starting from RegNum.
00100    // Simple rename works by setting just the reg no of the dsts of the op and
00101    // update the DAG by remove the Output and Anti(def) dep.
00102    void SimpleRename(legoOp *op, int RegNum, int IncMaxRegNum);
00103 
00104    // HZ: Rename the uses of the def.
00105    // For each use of the def (obtained by GetDUChain), set the oprdRegNum to
00106    // RegNum , also call the function ReverseGlobalRename(use, RegNum, orig_def)
00107    // to rename the defs of the use.
00108    void ForwardGlobalRename(legoOprd *def, int RegNum, legoOprd *orig_def);
00109    
00110    // HZ: Rename the defs of the use
00111    // For each def of the use (obtained by GetUDChain), set the oprdRegNum to
00112    // RegNum, also call the function ForwardGlobalRename(def, RegNum, orig_def)
00113    // to rename the uses of the def.
00114    //
00115    // Doubtful point: the setting of the ReDoLiveVarsAfterGlobal
00116    void ReverseGlobalRename(legoOprd *use, int RegNum, legoOprd *orig_def);   
00117       
00118    // HZ: Rename the dsts of the op.
00119    // If IncMaxRegNum == 1, rename the dsts of the op starting from reg no (++MaxRegNum)
00120    // If IncMaxRegNum == 0, rename the dsts of the op starting from RegNum.
00121    // For each dst of the op, after change the reg no, call
00122    // ForwardGlobalRename(def, localRegNum, def) to rename the reg no globally
00123    // Then remove the output deps on its predecessors and the antidep based on
00124    // the renamed def.
00125    void GlobalRename(legoOp *op, int RegNum, int IncMaxRegNum);
00126 
00127    // HZ: AddCopyOps: add the copy (move) ops of the op.
00128    // There are two scenarios considered in this function:
00129    // (1) If the op is scheduled, we are dealing with the dominate parallelism
00130    //   (Doubtful point for me at this time)
00131    // (2) If the op is unscheduled, we are doing the first step of
00132    //    renamewithcopy.
00133    // For each dst reg of the op, a copy (move) inst is created with the
00134    //  consideration of the predicate register.(e.g., mov r1,
00135    //  r1 (p1) ). Then the related DU, UD chains, and the copy ops are appended
00136    //  at the end of the List. Also the predecessor & successor
00137    //  dependency relationships in DAG are updated. 
00138    int AddCopyOps(legoOp *op);
00139 
00140    // HZ: Return true if orig_def is descendant of the BB that the def resides in.
00141    // This happens when a use has two reaching defs. In the renaming process,
00142    // just rename one of them is not enough. Matt called this 'Merge Problem' as
00143    // two defs merge at the same use.
00144    // Because of the nature of treegion, this mergeing use should not be in the
00145    // same treegion as the two defs.
00146    int IsRemoteMergeProblem(legoOprd *def, legoOprd *orig_def);
00147    
00148    // HZ: Check whether a merge problem exist for the orig_def.
00149    // For each use of the orig_def (obtained by GetDUChain()), if the use is
00150    // preceeds the def (due to the loop back), or the use is not descendant of
00151    // the def, or the use is in different treegions, check the defs of this use
00152    // to see whether there is a merge problem between the orig_def and any of the
00153    // defs. Also checks whether the dst of the orig_def are among the live-ins
00154    // of the treegion. If so, return YES to show that there is merge problem.
00155    int IsMergeProblem(legoOprd *orig_def);
00156 
00157    // HZ: Check whether there are any dsts of the op that are live along the edge.
00158    int anyliveout(legoOp *op, opEdges *edge);
00159 
00160    // HZ: The define (renamed_def) has been renamed. So we need to remove the output
00161    // dep caused by this define. The function does so by checking both its
00162    // successors and predecessors. Then remove the corresponding dependence edge
00163    // in the DAG.
00164    void RemoveOutputDepsAfterRename(legoOprd *renamed_def);
00165    
00166    // HZ: Same as the one above except that it just checks predecessors.
00167    void RemoveOutputDepsAfterRenameUp(legoOprd *renamed_def);
00168    
00169    // HZ: Anti Dep removal after renaming the use.
00170    //   In the following scenario:
00171    //   Inst. a     <- r1, r2 ( use of r1 has been renamed)
00172    //               ... (other instructions)
00173    //   Inst. b  r1 <- (define of r1)
00174    //   Looking through the successors of instruction a, remove the anti
00175    //   dep if the reg no, reg type, Oprd File Type, etc. match. Remove the
00176    //   dep edge by removing the successor from instr a and removing predecessor
00177    //   from instr. b. Also it is noted that for brl op, when reg no is INTP1 ~
00178    //   DBL_P2. This dep edge is not removed.
00179    void RemoveAntiDepsAfterUseRename(legoOprd *renamed_use);
00180    
00181    // HZ: Anti Dep removal after renaming the def.
00182    //   In the following scenario:
00183    //   Inst. a     <- r1, r2 ( use of r1)
00184    //               ... (other instructions)
00185    //   Inst. b  r1 <- (define of r1 has been renamed)
00186    //   Looking through the predecessors of instruction b, remove the anti
00187    //   dep if the reg no, reg type, Oprd File Type, etc. match. Remove the
00188    //   dep edge by removing the successor from instr a and removing predecessor
00189    //   from instr. b. Also it is noted that for brl op, when reg no is INTP1 ~
00190    //   DBL_P2. This dep edge is not removed.
00191    void RemoveAntiDepsAfterDefRename(legoOprd *renamed_def);
00192 
00193    
00194    // copy_operand 
00195    //   Src = source operand
00196    //   Target = target operand
00197    //
00198    // Copies fields from Src to Target, assuming a register-type operand.
00199    // Does NOT copy next and prev pointers.  
00200    void copy_operand(legoOprd *Src, legoOprd *Target);
00201    
00202    // add_to_existing_attr
00203    //   Attr = existing live attribute
00204    //   NewOprd = new operand to add to attribute
00205    //
00206    // Adds a copy of the operand NewOprd to attribute Attr. If a copy
00207    // already resides in Attr, no action is taken.   
00208    void add_to_existing_attr(attrs *Attr, legoOprd *NewOprd);
00209    
00210    // create_new_attr
00211    //   Edge = edge on which to add live attribute
00212    //   Oprd = operand to add to attribute
00213    //   Proc = proc to whose dictionary to add edge
00214    //
00215    // Creates a new live attribute for Edge containing a copy of Oprd.
00216    void create_new_attr(opEdges *Edge, legoOprd *Oprd, legoProc *Proc);
00217                                 
00218    // HZ: Fix the liveness after we move the op sepculatively up to a different
00219    // block from its orginal block (where before_op resides in).
00220    // Add the dsts of the op to live attr of the edges along the path from its  
00221    // original block to its current block. 
00222    int FixLiveVarsUp(legoOp *op, legoOp *before_op, legoProc *proc_ptr);
00223    
00224    // HZ: Fix the liveness after we move the op sepculatively down to a different
00225    // block from its orginal block.
00226    // Add the srcs of the op to live attr of the edge.
00227    // Note: if op is a brl instr, the src oprds are MACRO REGS (from INT_P1 to
00228    // DBL_P2)
00229    int FixLiveVarsDown(legoOp *op, opEdges *edge, legoProc *proc_ptr);
00230 
00231    // HZ: Add use to the live attr of the edges along the path from the BB where
00232    // before_op resides in to the BB where the use is.
00233    int FixLiveVarsFromUses(legoOprd *use, legoOp *before_op, legoProc *proc_ptr);
00234    
00235    // HZ: Determine whether there is any instruction in the path from op to
00236    // before op that uses the same dst reg as compare_dest.
00237    // (the path is obtained using GetPrevLink or GetInList()->GetOp)
00238    int AnyOutputDepsBetween(legoOp *op, legoOp *op_in_multiop, legoOprd *compare_dest);
00239    
00240    // DoTheMessyStuff: This code allows branches to be scheduled above other 
00241    // operations (or allows ops to move below branches) during scheduling.
00242    // This usually results in copy of ops (depending on liveness out of the 
00243    // branches. Priority lists, liveness, and reaching definitions are updated 
00244    // incrementally.    
00245    // HZ: As it is said by Matt, this function moves the br op upwards. So the input
00246    // op is a br instr. The other input proc_ptr is used for updating the       
00247    // liveness attr.
00248    // This is how it is done:
00249    //   1. Process the case that the op is the exit op of the treegion or the op
00250    //   is either BRU or DUMMY BR. (return RENAMING CONFLICT)
00251    //   2. If the op is either BRCT or BRCF, then there are two exit edges,
00252    //      called first edge and second edge of
00253    //      the op (not the treegion). Processing each instruction that
00254    //      is above the op but not scheduled yet (variable above_op):
00255    //      a. If above_op is brl or store, set the attribute
00256    //         "no_longer_speculative".
00257    //      b. Check the control dep between above_op and op using
00258    //         DPG->AreOpsDependent(above_op, op) (Doubtful point for me,
00259    //        ambiguous in what the function does exactly)
00260    //      c. If above_op has control dep on op, then if the above_op is live on
00261    //         second edge or the above_op is either store/brl, a duplicate of
00262    //         the above op will be created (duplicate the predicate needs more
00263    //         work). Then the duplicate will be placed after the C_MERGE op
00264    //         along the second edge. Also the related DU, UD chain and DDG will 
00265    //         be updated to reflect the correct dep info and the liveness on the
00266    //         second edge need to be fixed by calling FixLiveVarsDown.
00267    //      d. If above_op has control dep on op, then if the above_op is live on
00268    //         first edge or the above_op is either store/brl, the above op      
00269    //         will be moved after the C_MERGE op along the first edge (there is
00270    //         no needs to duplicate the above op as it is processed along the
00271    //         second edge already). Also the related DU, UD chain and DDG will 
00272    //         be updated to reflect the correct dep info and the liveness on the
00273    //         first edge need to be fixed by calling FixLiveVarsDown.
00274    //      e. Processing the dead ops by adding the DPRemoveAttribute and remove
00275    //         the dep with its successors and predecessors.
00276    int DoTheMessyStuff(legoOp *op, legoRegion *proc_ptr);
00277 
00278    // This routine returns the second, complementary destination for a CMPP op.
00279    // If the second predicate dest is OT_UNDEFINED, one will be created. 
00280    // if the CMPP opcode does not produce a complementary second dest, the 
00281    // opcode will be updated. The second destination oprd is returned.
00282    legoOprd* GetComplementaryDestOprd(legoOp *cmppop);
00283    
00284    // This routine cleans up ops and adds a dp_remove attr so that they 
00285    // can be remove after procedure is scheduled. Removing them earlier fucks 
00286    // up priority lists and RDefs() 
00287    // HZ: This is the way how to do it:
00288    //    1. RemoveOp and AddOp such that the infor in priority list & RDefs are
00289    //       not disturbed.
00290    //    2. Set the schedule time as zero for the op and add DPRemoveAttribute
00291    //    3. Remove the dep between the op and its successors & predecessors.
00292    void PrepareToDie(legoOp *op);
00293    
00294    // As a result of control flow changes during the forming of Multi-Way 
00295    // branches, some ops get re-targeted. Need to update the dag to reflect 
00296    // new predecessor ops for control deps in these cases. 
00297    //HZ: This is the way it works: (the op is branch op ??)
00298    //    1.  Find the C_MERGE op preceeding the op and set the inlist of the
00299    //        C_MERGE op to include the new_predecessor_op.
00300    //    2.  Remove old predecessor/successor pair (CONT Dep) between the op and
00301    //        the old_predecessor_op.
00302    //    3.  Add control dep between op & new_predecessor_op.
00303    //    4.  Repeat step 2,3 for the C_MERGE op.        
00304    void UpdatePredecessorBranch(legoOp *op, legoOp *old_predecessor_op, legoOp *new_predecessor_op);
00305 
00306    // Allowing Multi-Way branches to be formed during list scheduling requires
00307    // even MoreMessyStuff. 
00308    // Here I DoMoreMessyStuff.    
00309    // HZ: DoMoreMessy stuff happens when we are trying to schedule the branch op
00310    // (op) speculatively  (i.e., the current_before_op is in a different BB from
00311    //  the BB where the op resides in.) After calling the function
00312    //  DoTheMessyStuff to move its above ops into its descendant BBs, the op and
00313    //  the CMERGE_op are the instructions left in the BB. The function
00314    //  DoMoreMessyStuff moves such a br upwards to its parentBB to form a
00315    //  multiway br. (the resulted empty BB is removed ??)
00316    //  This is the way how to do it:
00317    //    If Final_Pass is not set, return RENAMING_CONFLICT.
00318    //    1.  Find the related pointers, including predecessor_branch_op,
00319    //        original_block, c_merge_op
00320    //    2.  Find the last op in the predecessor_branc_op's multiop, since we
00321    //        will move the op just before this last op.
00322    //    3.  Since we currently can not handle the jump table, check the
00323    //        attributes of the op and predecessor_branch_op. If ATTR_TBLNAME is
00324    //        found, return RENAMING_CONFLICT. (Jump table is a doubtful point
00325    //        for me)
00326    //    4.  If the op is either an DUMMY_BR or an BRU instr:
00327    //         a. Update the inlist of the C_MERGE op following the op so that
00328    //            the predecessor_branch_op is in the inlist. Also adjust the
00329    //            edge from op to its following C_MERGE so that the edge starts  
00330    //            from predecessor_branch_op to the C_MERGE. Delete the edge from
00331    //            the predecessor to the C_MERGE which is just before the op.
00332    //            Update the outlist of the predecessor_branch_op.
00333    //         b. Retarget PBR of predecessor_branch_op to the target of the op
00334    //            if the predecessor is a BRU instr or the op is in the taken
00335    //            path of the predecssor_branch_op. (Doubtful point: what if the
00336    //            op is on the fall-through path of the predecessor_branch_op?)
00337    //         c. PrepareToDie the op and its pbrrop (probably already scheduled)
00338    //    5.  If the op is a RTS instr:
00339    //         a. If the predecessor_branch_op is either an BRU or an DUMMY_BR,
00340    //            replace the predecessor_branch_op with this RTS by:
00341    //            Move the RTS to the last op found in step 2; Remove the control
00342    //            dep of the predecessor and its following C_MERGE and set the
00343    //            predicate of the predecessor_branch_op as the predicate of the
00344    //            RTS; PrepareToDie the predecessor_branch_op & its pbrr and free
00345    //            the resources that scheduled to the predecessor_branch_op (PBRR
00346    //            op takes no resources ?).
00347    //         b. If the predecessor_branch_op is cond br, change the
00348    //            predecessor_branch_op to an BRU instr and move the RTS up.
00349    //            Implementing this involves the following steps:
00350    //              b1. check whether the op is in the taken path of the
00351    //                  predecessor_branch_op
00352    //              b2. create a predicate for the RTS op that will be moved up.
00353    //                  Based on the CMPP op / orig_fall_through attribute of the
00354    //                  predecessor_branch_op, a predicate orpd is constructed.
00355    //              b3. Adjust the UD, DU chains to include the new predicate
00356    //                  oprd.
00357    //              b4. If the op is in the taken path of the
00358    //                  predecessor_branch_op and the predecessor_branch_op is
00359    //                  BRCF, set the predicate value of the RTS as the
00360    //                  complementary of what cmpp set. Also set the predicate
00361    //                  value of the predecessor_branch_op as what cmpp set.
00362    //              b5. If the op is in the taken path of the
00363    //                  predecessor_branch_op and the predecessor_branch_op is
00364    //                  BRCT, set the predicate value of the RTS as what cmpp set
00365    //                  and set the predicate value of the predecessor_branch_op
00366    //                  as the complementary of what cmpp set.
00367    //              b6. Process the other two cases of the RTS is in the fall
00368    //                  through path of the predecessor_branch_op which is either
00369    //                  BRCT or BRCF.
00370    //              b7. move up the RTS op, change the predecessor_branch_op 
00371    //                  (BRCT/BRCF) to BRU and update the the target of the
00372    //                  pbrr to point to the right CB.
00373    //    6.  If the op is a BRCT or BRCF instr:
00374    //         a. If the predecessor_branch_op is a BRU instr, we will retarget
00375    //            this predecessor_branch_op to the op's fall through block and
00376    //            change the the op to a BRU instr. Then mode the op upwards,
00377    //            update the control edges, UD DU chain for the predicates,
00378    //            update the predecessor/successor relationship, etc.
00379    //         b. If the predecessor_branch_op is a BRCT/BRCF instr, we will
00380    //            combine the op and predecessor_branch_op into a BRU and a BRC.
00381    //              b1. If the op is in the taken path of the
00382    //                  predecessor_branch_op, make the op a predicated BRU and
00383    //                  retarget the predecessor_branch_op to the fall-through
00384    //                  path of the op. Also do the related book-keeping
00385    //                  including: creating the new predicate, update the in/out
00386    //                  edges, in/out lists, DU/UD chain, predecessor/successor
00387    //                  dep relationship, change the op to BRU, etc.
00388    //              b2. If the op is in the fall-through path of the
00389    //                  predecessor_branch_op, change the predecessor_branch_op
00390    //                  to a BRU targeting at its orginal taken path. Change the
00391    //                  position of the op and predecessor_branch_op such that
00392    //                  the brc* happens at the end of the multiway branch. (o.w.,
00393    //                  yula may take the fall-thru path of the brc*
00394    //                  incorrectly.)
00395    //    7.  If the original block only has c_merge op left, destroy the
00396    //        cmerge_op and the BB. (actually, it is not deleted here, but the
00397    //        edge info. is updated. The actual removal happened after the
00398    //        procedure is scheduled (in Function ScheduleProc in schedule.C)).
00399    // 
00400    int DoMoreMessyStuff(legoOp *op, int Final_Pass);
00401 
00402    // HZ: Scan the current region under scheduling. For each br instr, if it is
00403    // not DUMMY_BR or dp_removed, find the the corresponding PBR and move the
00404    // PBR just before the br inst. If the need_duplicate attribute is set for
00405    // the PBR, duplicate the PBR and move the duplicated pbrr just before the
00406    // br.
00407    void PlacePBRsJustBeforeBranches(); 
00408    
00409    // HZ: Scan through the current region. Put the br to the end of the BB that
00410    // it resides in.
00411    void PlaceBranchesLast();
00412 
00413 
00414    // *********************************************************************************************
00415    // Scheduling Functions
00416    // *********************************************************************************************
00417    
00418    // MCT: ScheduleOp moves ops and sets schedule times once they can be scheduled. An
00419    // integer flag is returned indicating whether a renaming conflict was encountered.
00420    int ScheduleOp(legoOp *op, int cycle);
00421 
00422    // MCT: These functions traverse a treegion and schedule its constituent basic-blocks in
00423    // either a depth-first or breadth-first manner. One of these two functions is called from
00424    // ScheduleTree based on the "op-scheduler:tree-traversal" knob.
00425    void ScheduleTreeBreadthFirst();
00426    void ScheduleTreeDepthFirst(legoRegion *Block, int StartCycle);
00427 
00428    // *********************************************************************************************
00429    // Utility Functions
00430    // *********************************************************************************************
00431 
00432    //HZ: Note:
00433    // Matt used the word 'attribute' to describe the private/public variables of
00434    // the class. Also the word is used in the description of the Rebel code.
00435    // The meaning of the word in the comments should be clear from the context.
00436 
00437    // DescendantofBlock: Returns YES if this operation 
00438    // belongs to a block which is a descendant of the 
00439    // block identified by a pointer of value input_block_int.      
00440    int DescendantofBlock(int input_block_int, legoOp *op);
00441 
00442    // DescendantofCurBlockPtr: Returns YES if this operation 
00443    // belongs to a block which is a descendant of the 
00444    // block identified by the current_block_int attribute. 
00445    // It can be seen as a special case of the previous function with
00446    // the input_block_int is current_block_int and op as Node->GetOp().
00447    int DescendantofCurBlockPtr(ListIterator Node);
00448 
00449    // MCT: BuildList builds a valid sequential order of LegoOps for the op scheduler to consume.
00450    // At inception, BuildList will basically just spit out the list generated by the
00451    // DAG builder.
00452    // void BuildList();
00453 
00454    // MCT: BuildReadyTimes finds the ready times for each operand of the next unscheduled
00455    // candidate op
00456    void BuildReadyTimes(ListIterator Node, int IssueCycle);
00457    
00458    // MCT: PredecessorsScheduled determines whether all of a candidate's predecessor ops have
00459    // been scheduled. Returns YES is all predecessors have been scheduled, NO otherwise.
00460    int PredecessorsScheduled(ListIterator Node);
00461 
00462    // MCT: SortRegionListByWeight takes a LEGO regionList, converts it into a vector of legoRegions,
00463    // then calls BubbleSortRegionList to sort the vector. This allows us to schedule child
00464    // basic-blocks in order of profile weight.
00465    vector <legoRegion *> SortRegionListByWeight(regionList *rlist);
00466 
00467    // MCT: Performs a bubble sort of a vector of legoRegions based on the Compare function passed.
00468    void BubbleSortRegionList(vector <legoRegion *> Vector, int (*Compare)(legoRegion *, legoRegion *));
00469 
00470    // MCT: Tells the scheduler if this region has already been scheduled. I use this to avoid spinning
00471    // trying to schedule a child block that is a child of itself (i.e. has a back edge to itself).
00472    int HasBlockBeenScheduled(legoRegion *Block);
00473 
00474    // MCT: PrintBlockSchedule is used for debug purposes only.
00475    void PrintSchedule();
00476 
00477 public:
00478 
00479    // constructors and destructors
00480    op_scheduler() {}
00481    op_scheduler(legoRegion *, machine *, knobs *);
00482    ~op_scheduler() {}
00483 
00484    // Set knobs specific for operation scheduling
00485    virtual void SetKnobs();
00486 
00487    // Operation schedule a basic-block.
00488    int ScheduleBlock(legoRegion *Block, int StartCycle);
00489 
00490    // Operation schedule a treegion.
00491    void ScheduleTree();
00492 };
00493 
00494 
00495 #endif // _OP_SCHEDULER_H_

Generated on Mon Jul 21 20:28:47 2003 for TINKER LEGO DOC by doxygen 1.3.2