00001 /* 00002 * Copyright 2004, 2005, 2006 PathScale, Inc. All Rights Reserved. 00003 */ 00004 00005 /* 00006 00007 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00008 00009 This program is free software; you can redistribute it and/or modify it 00010 under the terms of version 2 of the GNU General Public License as 00011 published by the Free Software Foundation. 00012 00013 This program is distributed in the hope that it would be useful, but 00014 WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 00017 Further, this software is distributed without any warranty that it is 00018 free of the rightful claim of any third person regarding infringement 00019 or the like. Any license provided herein, whether implied or 00020 otherwise, applies only to this software file. Patent licenses, if 00021 any, provided herein do not apply to combinations of this program with 00022 other software, or any other product whatsoever. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with this program; if not, write the Free Software Foundation, Inc., 59 00026 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00027 00028 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00029 Mountain View, CA 94043, or: 00030 00031 http://www.sgi.com 00032 00033 For further information regarding this notice, see: 00034 00035 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00036 00037 */ 00038 00039 00040 /* ======================================================================= 00041 * ======================================================================= 00042 * 00043 * Module: cg_dep_graph.h 00044 * $Revision: 1.6 $ 00045 * $Date: 05/12/05 08:59:03-08:00 $ 00046 * $Author: bos@eng-24.pathscale.com $ 00047 * $Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/SCCS/s.cg_dep_graph.h $ 00048 * 00049 * Revision comments: 00050 * 00051 * 4-Apr-1995 - Initial version 00052 * 00053 * Description: 00054 * ============ 00055 * 00056 * This module implements the data dependence graph within the code 00057 * generator. The dependence graph for a BB or BB_SET is a Directed 00058 * Graph whose nodes are OPs and whose edges (arcs) indicate a 00059 * dependence between the connected nodes. CYCLIC graphs have cycles 00060 * to represent loop-carried dependences. Currently, only NON_CYCLIC 00061 * graphs are built for BB_SETs. BB_SETs must obey the same control- 00062 * flow constraints as regions (single entry, containing all BBs on 00063 * all control flow paths from the entry to all exits). Dependence 00064 * graphs are allocated in the PU memory pool. Currently, at most one 00065 * can exist at any one time. 00066 * 00067 * The main types exported by this module are CG_DEP_KINDs, ARCs 00068 * and ARC_LISTs: 00069 * 00070 * CG_DEP_KIND 00071 * Dependency kinds for ARCs. 00072 * 00073 * ARC_LIST 00074 * A list of ARCs. ARC_LISTs can be read (but not written) by: 00075 * 00076 * ARC *ARC_LIST_first(ARC_LIST *arcs) 00077 * Returns the first ARC in <arcs>. 00078 * (Equivalent to ARC_LIST_node in Ragnarok.) 00079 * 00080 * ARC_LIST *ARC_LIST_rest(ARC_LIST *arcs) 00081 * Returns list of the rest of the arcs (after the first) 00082 * in <arcs>. (Equivalent to ARC_LIST_next in Ragnarok.) 00083 * 00084 * ARC_LIST *OP_preds(OP *op) 00085 * ARC_LIST *OP_succs(OP *op) 00086 * Return list of arcs coming into / out of <op>. 00087 * A NULL value indicates an empty list. 00088 * 00089 * ARC_LIST *CG_DEP_GTN_Use_Arcs(TN *tn) 00090 * Return list of arcs to local uses of global <tn> in 00091 * the currently computed dependence graph. These arcs 00092 * all have kind CG_DEP_REGIN. Neither ARC_latency nor ARC_pred 00093 * can be accessed for these arcs. 00094 * 00095 * and searched by: 00096 * 00097 * ARC_LIST *ARC_LIST_Find(ARC_LIST *list,CG_DEP_KIND kind,INT16 opnd) 00098 * Searches <list> for the first arc such that ARC_kind(arc) 00099 * is <kind> and either ARC_has_opnd(arc) is FALSE, or 00100 * <opnd> is DONT_CARE, or ARC_opnd(arc) is <opnd>. If 00101 * found, returns the ARC_LIST starting with <arc>. 00102 * Otherwise returns NULL. 00103 * 00104 * ARC *ARC_LIST_Find_First(ARC_LIST *list,CG_DEP_KIND kind,INT16 opnd) 00105 * Same as ARC_LIST_Find, but returns the first ARC from 00106 * <list> matching <kind> and <opnd>, or NULL if there's 00107 * no such arc. 00108 * 00109 * ARC 00110 * An edge indicating a dependence between two OPs. ARC attributes 00111 * can be read (but not written) with: 00112 * 00113 * CG_DEP_KIND ARC_kind(ARC *arc) 00114 * Describes the kind of dependence represented. 00115 * Some examples are CG_DEP_REGIN and CG_DEP_MEMANTI. 00116 * 00117 * INT16 ARC_latency(ARC *arc) 00118 * Returns the latency between the OPs connected by <arc>. 00119 * 00120 * UINT8 ARC_omega(ARC *arc) 00121 * Returns the number of loop iterations back spanned by <arc>. 00122 * This is zero for all but cyclic dependences. An omega of 00123 * MAX_OMEGA implies the actual omega is >= MAX_OMEGA. (See 00124 * "cg_loop.h" for MAX_OMEGA.) 00125 * 00126 * UINT8 ARC_opnd(ARC *arc) 00127 * Available only for CG_DEP_REGIN and CG_DEP_REGANTI arcs. Tells 00128 * which operand is involved in the dependence. It is an error 00129 * to access this for non-REGIN/REGANTI arcs. 00130 * 00131 * BOOL ARC_has_opnd(ARC *arc) 00132 * Tells whether the ARC_opnd accessor is valid for this arc 00133 * (i.e., whether this is a REGIN or REGANTI arc). 00134 * 00135 * BOOL ARC_is_definite(ARC *arc) 00136 * Available only for memory dependence arcs (see ARC_is_mem, 00137 * below). Tells whether the dependence in question is definite 00138 * (both addresses known to always be the same). Always TRUE 00139 * for CG_DEP_SPILLIN arcs. 00140 * 00141 * BOOL ARC_is_dotted(ARC *arc) 00142 * Tells whether the dependence in question is dotted, 00143 * i.e. not always strictly observed. 00144 * 00145 * BOOL ARC_is_mem(ARC *arc) 00146 * Tells whether the arc is a memory dependence arc (i.e., one 00147 * of CG_DEP_MEMIN/MEMOUT/MEMANTI/MEMVOL/MEMREAD/SPILLIN). 00148 * 00149 * BOOL ARC_is_reg(ARC *arc) 00150 * Tells whether the arc is a register dependence arc (i.e., one 00151 * of CG_DEP_REGIN/REGOUT/REGANTI). 00152 * 00153 * BOOL ARC_is_input(ARC *arc) 00154 * Tells whether the arc is an input (aka flow, true) dependence. 00155 * 00156 * BOOL ARC_is_output(ARC *arc) 00157 * Tells whether the arc is an output dependence. 00158 * 00159 * BOOL ARC_is_anti(ARC *arc) 00160 * Tells whether the arc is an anti-dependence. 00161 * 00162 * OP *ARC_pred(ARC *arc) 00163 * Returns the OP which is the source of the dependence in <arc>. 00164 * (This replaces ARC_tail in Ragnarok.) 00165 * 00166 * OP *ARC_succ(ARC *arc) 00167 * Returns the OP which is the destination of the dependence 00168 * in <arc>. (This replaces ARC_head in Ragnarok.) 00169 * 00170 * To compute (or update) the dependence graph for a BB, call: 00171 * 00172 * void CG_DEP_Compute_Graph(BB *bb, 00173 * BOOL include_assigned_registers, 00174 * BOOL cyclic, 00175 * BOOL include_memread_arcs, 00176 * BOOL include_memin_arcs, 00177 * BOOL include_control_arcs, 00178 * TN_SET *need_anti_out_dep) 00179 * 00180 * <include_assigned_registers> indicates 00181 * whether dependences due solely to register assignments should be 00182 * included in the graph. (Note: dependences due to dedicated 00183 * registers are always included). <cyclic> indicates whether 00184 * we're building a cyclic or non-cyclic graph. The cyclic graph 00185 * is intended for cyclic schedulers such as software pipeliners. 00186 * It includes loop-carried dependences and does not include anti- 00187 * dependences that can be removed by TN renaming (but does include 00188 * anti-dependences due to dedicated register assignments since 00189 * these can't be renamed). <include_memread_arcs> tells the graph 00190 * builder whether to include memory arcs between dependent loads. 00191 * <include_memin_arcs> tells the graph builder whether to include 00192 * memory input dependences, i.e a store followed by load(s) dependence. 00193 * <include_control_arcs> tells the graph builder whether to include 00194 * control arcs between the OP and the branch instruction. 00195 * 00196 * For clarity, the following boolean symbolic constants are defined: 00197 * INCLUDE_ASSIGNED_REG_DEPS = TRUE 00198 * NO_ASSIGNED_REG_DEPS = FALSE 00199 * CYCLIC = TRUE 00200 * NON_CYCLIC = FALSE 00201 * INCLUDE_MEMREAD_ARCS = TRUE 00202 * NO_MEMREAD_ARCS = FALSE 00203 * INCLUDE_MEMIN_ARCS = TRUE 00204 * NO_MEMIN_ARCS = FALSE 00205 * INCLUDE_CONTROL_ARCS = TRUE 00206 * NO_CONTROL_ARCS = FALSE 00207 * 00208 * need_anti_out_dep is meaning only when cyclic dep graph is built 00209 * 00210 * 00211 * void CG_DEP_Compute_Region_Graph(list<BB*> bb_region, 00212 * BOOL include_assigned_registers, 00213 * BOOL include_memread_arcs, 00214 * BOOL include_control_arcs) 00215 * 00216 * This routines computes the dependence graph for a bb_region containing 00217 * a chain of sequential blocks (eg. hyperblocks). The essential 00218 * requirement of a bb_region is that it can only have a single entry point 00219 * but can have multiple exits. The rest of the parameters are described in 00220 * the previous section. 00221 * 00222 * To prune the dependence graph for list of BBs, call: 00223 * 00224 * void CG_DEP_Prune_Dependences(list<BB*> bblist, 00225 * BOOL prune_predicate_arcs); 00226 * 00227 * The above is used as a special-purpose routine to prune any dependences 00228 * of interest. <prune_predicate_arcs> is used to prune predicate 00229 * dependence arcs for guarded OPs which are inherently safe to speculate. 00230 * 00231 * For clarity, the following boolean symbolic constants are defined: 00232 * PRUNE_PREDICATE_ARCS = TRUE 00233 * NO_PRUNE_PREDICATE_ARCS = FALSE 00234 * 00235 * The following control knobs for debugging are defined: 00236 * BOOL CG_DEP_Ignore_LNO (-CG:ignore_lno) 00237 * Ignore LNO dependence info. 00238 * BOOL CG_DEP_Ignore_WOPT (-CG:ignore_wopt) 00239 * Ignore WOPT alias info. 00240 * BOOL CG_DEP_Addr_Analysis (-CG:addr_analysis) 00241 * Perform address analysis before resorting to WOPT and/or LNO 00242 * to determine memory aliasing relationships. 00243 * BOOL CG_DEP_Verify_Mem_Deps (-CG:verify_mem_deps) 00244 * Cross-check memory dependence info (CG's analysis vs LNO/WOPT 00245 * analysis). If there's a conflict, believe the CG info (since 00246 * its analysis is based on the current code, while the LNO/WOPT 00247 * info was based on the WHIRL IR), and emit a DevWarn showing 00248 * the conflict. 00249 * INT32 CG_DEP_Mem_Arc_Pruning (-CG:prune_mem=n) 00250 * Specify the level of pruning of memory arcs. Each level includes 00251 * all pruning enabled by lower levels: 00252 * level 0: No pruning 00253 * level 1: Pruning of non-cyclic graph 00254 * level 2: Pruning of 0-omega arcs in cyclic graph 00255 * level 3: Pruning of 1-omega arcs in cyclic graph 00256 * level 4: Maximum possible pruning 00257 * BOOL CG_DEP_Add_Alloca_Arcs (-CG:add_alloca_arcs) (default TRUE) 00258 * Specify whether or not CG should add MISC arcs between 00259 * stack-ptr definitions and memory ops that might be accessing 00260 * the stack. This is a temporary workaround for PV 707179. 00261 * 00262 * The currently-computed dependence graph can be dumped to the trace 00263 * file with: 00264 * void CG_DEP_Trace_Graph(BB *bb) // trace for a bb. 00265 * void CG_DEP_Trace_HB_Graph(list<BB*> bblist) // trace for a hyperblock. 00266 * while the arcs for a single OP (and the OP itself) may be traced with: 00267 * void CG_DEP_Trace_Op_Arcs(OP *op) 00268 * void CG_DEP_Trace_Op_SCC_Arcs(OP *op) (for SCC arcs - see below) 00269 * 00270 * 00271 * The identifier (BB_id) of the BB to which the graph applies is also 00272 * printed in the trace file. Individual ARCs can be dumped to the 00273 * trace file with: 00274 * 00275 * void CG_DEP_Trace_Arc(ARC *arc, BOOL is_succ, BOOL verbose) 00276 * Print dependency <arc> to the trace file. <is_succ> tells 00277 * whether the arc is from a successor list (used only to print 00278 * a 'p' or 's' before the arc) and <verbose> tells whether to 00279 * print the end nodes also. <is_succ> is ignored if <verbose> 00280 * is true. 00281 * 00282 * To determine whether the graph for BB is cyclic, use: 00283 * BOOL CG_DEP_Graph_Is_Cyclic(BB *bb) 00284 * Return TRUE iff there is a currently existing dep graph for <bb> 00285 * that is CYCLIC. 00286 * 00287 * The following functions are provided to determine the aliasing 00288 * relationship between two memory OPs (from arbitrary BBs): 00289 * 00290 * BOOL CG_DEP_Mem_Ops_Alias(OP *memop1, OP *memop2, BOOL *identical) 00291 * Requires: OP_load(memop1) || OP_store(memop1) 00292 * OP_load(memop2) || OP_store(memop2) 00293 * If <memop1> and <memop2> always access completely distinct memory 00294 * locations, returns FALSE. Otherwise returns TRUE, and if 00295 * <identical> isn't NULL, indicates whether the references are 00296 * to the exact same location and amount of data. 00297 * 00298 * BOOL CG_DEP_Mem_Ops_Offsets_Overlap(OP *memop1, OP *memop2, 00299 * BOOL *identical); 00300 * Requires: OP_load(memop1) || OP_store(memop1) 00301 * OP_load(memop2) || OP_store(memop2) 00302 * Looks only at the offsets (ignoring base TN) of <memop1> and 00303 * <memop2>, returning FALSE if the offsets might overlap (from 00304 * the same base). Otherwise returns TRUE, and if <identical> 00305 * isn't NULL, indicates whether they refer to the same location 00306 * and amount of data. 00307 * 00308 * and this one to determine whether (and how) an arbitrary op might be 00309 * aliased by a call: 00310 * 00311 * BOOL CG_DEP_Call_Aliases(OP *call_op, OP *op, BOOL read, BOOL write); 00312 * Requires: OP_call(call_op) && (read || write) 00313 * Returns TRUE iff <op> is aliased by <call_op>. Checks for read 00314 * aliases iff <read>, and write aliases iff <write>. 00315 * 00316 * The following latency-calculation function is exposed so that 00317 * other components can calculate latencies between dependent OPs 00318 * in different BBs. (This is currently used by the local scheduler 00319 * to schedule OPs whose results are live-out.) It computes the 00320 * latency from <pred> to <succ> of the given <kind> (typically 00321 * CG_DEP_REGIN) using the given operand number <opnd> (used only for 00322 * REGIN/REGANTI kinds). 00323 * 00324 * INT16 CG_DEP_Latency(OP *pred, OP *succ, CG_DEP_KIND kind, UINT8 opnd) 00325 * 00326 * To inquire about the latencies of operators without OPs, use: 00327 * 00328 * INT16 CG_DEP_Oper_Latency(TOP pred_oper, TOP succ_oper, 00329 * CG_DEP_KIND kind, UINT8 opnd) 00330 * 00331 * 00332 * To delete the dependence graph for a BB or a HB (hyperblock), call: 00333 * 00334 * void CG_DEP_Delete_Graph(void *item) 00335 * 00336 * Software pipelining and Hyberblock scheduling require "prebranch" 00337 * (CG_DEP_PREBR) arcs in 00338 * the cyclic graph. To avoid the expense of maintaining these all the 00339 * time, we provide: <comp_func> is a filter function to provide clients 00340 * with ability to care only for dependences they care: 00341 * void CG_DEP_Add_PREBR_Arcs(BB* bb, COMPARE_FUNCTION comp_func, 00342 * BOOL ignore_latency); 00343 * 00344 * Hyberblock scheduling also requires "postbranch" (CG_DEP_POSTBR) arcs 00345 * between the predecessor branch node and the successor op node (in the 00346 * context of single-entry multiple-exit BBs). 00347 * void CG_DEP_Add_POSTBR_Arcs(list<BB*>, COMPARE_FUNCTION comp_func, 00348 * BOOL ignore_latency); 00349 * 00350 * Special routines are provided so that the CG_LOOP module can add 00351 * and delete SCC (Strongly Connected Component) arcs: 00352 * 00353 * void CG_DEP_Add_SCC_Arc(OP *pred, OP *succ, UINT8 omega, INT16 latency, 00354 * ARC_LIST **scc_ancestor_list, 00355 * ARC_LIST **scc_descendent_list) 00356 * Construct a new SCC arc from <pred> to <succ> with the given 00357 * <omega> and <latency>, then attach it to <scc_ancestor_list> 00358 * and <scc_descendent_list>. 00359 * 00360 * void CG_DEP_Delete_SCC_Arcs(ARC_LIST *arcs) 00361 * Free the arcs in <arcs> so they can be reused. 00362 * 00363 * void CG_DEP_Set_SCC_ARC_omega(ARC *arc, UINT8 omega) 00364 * Change the omega on SCC arc <arc> to <omega>. 00365 * 00366 * void CG_DEP_Detach_Arc(ARC *arc) 00367 * Remove <arc> from OP_preds(ARC_succ(arc)) (from_succ) and/or 00368 * OP_succs(ARC_pred(arc)) (from_pred). detach_arc does both. 00369 * 00370 * 00371 * Generic utilitiy routines which query predicate relations from any two 00372 * given OPs (represented as const void*) 00373 * 00374 * BOOL OP_has_subset_predicate(const void *value1, const void *value2) 00375 * Checks to see if the <value2> qualifying predicate is a subset 00376 * predicate of <value1> qualifying predicate. 00377 * 00378 * BOOL OP_has_disjoint_predicate(const void *value1, const void *value2) 00379 * Checks to see if the <value2> qualifying predicate and <value1> 00380 * qualfying predicate are disjoint. 00381 * 00382 * ======================================================================= 00383 * ======================================================================= */ 00384 00385 #ifndef CG_DEP_GRAPH_INCLUDED 00386 #define CG_DEP_GRAPH_INCLUDED 00387 00388 #ifdef _KEEP_RCS_ID 00389 static char *cg_dep_graph_rcs_id = "$Source: /scratch/mee/2.4-65/kpro64-pending/be/cg/SCCS/s.cg_dep_graph.h $ $Revision: 1.6 $"; 00390 #endif /* _KEEP_RCS_ID */ 00391 00392 #include <list> 00393 #include "op.h" 00394 #include "op_map.h" 00395 #include "op_list.h" 00396 #include "tn.h" 00397 #include "tn_set.h" 00398 #include "cg_dep_graph_update.h" 00399 00400 /* Exported symbolic constants. */ 00401 00402 #define INCLUDE_ASSIGNED_REG_DEPS TRUE 00403 #define NO_ASSIGNED_REG_DEPS FALSE 00404 00405 #define CYCLIC TRUE 00406 #define NON_CYCLIC FALSE 00407 00408 #define INCLUDE_MEMREAD_ARCS TRUE 00409 #define NO_MEMREAD_ARCS FALSE 00410 00411 #define INCLUDE_MEMIN_ARCS TRUE 00412 #define NO_MEMIN_ARCS FALSE 00413 00414 #define INCLUDE_CONTROL_ARCS TRUE 00415 #define NO_CONTROL_ARCS FALSE 00416 00417 #define PRUNE_PREDICATE_ARCS TRUE 00418 #define NO_PRUNE_PREDICATE_ARCS FALSE 00419 00420 #if defined(TARG_IA64) 00421 #define delete_gtn_use_arcs() { TN_MAP_Delete(gtn_use_map); gtn_use_map = NULL; } 00422 #endif 00423 00424 /* Exported types and accessors */ 00425 00426 /* Define possible kinds for ARCs in the dependency graph: 00427 */ 00428 typedef enum cg_dep_kind { 00429 CG_DEP_REGIN, /* Register flow (true dependency): the succ uses 00430 * a TN defined by the pred. The pred must access 00431 * its operand after the succ writes it. */ 00432 CG_DEP_REGOUT, /* Register output: the succ redefines a TN defined 00433 * by the pred. The succ must write its operand 00434 * after the pred writes it. */ 00435 CG_DEP_REGANTI, /* Register anti-dependency: the succ redefines 00436 * a TN used by the pred. */ 00437 CG_DEP_MEMIN, /* Memory flow (true dependency): the succ may use 00438 * a memory location defined by the pred. The 00439 * succ must access its operand after the pred 00440 * writes it. */ 00441 CG_DEP_MEMOUT, /* Memory output: the succ may redefine a memory 00442 * location define by the pred. The succ must write 00443 * its operand after the pred writes it. */ 00444 CG_DEP_MEMANTI, /* Memory anti-dependency: the succ may redefine 00445 * a memory location used by the pred. The succ 00446 * must write its operand after the pred uses it. */ 00447 CG_DEP_MEMVOL, /* Memory input (volatile data): the succ and pred 00448 * both read the same memory location, and the 00449 * reference order must be preserved. */ 00450 CG_DEP_MEMREAD, /* Memory definite read-read (for r/r elimination) */ 00451 CG_DEP_SPILLIN, /* Dependence between a spill and restore */ 00452 CG_DEP_PREFIN, /* prefetch memory flow */ 00453 CG_DEP_PREFOUT, /* prefetch memory output */ 00454 CG_DEP_PREBR, /* Pre-branch: the succ is a branch operation. 00455 * The tail must be issued before the control 00456 * transfer takes effect, perhaps in the shadow. */ 00457 CG_DEP_POSTBR, /* Post-branch: the pred is a branch operation. 00458 * The head must be issued before the control 00459 * transfer takes effect */ 00460 CG_DEP_SCC, /* Strongly connected component arcs */ 00461 00462 #ifdef TARG_IA64 00463 CG_DEP_PRECHK, /* Pre-chk: the succ is a check op */ 00464 CG_DEP_POSTCHK, /* Post-chk: the pred is a check op */ 00465 CG_DEP_CTLSPEC, /* control speculation, a special dep */ 00466 /* between a cmp and its guarded operations. */ 00467 #endif 00468 CG_DEP_MISC, /* Everything else: the pred must be issued 00469 * before the succ. */ 00470 CG_DEP_NUM_KIND /* Number (count) of defined CG_DEP_KINDs */ 00471 } CG_DEP_KIND; 00472 00473 00474 /* In addition to the essential ARC attributes (pred, succ, latency, 00475 * kind, opnd), this implementation of ARCs keeps two "next" pointers: 00476 * one for the next predecessor and one for the next successor. These 00477 * are used because each ARC is a member of one OP's predecessor list 00478 * and one OP's successor list, so this way we can share the essential 00479 * ARC info among the two lists. This takes exactly the same amount 00480 * of memory as keeping a copy of the essential ARC info in both 00481 * lists, requires no external linkage, and makes memory management 00482 * easier than representing ARC_LISTs by dynamic vectors. (Assuming 00483 * pointers are 32 bits, that is. If we ever decide to use 64-bit 00484 * pointers, the dynamic vector approach will require less memory not 00485 * considering vector reuse efficiency.) */ 00486 00487 typedef struct arc { 00488 OP *pred; /* the predecessor */ 00489 OP *succ; /* the successor */ 00490 mINT16 latency; /* latency in cycles from pred to succ */ 00491 mUINT8 omega; /* iteration distance for loop-carried deps */ 00492 mUINT16 kind_def_opnd; /* kind is LOW 8 bits, definite is next bit, 00493 * dotted edge is the next bit, which tells 00494 * if the edge is not always strict and opnd 00495 * is the HIGH 4 bits */ 00496 struct arc *next[2]; /* next ARC in pred/succ list, respectively */ 00497 } ARC; 00498 00499 /* These accessors are read-only. The "+0" prevents use as lhs. */ 00500 00501 #define ARC_pred(arc) (((arc)->pred)+0) 00502 #define ARC_succ(arc) (((arc)->succ)+0) 00503 #define ARC_latency(arc) ((arc)->latency+0) 00504 #define ARC_omega(arc) ((arc)->omega+0) 00505 #define ARC_kind(arc) ((CG_DEP_KIND)((arc)->kind_def_opnd & 0xff)) 00506 #define ARC_is_definite(arc) (((arc)->kind_def_opnd >> 8) & 1) 00507 #define ARC_is_dotted(arc) (((arc)->kind_def_opnd >> 9) & 1) 00508 #define ARC_opnd(arc) ((arc)->kind_def_opnd >> 12) 00509 00510 #define Set_ARC_is_dotted(arc, val) { \ 00511 ARC *_arc = arc; \ 00512 _arc->kind_def_opnd &= ~0x0200; \ 00513 _arc->kind_def_opnd |= (val != 0) << 9; \ 00514 } 00515 00516 /* Because ARCs include next pred/succ fields, an ARC_LIST needs to 00517 * represent only the current first ARC in the list, plus a bit to 00518 * indicate whether to use the next[0] (pred) or next[1] (succ) field 00519 * when iterating. (The ARC_LIST_rest iterator applies to both pred 00520 * and succ lists. This allows us to walk ARC_LISTs the same 00521 * regardless of whether they come from succ or pred lists.) Since 00522 * the interface uses ARC_LIST pointers, and we know the memory they 00523 * reference will be at least word-aligned, we'll use the least 00524 * significant bit of the pointer to indicate which next pointer to 00525 * use and strip away this bit before dereferencing. 00526 */ 00527 typedef ARC ARC_LIST; 00528 00529 #define ARC_LIST_first(list) ((ARC *)(((INTPTR)(list)) & ~1)) 00530 00531 /* Make ARC_LIST_rest an inline function so <list> isn't 00532 * evaluated twice. 00533 */ 00534 inline ARC_LIST* ARC_LIST_rest(ARC_LIST *list) 00535 { 00536 UINT8 which = (INTPTR)list & 1; 00537 ARC_LIST *result = ARC_LIST_first(list)->next[which]; 00538 /* It's very common for loops to delete/detach arcs before using 00539 * ARC_LIST_rest, but this implementation does not allow that, 00540 * so check for this error. See also detach_arc_from_succ/pred 00541 * and delete_arc. 00542 */ 00543 DevAssert((INTPTR)result != ~0, 00544 ("can't follow link from deleted/detached arc")); 00545 return result == NULL ? result : (ARC_LIST *)((INTPTR)result | which); 00546 } 00547 00548 inline BOOL ARC_has_opnd(ARC *arc) 00549 { 00550 CG_DEP_KIND kind = ARC_kind(arc); 00551 return kind == CG_DEP_REGIN || kind == CG_DEP_REGANTI; 00552 } 00553 00554 inline BOOL ARC_is_mem(ARC *arc) 00555 { 00556 CG_DEP_KIND kind = ARC_kind(arc); 00557 return kind == CG_DEP_MEMIN || kind == CG_DEP_MEMOUT || 00558 kind == CG_DEP_MEMANTI || kind == CG_DEP_MEMVOL || 00559 kind == CG_DEP_MEMREAD || kind == CG_DEP_SPILLIN; 00560 } 00561 00562 inline BOOL ARC_is_reg(ARC *arc) 00563 { 00564 CG_DEP_KIND kind = ARC_kind(arc); 00565 return kind == CG_DEP_REGIN || kind == CG_DEP_REGOUT || kind == CG_DEP_REGANTI; 00566 } 00567 00568 inline BOOL ARC_is_input(ARC *arc) 00569 { 00570 CG_DEP_KIND kind = ARC_kind(arc); 00571 return kind == CG_DEP_REGIN || kind == CG_DEP_MEMIN || 00572 kind == CG_DEP_MEMVOL || kind == CG_DEP_SPILLIN; 00573 } 00574 00575 inline BOOL ARC_is_output(ARC *arc) 00576 { 00577 CG_DEP_KIND kind = ARC_kind(arc); 00578 return kind == CG_DEP_REGOUT || kind == CG_DEP_MEMOUT; 00579 } 00580 00581 inline BOOL ARC_is_anti(ARC *arc) 00582 { 00583 CG_DEP_KIND kind = ARC_kind(arc); 00584 return kind == CG_DEP_REGANTI || kind == CG_DEP_MEMANTI; 00585 } 00586 00587 /* --------------------------------------------------------------------- 00588 * Some internal globals and types (not exported): 00589 * 00590 * _CG_DEP_OP_INFO is a struct holding the per-OP dependence info. 00591 * 00592 * _cg_dep_op_info maps each BB to a BB_OP_MAP holding _CG_DEP_OP_INFO 00593 * for each OP in the BB. Usually we'll have _CG_DEP_OP_INFO for only 00594 * a single BB at a time, so this is much more efficient than having a 00595 * single (global) OP_MAP. May want to experiment with other representation 00596 * if this is no longer true. 00597 */ 00598 00599 extern BB_MAP _cg_dep_op_info; 00600 00601 typedef struct { 00602 ARC_LIST *preds; 00603 ARC_LIST *succs; 00604 } _CG_DEP_OP_INFO; 00605 00606 inline _CG_DEP_OP_INFO* _CG_DEP_op_info(OP *op) 00607 { 00608 BB_OP_MAP omap = (BB_OP_MAP) BB_MAP_Get(_cg_dep_op_info, OP_bb(op)); 00609 _CG_DEP_OP_INFO *info = (_CG_DEP_OP_INFO *) BB_OP_MAP_Get(omap, op); 00610 return info; 00611 } 00612 00613 inline _CG_DEP_OP_INFO* _CG_DEP_op_info_valid(OP *op) 00614 { 00615 _CG_DEP_OP_INFO *info = _CG_DEP_op_info(op); 00616 DevAssert(info, ("OP has no CG_DEP info")); 00617 return info; 00618 } 00619 00620 /* More exported declarations and macros */ 00621 00622 #ifdef DevAssert_On 00623 #define OP_preds(op) (_CG_DEP_op_info_valid(op)->preds+0) 00624 #define OP_succs(op) (_CG_DEP_op_info_valid(op)->succs+0) 00625 #else 00626 #define OP_preds(op) (_CG_DEP_op_info(op)->preds+0) 00627 #define OP_succs(op) (_CG_DEP_op_info(op)->succs+0) 00628 #endif 00629 00630 // Data structure to manage memory allocation for CYCLIC DEP GRAPH 00631 // 00632 class CYCLIC_DEP_GRAPH { 00633 private: 00634 BB *_body; 00635 public: 00636 CYCLIC_DEP_GRAPH( BB *body, MEM_POOL *pool ); 00637 ~CYCLIC_DEP_GRAPH(); 00638 }; 00639 00640 00641 #define DONT_CARE -1 00642 ARC_LIST *ARC_LIST_Find(ARC_LIST *list, CG_DEP_KIND kind, INT16 opnd); 00643 00644 inline ARC *ARC_LIST_Find_First(ARC_LIST *list, CG_DEP_KIND kind, INT16 opnd) 00645 { 00646 ARC_LIST *arcs = ARC_LIST_Find(list, kind, opnd); 00647 return arcs ? ARC_LIST_first(arcs) : NULL; 00648 } 00649 00650 typedef BOOL (*COMPARE_FUNCTION)(const void*, const void*); 00651 00652 void CG_DEP_Compute_Graph(struct bb *bb, 00653 BOOL assigned_regs, 00654 BOOL cyclic, 00655 BOOL memread_arcs, 00656 BOOL memin_arcs, 00657 BOOL control_arcs, 00658 TN_SET *need_anti_out_dep); 00659 00660 void CG_DEP_Compute_Region_Graph(std::list<BB*> bb_region, 00661 BOOL assigned_regs, 00662 BOOL memread_arcs, 00663 BOOL control_arcs); 00664 00665 void CG_DEP_Prune_Dependence_Arcs(std::list<BB*> bblist, 00666 BOOL prune_predicate_arcs, 00667 BOOL trace); 00668 00669 void CG_DEP_Trace_Graph(BB *bb); 00670 #pragma mips_frequency_hint NEVER CG_DEP_Trace_Graph 00671 00672 void CG_DEP_Trace_HB_Graph(std::list<BB*> bblist); 00673 #pragma mips_frequency_hint NEVER CG_DEP_Trace_HB_Graph 00674 00675 void CG_DEP_Trace_Arc(ARC *arc, BOOL is_succ, BOOL verbose); 00676 #pragma mips_frequency_hint NEVER CG_DEP_Trace_Arc 00677 00678 void CG_DEP_Trace_Op_Arcs(OP *op); 00679 #pragma mips_frequency_hint NEVER CG_DEP_Trace_Op_Arcs 00680 00681 void CG_DEP_Trace_Op_SCC_Arcs(OP *op); 00682 #pragma mips_frequency_hint NEVER CG_DEP_Trace_Op_SCC_Arcs 00683 00684 void CG_DEP_Delete_Graph(void *item); 00685 00686 #ifdef TARG_IA64 00687 INT16 CG_DEP_Oper_cycle(TOP oper, CG_DEP_KIND kind); 00688 #endif 00689 00690 INT16 CG_DEP_Latency(OP *pred, OP *succ, CG_DEP_KIND kind, UINT8 opnd); 00691 INT16 CG_DEP_Oper_Latency(TOP pred_oper, 00692 TOP succ_oper, 00693 CG_DEP_KIND kind, 00694 UINT8 opnd); 00695 00696 void CG_DEP_Add_SCC_Arc(OP *pred, 00697 OP *succ, 00698 UINT8 omega, 00699 INT16 latency, 00700 ARC_LIST **scc_ancestor_list, 00701 ARC_LIST **scc_descendent_list); 00702 00703 void CG_DEP_Delete_SCC_Arcs(ARC_LIST *arcs); 00704 00705 void CG_DEP_Set_SCC_ARC_omega(ARC *arc, UINT8 omega); 00706 00707 extern BOOL CG_DEP_Ignore_LNO; 00708 extern BOOL CG_DEP_Ignore_WOPT; 00709 extern BOOL CG_DEP_Addr_Analysis; 00710 extern BOOL CG_DEP_Verify_Mem_Deps; 00711 extern INT32 CG_DEP_Mem_Arc_Pruning; 00712 extern BOOL CG_DEP_Add_Alloca_Arcs; 00713 extern BOOL CG_DEP_Relax_Xfer_Dependence; 00714 extern BOOL CG_DEP_Adjust_OOO_Latency; 00715 extern BOOL CG_DEP_Prune_Dependence; 00716 00717 BOOL CG_DEP_Add_Same_Res_Arcs(); 00718 void CG_DEP_Remove_Same_Res_Arcs(); 00719 00720 void CG_DEP_Add_Op_Same_Res_Arcs(OP *op); 00721 void CG_DEP_Remove_Op_Same_Res_Arcs(OP *op); 00722 00723 void CG_DEP_Add_PREBR_Arcs(BB *bb, COMPARE_FUNCTION comp_func, BOOL ignore_latency); 00724 00725 BOOL CG_DEP_Graph_Is_Cyclic(BB *bb); 00726 00727 ARC_LIST *CG_DEP_GTN_Use_Arcs(TN *tn); 00728 00729 BOOL CG_DEP_Mem_Ops_Alias(OP *memop1, OP *memop2, BOOL *identical); 00730 00731 BOOL CG_DEP_Mem_Ops_Offsets_Overlap(OP *memop1, OP *memop2, BOOL *identical); 00732 00733 BOOL CG_DEP_Call_Aliases(OP *call_op, OP *op, BOOL read, BOOL write); 00734 00735 BOOL CG_DEP_Can_OP_Move_Across_Call(OP *cur_op, OP *call_op, BOOL forw, BOOL Ignore_TN_Dep); 00736 00737 extern BOOL OP_has_subset_predicate(const void *value1, const void *value2); 00738 extern BOOL OP_has_disjoint_predicate(const OP *value1, const OP *value2); 00739 00740 #if defined(TARG_IA64) 00741 inline BOOL TN_is_predicate (TN * tn) 00742 { 00743 return TN_is_register(tn) && TN_register_class(tn) == ISA_REGISTER_CLASS_predicate; 00744 } 00745 #endif 00746 00747 extern void CG_DEP_Detach_Arc(ARC *arc); 00748 00749 #if defined(TARG_IA64) || defined(TARG_SL) || defined(TARG_MIPS) 00750 extern ARC *new_arc(CG_DEP_KIND kind, OP *pred, OP *succ, UINT8 omega, 00751 UINT8 opnd, BOOL is_definite); 00752 #endif 00753 00754 #endif /* CG_DEP_GRAPH_INCLUDED */
1.5.6