Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
prompf.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 #ifdef USE_PCH
00037 #include "be_com_pch.h"
00038 #endif /* USE_PCH */
00039 #pragma hdrstop
00040 #include <sys/types.h>
00041 #include <elf.h>
00042 #include <stdio.h> 
00043 
00044 #define USE_STANDARD_TYPES
00045 #include "wn.h"
00046 #include "stab.h"
00047 #include "cxx_template.h"
00048 #include "cxx_memory.h" 
00049 #include "anl_driver.h"
00050 #include "prompf.h"
00051 #include "ir_reader.h"
00052 #include "targ_sim.h"
00053 
00054 #if defined(_GCC_NO_PRAGMAWEAK) || defined(__CYGWIN__)
00055 
00056 // symbols defined in prompf_anl.so (and stubbed in driver.cxx)
00057 // from be/prompf_anl/anl_driver.h
00058 
00059 extern "C" INT64 Get_Next_Construct_Id() { return 0; }
00060 extern "C" INT64 New_Construct_Id() { return 0; }
00061 extern "C" const char * Anl_File_Path() { return NULL; }
00062 
00063 #else 
00064 
00065 #pragma weak New_Construct_Id 
00066 #pragma weak Get_Next_Construct_Id
00067 #pragma weak Anl_File_Path
00068 
00069 #endif
00070 
00071 PROMPF_INFO* Prompf_Info = NULL; 
00072 MEM_POOL PROMPF_pool;
00073 FILE* STDOUT = stdout;
00074 
00075 //-----------------------------------------------------------------------
00076 // NAME: prompf_chain 
00077 // FUNCTION: For each PROMPF_TRANS_TYPE, gives the corresponding 
00078 //   MPF_CHAIN_TYPE.  
00079 //-----------------------------------------------------------------------
00080 
00081 PROMPF_CHAIN_TYPE prompf_chain[] = {
00082   /* MPF_UNKNOWN,             */  MPF_CHAIN_INVALID,
00083   /* MPF_MARK_F90_LOWER,      */  MPF_CHAIN_TRANSMIT,
00084   /* MPF_MARK_OMP,            */  MPF_CHAIN_TRANSMIT,
00085   /* MPF_MARK_PREOPT,         */  MPF_CHAIN_TRANSMIT,
00086   /* MPF_MARK_PRELNO,         */  MPF_CHAIN_TRANSMIT,
00087   /* MPF_MARK_POSTLNO,        */  MPF_CHAIN_TRANSMIT,
00088   /* MPF_ELIMINATION,         */  MPF_CHAIN_TRANSFORM,
00089   /* MPF_FUSION,              */  MPF_CHAIN_TRANSFORM,
00090   /* MPF_FISSION,             */  MPF_CHAIN_TRANSFORM,  
00091   /* MPF_DISTRIBUTION,        */  MPF_CHAIN_TRANSFORM,
00092   /* MPF_INTERCHANGE          */  MPF_CHAIN_TRANSMIT,
00093   /* MPF_PRE_PEEL             */  MPF_CHAIN_TRANSFORM,
00094   /* MPF_POST_PEEL            */  MPF_CHAIN_TRANSFORM, 
00095   /* MPF_MP_TILE              */  MPF_CHAIN_TRANSFORM,
00096   /* MPF_DSM_TILE             */  MPF_CHAIN_TRANSFORM,
00097   /* MPF_DONEST_OUTER_TILE    */  MPF_CHAIN_TRANSFORM, 
00098   /* MPF_DONEST_MIDDLE_TILE   */  MPF_CHAIN_TRANSFORM, 
00099   /* MPF_DSM_LOCAL            */  MPF_CHAIN_TRANSFORM,
00100   /* MPF_DSM_IO               */  MPF_CHAIN_TRANSFORM, 
00101   /* MPF_SINGLE_PROCESS       */  MPF_CHAIN_TRANSFORM,
00102   /* MPF_MP_VERSION           */  MPF_CHAIN_TRANSFORM,
00103   /* MPF_PARALLEL_REGION      */  MPF_CHAIN_TRANSFORM,
00104   /* MPF_HOIST_MESSY_BOUNDS   */  MPF_CHAIN_TRANSFORM,
00105   /* MPF_DOACROSS_SYNC        */  MPF_CHAIN_TRANSFORM,
00106   /* MPF_DOACROSS_OUTER_TILE  */  MPF_CHAIN_TRANSFORM,
00107   /* MPF_DOACROSS_INNER_TILE  */  MPF_CHAIN_TRANSFORM,
00108   /* MPF_REMOVE_UNITY_TRIP    */  MPF_CHAIN_TRANSFORM,
00109   /* MPF_CACHE_WINDDOWN       */  MPF_CHAIN_TRANSFORM, 
00110   /* MPF_INTERLEAVED_WINDDOWN */  MPF_CHAIN_TRANSFORM, 
00111   /* MPF_GENERAL_VERSION      */  MPF_CHAIN_TRANSFORM,
00112   /* MPF_CACHE_TILE           */  MPF_CHAIN_TRANSFORM,
00113   /* MPF_REGISTER_WINDDOWN    */  MPF_CHAIN_TRANSFORM,
00114   /* MPF_REGISTER_SSTRIP      */  MPF_CHAIN_TRANSFORM,
00115   /* MPF_REGISTER_TILE        */  MPF_CHAIN_TRANSMIT,
00116   /* MPF_REGISTER_STARTUP     */  MPF_CHAIN_TRANSFORM,
00117   /* MPF_REGISTER_SHUTDOWN    */  MPF_CHAIN_TRANSFORM,
00118   /* MPF_SE_TILE              */  MPF_CHAIN_TRANSFORM,
00119   /* MPF_SE_CACHE_TILE        */  MPF_CHAIN_TRANSFORM,
00120   /* MPF_INNER_FISSION        */  MPF_CHAIN_TRANSFORM,
00121   /* MPF_GATHER_SCATTER       */  MPF_CHAIN_TRANSFORM,
00122   /* MPF_VINTR_FISSION        */  MPF_CHAIN_TRANSFORM,
00123   /* MPF_PREFETCH_VERSION     */  MPF_CHAIN_TRANSFORM,
00124   /* MPF_OMPL_SECTIONS_LOOP   */  MPF_CHAIN_TRANSMIT,
00125   /* MPF_OMPL_ELIM_SECTION    */  MPF_CHAIN_TRANSFORM,
00126   /* MPF_OMPL_ATOMIC_CSECTION */  MPF_CHAIN_TRANSMIT, 
00127   /* MPF_OMPL_ATOMIC_SWAP     */  MPF_CHAIN_TRANSFORM,
00128   /* MPF_OMPL_ATOMIC_FETCHOP  */  MPF_CHAIN_TRANSFORM,
00129   /* MPF_OMPL_MASTER_IF       */  MPF_CHAIN_TRANSFORM,
00130   /* MPF_OMPL_FETCHOP_ATOMIC  */  MPF_CHAIN_TRANSFORM,
00131   /* MPF_F90_ARRAY_STMT       */  MPF_CHAIN_TRANSFORM,
00132   /* MPF_OUTER_SHACKLE        */  MPF_CHAIN_TRANSFORM,
00133   /* MPF_INNER_SHACKLE        */  MPF_CHAIN_TRANSFORM,
00134   /* MPF_PREOPT_CREATE        */  MPF_CHAIN_TRANSFORM,
00135 }; 
00136 
00137 //-----------------------------------------------------------------------
00138 // NAME: PROMPF_LINES::Add_Lines
00139 // FUNCTION: Walk the tree rooted at 'wn_tree', adding the line numbers 
00140 //   of all of the statements to the PROMPF_LINES. 
00141 //-----------------------------------------------------------------------
00142 
00143 void PROMPF_LINES::Add_Lines(WN* wn_tree)
00144 {
00145    if (wn_tree == NULL) 
00146      return; 
00147 
00148    if (OPCODE_has_next_prev(WN_opcode(wn_tree)))
00149      Add_Line(WN_linenum(wn_tree)); 
00150 
00151    if (OPCODE_is_expression(WN_opcode(wn_tree)))  
00152      return; 
00153 
00154    if (WN_opcode(wn_tree) == OPC_BLOCK) { 
00155      for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn)) 
00156        Add_Lines(wn); 
00157    } else { 
00158      INT i;
00159      for (i = 0; i < WN_kid_count(wn_tree); i++) 
00160        Add_Lines(WN_kid(wn_tree, i)); 
00161    } 
00162 } 
00163 
00164 //-----------------------------------------------------------------------
00165 // NAME: PROMPF_LINES::PROMPF_LINES 
00166 // FUNCTION: Create a PROMPF_LINES containing the line numbers of all of 
00167 //   the statements in the tree 'wn_tree'.  Create the PROMPF_LINES out 
00168 //   of memory from 'pool'. 
00169 //-----------------------------------------------------------------------
00170 
00171 PROMPF_LINES::PROMPF_LINES(WN* wn_tree, 
00172                            MEM_POOL* pool): 
00173   _pool(pool), _low(pool), _high(pool)
00174 {
00175   Add_Lines(wn_tree);  
00176 } 
00177 
00178 //-----------------------------------------------------------------------
00179 // NAME: PROMPF_LINES::Sections 
00180 // FUNCTION: Returns the number of sections in the set of line number 
00181 //   ranges. 
00182 // EXAMPLE: The PROMPF_LINES with line numbers 1-7,9-15 has 2 sections.
00183 //-----------------------------------------------------------------------
00184 
00185 INT PROMPF_LINES::Sections()
00186 {
00187   FmtAssert(_low.Elements() == _high.Elements(), 
00188     ("PROMPF_LINES::Sections: high and low range counts do not match")); 
00189   return _low.Elements(); 
00190 } 
00191 
00192 //-----------------------------------------------------------------------
00193 // NAME: PROMPF_LINES::Low 
00194 // FUNCTION: Returns the low end of the 'i'-th line number range in the 
00195 //   PROMPF_LINES. 
00196 //-----------------------------------------------------------------------
00197 
00198 INT PROMPF_LINES::Low(INT i)
00199 {
00200   FmtAssert(i >= 0 && i <= _low.Elements(), 
00201     ("PROMPF_LINES::Low: Low part of section does not exist"));
00202   return _low.Bottom_nth(i); 
00203 } 
00204 
00205 //-----------------------------------------------------------------------
00206 // NAME: PROMPF_LINES::High 
00207 // FUNCTION: Returns the high end of the 'i'-th line number range in the 
00208 //   PROMPF_LINES. 
00209 //-----------------------------------------------------------------------
00210 
00211 INT PROMPF_LINES::High(INT i)
00212 {
00213   FmtAssert(i >= 0 && i <= _high.Elements(), 
00214     ("PROMPF_LINES::High: High part of section does not exist")); 
00215   return _high.Bottom_nth(i); 
00216 } 
00217 
00218 //-----------------------------------------------------------------------
00219 // NAME: PROMPF_LINES::Print 
00220 // FUNCTION: Print the PROMPF_LINES to the file 'fp'. 
00221 //-----------------------------------------------------------------------
00222 
00223 void PROMPF_LINES::Print(FILE* fp)
00224 {
00225   INT i;
00226   for (i = 0; i < Sections(); i++) { 
00227     fprintf(fp, "<%d:%d>", Low(i), High(i)); 
00228     if (i < Sections() - 1) 
00229       fprintf(fp, ","); 
00230   }
00231 }
00232 
00233 //-----------------------------------------------------------------------
00234 // NAME: PROMPF_LINES::Print_Compact 
00235 // FUNCTION: Print the PROMPF_LINES to the file 'fp' in compact form. 
00236 //   (This is the form used by the PROMPF anl file.)  
00237 //-----------------------------------------------------------------------
00238 
00239 INT PROMPF_LINES::Print_Compact(FILE* fp, 
00240                                 BOOL print_brackets) 
00241                                 
00242 {
00243   INT field_count = 0; 
00244   field_count += fprintf(fp, "lines "); 
00245   if (print_brackets) 
00246     fprintf(fp, "["); 
00247   INT i;
00248   for (i = 0; i < Sections(); i++) { 
00249     if (Low(i) == High(i))
00250       field_count += fprintf(fp, "%d", Low(i)); 
00251     else 
00252       field_count += fprintf(fp, "%d-%d", Low(i), High(i)); 
00253     if (i < Sections() - 1) 
00254       field_count += fprintf(fp, ","); 
00255   }
00256   if (print_brackets) 
00257     fprintf(fp, "]"); 
00258   return field_count; 
00259 }
00260 
00261 //-----------------------------------------------------------------------
00262 // NAME: PROMPF_LINES::Add_Line 
00263 // FUNCTION: Add the linenumber 'line' to the PROMPF_LINES. 
00264 //-----------------------------------------------------------------------
00265 
00266 void PROMPF_LINES::Add_Line(INT line) 
00267 { 
00268   FmtAssert(line >= 0, 
00269     ("PROMPF_LINES::Add_Line: Line number should not be negative")); 
00270   if (line == 0)
00271     return; 
00272   if (Sections() == 0) { 
00273     _low.Push(line); 
00274     _high.Push(line); 
00275    return; 
00276   } 
00277   INT i;
00278   for (i = 0; i < Sections(); i++) {
00279     if (line < Low(i)) 
00280       break; 
00281     if (line >= Low(i) && line <= High(i)) { 
00282       return; 
00283     } 
00284   }
00285   BOOL adjacent_low = i < Sections() && line == Low(i) - 1;  
00286   BOOL adjacent_high = i > 0 && line == High(i-1) + 1;
00287   if (adjacent_low) { 
00288     if (!adjacent_high) { 
00289       _low.Bottom_nth(i)--; 
00290     } else {  
00291       _high.Bottom_nth(i-1) = High(i); 
00292       STACK<INT> new_low(_pool);
00293       STACK<INT> new_high(_pool);
00294       INT replace_count = Sections() - i - 1; 
00295       INT j;
00296       for (j = 0; j < replace_count; j++) {
00297         INT lowpop = _low.Pop(); 
00298         new_low.Push(lowpop);
00299         INT highpop = _high.Pop();  
00300         new_high.Push(highpop); 
00301       } 
00302       _low.Pop(); 
00303       _high.Pop(); 
00304       for (j = 0; j < replace_count; j++) {
00305         INT newlowpop = new_low.Pop(); 
00306         _low.Push(newlowpop); 
00307         INT newhighpop = new_high.Pop(); 
00308         _high.Push(newhighpop); 
00309       } 
00310     } 
00311   } else { 
00312     if (adjacent_high) { 
00313       _high.Bottom_nth(i-1)++; 
00314     } else { 
00315       STACK<INT> new_low(_pool);   
00316       STACK<INT> new_high(_pool);  
00317       INT replace_count = Sections() - i;  
00318       INT j;
00319       for (j = 0; j < replace_count; j++) {
00320         INT lowpop = _low.Pop(); 
00321         new_low.Push(lowpop);
00322         INT highpop = _high.Pop();  
00323         new_high.Push(highpop); 
00324       } 
00325       _low.Push(line); 
00326       _high.Push(line); 
00327       for (j = 0; j < replace_count; j++) {
00328         INT newlowpop = new_low.Pop(); 
00329         _low.Push(newlowpop); 
00330         INT newhighpop = new_high.Pop(); 
00331         _high.Push(newhighpop); 
00332       } 
00333     }
00334   } 
00335 } 
00336 
00337 //-----------------------------------------------------------------------
00338 // NAME: PROMPF_TRANS::Old_Loop 
00339 // FUNCTION: Returns the id of the PROMPF_TRANS's 'i'th old loop. 
00340 //-----------------------------------------------------------------------
00341 
00342 INT PROMPF_TRANS::Old_Loop(INT i)
00343 {
00344   FmtAssert(i >= 0 && i < _old_loops.Elements(), 
00345     ("PROMPF_TRANS::Old_Loop() index out of range")); 
00346   return _old_loops.Bottom_nth(i); 
00347 }
00348 
00349 //-----------------------------------------------------------------------
00350 // NAME: PROMPF_TRANS::New_Loop 
00351 // FUNCTION: Returns the id of the PROMPF_TRANS's 'i'th new loop. 
00352 //-----------------------------------------------------------------------
00353 
00354 INT PROMPF_TRANS::New_Loop(INT i)
00355 {
00356   FmtAssert(i >= 0 && i < _new_loops.Elements(), 
00357     ("PROMPF_TRANS::New_Loop() index out of range")); 
00358   return _new_loops.Bottom_nth(i); 
00359 }
00360 
00361 //-----------------------------------------------------------------------
00362 // NAME: PROMPF_TRANS::Prev_Loop
00363 // FUNCTION: Returns the transaction index of the previous instance of 
00364 //   the PROMPF_TRANS's 'i'th old loop.  Returns -1 if there is no previous 
00365 //   instance.   
00366 //-----------------------------------------------------------------------
00367 
00368 INT PROMPF_TRANS::Prev_Loop(INT i)
00369 {
00370   FmtAssert(i >= 0 && i < _prev_loops.Elements(), 
00371     ("PROMPF_TRANS::Prev_Loop() index out of range")); 
00372   return _prev_loops.Bottom_nth(i); 
00373 }
00374 
00375 //-----------------------------------------------------------------------
00376 // NAME: PROMPF_TRANS:: Add_Index_Name
00377 // FUNCTION: Add the name of the newly created index variable 'index_name' 
00378 //   to the PROMPF_TRANS. 
00379 //-----------------------------------------------------------------------
00380 
00381 void PROMPF_TRANS::Add_Index_Name(char* index_name)
00382 { 
00383   char* name = (char*) CXX_NEW_ARRAY(char, strlen(index_name) + 1, _pool);
00384   strcpy(name, index_name);
00385   _index_name = name; 
00386 } 
00387 
00388 //-----------------------------------------------------------------------
00389 // NAME: PROMPF_TRANS::Print 
00390 // FUNCTION: Print the PROMPF_TRANS to the file 'fp'.  
00391 //-----------------------------------------------------------------------
00392 
00393 void PROMPF_TRANS::Print(FILE* fp)
00394 {
00395   const INT MIDDLE_FIELD_COUNT = 30; 
00396   switch (_type) {
00397   case MPF_UNKNOWN: 
00398     fprintf(fp, "UNKNOWN              "); 
00399     break;
00400   case MPF_MARK_OMP: 
00401     fprintf(fp, "MARK OMP             "); 
00402     break;
00403   case MPF_MARK_PREOPT: 
00404     fprintf(fp, "MARK PREOPT          "); 
00405     break;
00406   case MPF_MARK_PRELNO: 
00407     fprintf(fp, "MARK PRELNO          "); 
00408     break;
00409   case MPF_MARK_POSTLNO: 
00410     fprintf(fp, "MARK POSTLNO         "); 
00411     break;
00412   case MPF_ELIMINATION: 
00413     fprintf(fp, "ELIMINATION          ");  
00414     break;
00415   case MPF_FUSION:
00416     fprintf(fp, "FUSION               ");  
00417     break;
00418   case MPF_FISSION:
00419     fprintf(fp, "FISSION              ");  
00420     break;
00421   case MPF_DISTRIBUTION:
00422     fprintf(fp, "DISTRIBUTION         ");  
00423     break;
00424   case MPF_INTERCHANGE: 
00425     fprintf(fp, "INTERCHANGE          ");  
00426     break;
00427   case MPF_PRE_PEEL: 
00428     fprintf(fp, "PRE-LOOP PEELING     "); 
00429     break; 
00430   case MPF_POST_PEEL: 
00431     fprintf(fp, "POST-LOOP PEELING    "); 
00432     break; 
00433   case MPF_MP_TILE: 
00434     fprintf(fp, "MP TILE              ");
00435     break;
00436   case MPF_DSM_TILE: 
00437     fprintf(fp, "DSM TILE             ");
00438     break;
00439   case MPF_DONEST_OUTER_TILE: 
00440     fprintf(fp, "DONEST OUTER TILE    ");
00441     break;
00442   case MPF_DONEST_MIDDLE_TILE: 
00443     fprintf(fp, "DONEST MIDDLE TILE   ");
00444     break;
00445   case MPF_DSM_LOCAL: 
00446     fprintf(fp, "DSM LOCAL            "); 
00447     break; 
00448   case MPF_DSM_IO: 
00449     fprintf(fp, "DSM IO               "); 
00450     break; 
00451   case MPF_SINGLE_PROCESS: 
00452     fprintf(fp, "SINGLE PROCESS       "); 
00453     break; 
00454   case MPF_MP_VERSION: 
00455     fprintf(fp, "MP VERSION           "); 
00456     break; 
00457   case MPF_PARALLEL_REGION:
00458     fprintf(fp, "PARALLEL REGION      "); 
00459     break; 
00460   case MPF_HOIST_MESSY_BOUNDS: 
00461     fprintf(fp, "HOIST MESSY BOUNDS   ");
00462     break;
00463   case MPF_DOACROSS_SYNC: 
00464     fprintf(fp, "DOACROSS SYNC        "); 
00465     break;
00466   case MPF_DOACROSS_OUTER_TILE: 
00467     fprintf(fp, "DOACROSS OUTER TILE  ");
00468     break;
00469   case MPF_DOACROSS_INNER_TILE: 
00470     fprintf(fp, "DOACROSS INNER TILE  ");
00471     break;
00472   case MPF_REMOVE_UNITY_TRIP: 
00473     fprintf(fp, "REMOVE UNITY TRIP    ");
00474     break;
00475   case MPF_CACHE_WINDDOWN: 
00476     fprintf(fp, "CACHE WINDDOWN       ");
00477     break;
00478   case MPF_INTERLEAVED_WINDDOWN: 
00479     fprintf(fp, "INTERLEAVED WINDDOWN ");
00480     break;
00481   case MPF_GENERAL_VERSION: 
00482     fprintf(fp, "GENERAL VERSION      ");
00483     break;
00484   case MPF_CACHE_TILE: 
00485     fprintf(fp, "CACHE TILE           "); 
00486     break; 
00487   case MPF_REGISTER_WINDDOWN: 
00488     fprintf(fp, "REGISTER WINDDOWN    ");
00489     break;
00490   case MPF_REGISTER_SSTRIP: 
00491     fprintf(fp, "REGISTER SSTRIP      ");
00492     break;
00493   case MPF_REGISTER_TILE: 
00494     fprintf(fp, "REGISTER TILE        ");
00495     break;
00496   case MPF_REGISTER_STARTUP: 
00497     fprintf(fp, "REGISTER STARTUP     ");
00498     break;
00499   case MPF_REGISTER_SHUTDOWN: 
00500     fprintf(fp, "REGISTER SHUTDOWN    ");
00501     break;
00502   case MPF_SE_TILE: 
00503     fprintf(fp, "SE TILE              ");
00504     break;
00505   case MPF_SE_CACHE_TILE: 
00506     fprintf(fp, "SE CACHE TILE        ");
00507     break;
00508   case MPF_INNER_FISSION: 
00509     fprintf(fp, "INNER FISSION        "); 
00510     break; 
00511   case MPF_GATHER_SCATTER: 
00512     fprintf(fp, "GATHER SCATTER       "); 
00513     break; 
00514   case MPF_VINTR_FISSION: 
00515     fprintf(fp, "VINTR FISSION        "); 
00516     break; 
00517   case MPF_PREFETCH_VERSION: 
00518     fprintf(fp, "PREFETCH VERSION     "); 
00519     break; 
00520   case MPF_OMPL_SECTIONS_LOOP: 
00521     fprintf(fp, "OMPL SECTIONS LOOP   "); 
00522     break;
00523   case MPF_OMPL_ELIM_SECTION: 
00524     fprintf(fp, "OMPL ELIM SECTION    "); 
00525     break;
00526   case MPF_OMPL_ATOMIC_CSECTION: 
00527     fprintf(fp, "OMPL ATOMIC CSECTION "); 
00528     break; 
00529   case MPF_OMPL_ATOMIC_SWAP: 
00530     fprintf(fp, "OMPL ATOMIC SWAP     ");
00531     break;
00532   case MPF_OMPL_ATOMIC_FETCHOP: 
00533     fprintf(fp, "OMPL ATOMIC FETCHOP  "); 
00534     break;
00535   case MPF_OMPL_MASTER_IF: 
00536     fprintf(fp, "OMPL MASTER IF       ");
00537     break; 
00538   case MPF_OMPL_FETCHOP_ATOMIC:
00539     fprintf(fp, "OMPL FETCHOP ATOMIC  ");
00540     break;
00541   case MPF_F90_ARRAY_STMT: 
00542     fprintf(fp, "F90 ARRAY STMT       ");
00543     break;
00544   case MPF_OUTER_SHACKLE:
00545     fprintf(fp, "OUTER SHACKLE        ");
00546     break;
00547   case MPF_INNER_SHACKLE:
00548     fprintf(fp, "INNER SHACKLE        ");
00549     break;
00550   case MPF_PREOPT_CREATE: 
00551     fprintf(fp, "PREOPT CREATE        ");
00552     break; 
00553   } 
00554   INT field_count = 0; 
00555   field_count += fprintf(fp, "("); 
00556   INT i;
00557   for (i = 0; i < _old_loops.Elements(); i++) {
00558     field_count += fprintf(fp, "%d", _old_loops.Bottom_nth(i));  
00559     if (i < _old_loops.Elements() - 1)
00560       field_count += fprintf(fp, ",");
00561   } 
00562   field_count += fprintf(fp, ") -> ("); 
00563   for (i = 0; i < _new_loops.Elements(); i++) {
00564     field_count += fprintf(fp, "%d", _new_loops.Bottom_nth(i));  
00565     if (i < _new_loops.Elements() - 1)
00566       field_count += fprintf(fp, ",");
00567   } 
00568   field_count += fprintf(fp, ") "); 
00569   for (i = field_count + 1; i < MIDDLE_FIELD_COUNT; i++) 
00570     fprintf(fp, " "); 
00571   fprintf(fp, "["); 
00572   for (i = 0; i < _prev_loops.Elements(); i++) {
00573     fprintf(fp, "%d", _prev_loops.Bottom_nth(i));
00574     if (i < _prev_loops.Elements() - 1)
00575       fprintf(fp, ",");
00576   } 
00577   fprintf(fp, "] "); 
00578   for (i = 0; i < _old_lines.Elements(); i++) {
00579     _old_lines.Bottom_nth(i)->Print(fp); 
00580     if (i < _old_lines.Elements() - 1)
00581       fprintf(fp, ",");
00582   } 
00583   fprintf(fp, " "); 
00584   for (i = 0; i < _new_lines.Elements(); i++) {
00585     _new_lines.Bottom_nth(i)->Print(fp); 
00586     if (i < _new_lines.Elements() - 1)
00587       fprintf(fp, ",");
00588   } 
00589   fprintf(fp, " "); 
00590   if (_index_name != NULL) 
00591     fprintf(fp, "\"%s\"", _index_name);
00592   fprintf(fp, "\n"); 
00593 }
00594 
00595 //-----------------------------------------------------------------------
00596 // NAME: PROMPF_TRANS::Print_Compact 
00597 // FUNCTION: Print the PROMPF_TRANS in compact form to the file 'fp'.  
00598 //   (This is the form used by the PROMPF anl file.)  
00599 //-----------------------------------------------------------------------
00600 
00601 void PROMPF_TRANS::Print_Compact(FILE* fp)
00602 {
00603   switch (_type) {
00604   case MPF_UNKNOWN: 
00605     fprintf(fp, "UNKNOWN              "); 
00606     break;
00607   case MPF_MARK_OMP: 
00608     fprintf(fp, "MARK OMP             "); 
00609     break;
00610   case MPF_MARK_PREOPT: 
00611     fprintf(fp, "MARK PREOPT          "); 
00612     break;
00613   case MPF_MARK_PRELNO: 
00614     fprintf(fp, "MARK PRELNO          "); 
00615     break;
00616   case MPF_MARK_POSTLNO: 
00617     fprintf(fp, "MARK POSTLNO         "); 
00618     break;
00619   case MPF_ELIMINATION: 
00620     fprintf(fp, "ELIMINATION          ");  
00621     break;
00622   case MPF_FUSION:
00623     fprintf(fp, "FUSION               ");  
00624     break;
00625   case MPF_FISSION:
00626     fprintf(fp, "FISSION              ");  
00627     break;
00628   case MPF_DISTRIBUTION:
00629     fprintf(fp, "DISTRIBUTION         ");  
00630     break;
00631   case MPF_INTERCHANGE: 
00632     fprintf(fp, "INTERCHANGE          ");  
00633     break;
00634   case MPF_PRE_PEEL: 
00635     fprintf(fp, "PRE_LOOP_PEELING     "); 
00636     break; 
00637   case MPF_POST_PEEL: 
00638     fprintf(fp, "POST_LOOP_PEELING    "); 
00639     break; 
00640   case MPF_MP_TILE: 
00641     fprintf(fp, "MP_TILE              ");
00642     break;
00643   case MPF_DSM_TILE: 
00644     fprintf(fp, "DSM_TILE             ");
00645     break;
00646   case MPF_DONEST_OUTER_TILE: 
00647     fprintf(fp, "DONEST_OUTER_TILE    ");
00648     break;
00649   case MPF_DONEST_MIDDLE_TILE: 
00650     fprintf(fp, "DONEST_MIDDLE_TILE   ");
00651     break;
00652   case MPF_DSM_LOCAL: 
00653     fprintf(fp, "DSM_LOCAL            "); 
00654     break; 
00655   case MPF_DSM_IO: 
00656     fprintf(fp, "DSM_IO               "); 
00657     break; 
00658   case MPF_SINGLE_PROCESS: 
00659     fprintf(fp, "SINGLE_PROCESS       "); 
00660     break; 
00661   case MPF_MP_VERSION: 
00662     fprintf(fp, "MP_VERSION           "); 
00663     break; 
00664   case MPF_PARALLEL_REGION: 
00665     fprintf(fp, "PARALLEL_REGION      "); 
00666     break; 
00667   case MPF_HOIST_MESSY_BOUNDS: 
00668     fprintf(fp, "HOIST_MESSY_BOUNDS   ");
00669     break;
00670   case MPF_DOACROSS_SYNC: 
00671     fprintf(fp, "DOACROSS_SYNC        ");
00672     break; 
00673   case MPF_DOACROSS_OUTER_TILE: 
00674     fprintf(fp, "DOACROSS_OUTER_TILE  ");
00675     break; 
00676   case MPF_DOACROSS_INNER_TILE: 
00677     fprintf(fp, "DOACROSS_INNER_TILE  ");
00678     break; 
00679   case MPF_REMOVE_UNITY_TRIP: 
00680     fprintf(fp, "REMOVE_UNITY_TRIP    ");
00681     break;
00682   case MPF_CACHE_WINDDOWN: 
00683     fprintf(fp, "CACHE_WINDDOWN       ");
00684     break;
00685   case MPF_INTERLEAVED_WINDDOWN: 
00686     fprintf(fp, "INTERLEAVED_WINDDOWN ");
00687     break;
00688   case MPF_GENERAL_VERSION: 
00689     fprintf(fp, "GENERAL_VERSION      ");
00690     break;
00691   case MPF_CACHE_TILE: 
00692     fprintf(fp, "CACHE_TILE           "); 
00693     break; 
00694   case MPF_REGISTER_WINDDOWN: 
00695     fprintf(fp, "REGISTER_WINDDOWN    ");
00696     break;
00697   case MPF_REGISTER_SSTRIP: 
00698     fprintf(fp, "REGISTER_SSTRIP      ");
00699     break;
00700   case MPF_REGISTER_TILE: 
00701     fprintf(fp, "REGISTER_TILE        ");
00702     break;
00703   case MPF_REGISTER_STARTUP: 
00704     fprintf(fp, "REGISTER_STARTUP     ");
00705     break;
00706   case MPF_REGISTER_SHUTDOWN: 
00707     fprintf(fp, "REGISTER_SHUTDOWN    ");
00708     break;
00709   case MPF_SE_TILE: 
00710     fprintf(fp, "SE_TILE              ");
00711     break;
00712   case MPF_SE_CACHE_TILE: 
00713     fprintf(fp, "SE_CACHE_TILE        ");
00714     break;
00715   case MPF_INNER_FISSION: 
00716     fprintf(fp, "INNER_FISSION        "); 
00717     break; 
00718   case MPF_GATHER_SCATTER: 
00719     fprintf(fp, "GATHER_SCATTER       "); 
00720     break; 
00721   case MPF_VINTR_FISSION: 
00722     fprintf(fp, "VINTR_FISSION        "); 
00723     break; 
00724   case MPF_PREFETCH_VERSION: 
00725     fprintf(fp, "PREFETCH_VERSION     "); 
00726     break; 
00727   case MPF_OMPL_SECTIONS_LOOP: 
00728     fprintf(fp, "OMPL_SECTIONS_LOOP   "); 
00729     break;
00730   case MPF_OMPL_ELIM_SECTION: 
00731     fprintf(fp, "OMPL_ELIM_SECTION    "); 
00732     break;
00733   case MPF_OMPL_ATOMIC_CSECTION: 
00734     fprintf(fp, "OMPL_ATOMIC_CSECTION "); 
00735     break; 
00736   case MPF_OMPL_ATOMIC_SWAP: 
00737     fprintf(fp, "OMPL_ATOMIC_SWAP     ");
00738     break;
00739   case MPF_OMPL_ATOMIC_FETCHOP: 
00740     fprintf(fp, "OMPL_ATOMIC_FETCHOP  "); 
00741     break;
00742   case MPF_OMPL_MASTER_IF: 
00743     fprintf(fp, "OMPL_MASTER_IF       ");
00744     break; 
00745   case MPF_OMPL_FETCHOP_ATOMIC:
00746     fprintf(fp, "OMPL_FETCHOP_ATOMIC  ");
00747     break;
00748   case MPF_F90_ARRAY_STMT:
00749     fprintf(fp, "F90_ARRAY_STMT       ");
00750     break;
00751   case MPF_OUTER_SHACKLE:
00752     fprintf(fp, "OUTER_SHACKLE        ");
00753     break;
00754   case MPF_INNER_SHACKLE:
00755     fprintf(fp, "INNER_SHACKLE        ");
00756     break;
00757   case MPF_PREOPT_CREATE: 
00758     fprintf(fp, "PREOPT_CREATE        ");
00759     break; 
00760   } 
00761   INT field_count = 0; 
00762   INT i;
00763   for (i = 0; i < _old_loops.Elements(); i++) {
00764     field_count += fprintf(fp, "%d", _old_loops.Bottom_nth(i));  
00765     if (_old_lines.Elements() > 0) {
00766       field_count += fprintf(fp, " ");  
00767       field_count += _old_lines.Bottom_nth(i)->Print_Compact(fp); 
00768     } 
00769     if (i < _old_loops.Elements() - 1)
00770       field_count += fprintf(fp, ",");
00771   } 
00772   if (_old_loops.Elements() > 0)
00773     field_count += fprintf(fp, " "); 
00774   for (i = 0; i < _new_loops.Elements(); i++) {
00775     field_count += fprintf(fp, "%d", _new_loops.Bottom_nth(i));  
00776     if (_new_lines.Elements() > 0) {
00777       field_count += fprintf(fp, " ");  
00778       field_count += _new_lines.Bottom_nth(i)->Print_Compact(fp); 
00779     } 
00780     if (i < _new_loops.Elements() - 1)
00781       field_count += fprintf(fp, ",");
00782   } 
00783   if (_index_name != NULL) 
00784     fprintf(fp, " \"%s\"", _index_name);
00785   field_count += fprintf(fp, "\n"); 
00786 }
00787 
00788 //-----------------------------------------------------------------------
00789 // NAME: PROMPF_ID::Print  
00790 // FUNCTION: Print the PROMPF_ID to the file 'fp'.  
00791 //-----------------------------------------------------------------------
00792 
00793 void PROMPF_ID::Print(FILE* fp, INT entry)
00794 {
00795   switch (_type) {
00796   case MPID_FUNC_ENTRY:
00797     fprintf(fp, "FUNC ENTRY        "); 
00798     break;
00799   case MPID_DO_LOOP:
00800     fprintf(fp, "DO LOOP           "); 
00801     break;
00802   case MPID_PAR_REGION:
00803     fprintf(fp, "PARALLEL REGION   "); 
00804     break;
00805   case MPID_PAR_SECTION:
00806     fprintf(fp, "PARALLEL SECTION  ");
00807     break;
00808   case MPID_SECTION:
00809     fprintf(fp, "SECTION           ");  
00810     break;
00811   case MPID_BARRIER:
00812     fprintf(fp, "BARRIER           ");  
00813     break;
00814   case MPID_SINGLE_PROCESS:
00815     fprintf(fp, "SINGLE PROCESS    ");  
00816     break;
00817   case MPID_CRITICAL_SECTION:
00818     fprintf(fp, "CRITICAL SECTION  ");  
00819     break;
00820   case MPID_MASTER: 
00821     fprintf(fp, "MASTER            "); 
00822     break; 
00823   case MPID_ORDERED: 
00824     fprintf(fp, "ORDERED           "); 
00825     break; 
00826   case MPID_PAR_SECTIONS: 
00827     fprintf(fp, "PARALLEL SECTIONS "); 
00828     break;  
00829   case MPID_ATOMIC: 
00830     fprintf(fp, "ATOMIC            "); 
00831     break;  
00832   default: 
00833     fprintf(fp, "<UNKNOWN>         ");
00834     break; 
00835   } 
00836   fprintf(fp, "%s", _valid ? "OK " : "   ");  
00837   fprintf(fp, "(%d) [%d]\n", entry, _last_trans); 
00838 }
00839 
00840 //-----------------------------------------------------------------------
00841 // NAME: PROMPF_INFO::Add_Trans 
00842 // FUNCTION: Add the transaction 'pt' to the PROMPF_INFO's transaction 
00843 //   list, assigning values to its Prev_Loop() fields.  
00844 //-----------------------------------------------------------------------
00845 
00846 void PROMPF_INFO::Add_Trans(PROMPF_TRANS* pt)
00847 {
00848   INT j;
00849   for (j = 0; j < pt->Old_Loop_Count(); j++) {
00850     INT old_loop = pt->Old_Loop(j); 
00851     INT i;
00852     for (i = Last_Trans(); i >= 0; i--) {
00853       PROMPF_TRANS* ptt = Trans(i); 
00854       INT k;
00855       for (k = 0; k < ptt->New_Loop_Count(); k++) 
00856         if (ptt->New_Loop(k) == old_loop) 
00857            break;
00858       if (k < ptt->New_Loop_Count()) {
00859         pt->Add_Prev_Loop(i);  
00860         break; 
00861       }
00862     }
00863     if (i == -1) 
00864       pt->Add_Prev_Loop(-1); 
00865   } 
00866   _trans_stack.Push(pt); 
00867 }
00868 
00869 //-----------------------------------------------------------------------
00870 // NAME: PROMPF_INFO::Remove_Trans 
00871 // FUNCTION: Remove the last transaction from the transaction list.
00872 //-----------------------------------------------------------------------
00873 
00874 PROMPF_TRANS* PROMPF_INFO::Remove_Trans()
00875 {
00876   return _trans_stack.Pop();
00877 } 
00878 
00879 //-----------------------------------------------------------------------
00880 // NAME: Is_Grandparent_Region
00881 // FUNCTION: Returns TRUE if 'wn_node' is a child of the WN_region_body 
00882 //   of the OPC_REGION node 'wn_region'; returns FALSE otherwise.  
00883 //-----------------------------------------------------------------------
00884 
00885 static BOOL Is_Grandparent_Region(WN* wn_node, 
00886                                   WN* wn_region)
00887 { 
00888   if (wn_region == NULL)
00889     return FALSE; 
00890   FmtAssert(WN_opcode(wn_region) == OPC_REGION, 
00891     ("Is_Grandparent_Region: Expected a OPC_REGION")); 
00892   WN* wn_first = WN_first(WN_region_body(wn_region)); 
00893   for (WN* wn = wn_first; wn != NULL; wn = WN_next(wn)) 
00894     if (wn == wn_node) 
00895       return TRUE; 
00896   return FALSE; 
00897 } 
00898 
00899 //-----------------------------------------------------------------------
00900 // NAME: Prompf_Id_Type 
00901 // FUNCTION: Returns the PROMPF_ID_TYPE corresponding to the node 'wn_ref'.
00902 //   Returns MPID_UNKNOWN if this node is not one for which we should 
00903 //   construct a PROMPF_ID.  Returns TRUE in 'is_first' if 'wn' should be
00904 //   the first node with its PROMP map id, FALSE otherwise.  The 'wn_region'
00905 //   is the closest enclosing OPC_REGION node, if there is one. 
00906 //-----------------------------------------------------------------------
00907 
00908 extern PROMPF_ID_TYPE Prompf_Id_Type(WN* wn_ref,
00909                                      WN* wn_region, 
00910                                      BOOL* is_first)
00911 {
00912   if (is_first != NULL) 
00913     *is_first = TRUE; 
00914   OPCODE opc = WN_opcode(wn_ref); 
00915   if (opc == OPC_FUNC_ENTRY) 
00916     return MPID_FUNC_ENTRY; 
00917   if (opc == OPC_REGION) { 
00918     WN* wn_pragma = WN_first(WN_region_pragmas(wn_ref)); 
00919     if (wn_pragma != NULL && WN_opcode(wn_pragma) == OPC_PRAGMA) {
00920       switch (WN_pragma(wn_pragma)) { 
00921       case WN_PRAGMA_DOACROSS:
00922       case WN_PRAGMA_PARALLEL_DO:
00923       case WN_PRAGMA_PDO_BEGIN: 
00924         if (WN_pragma_arg1(wn_pragma) == 0)
00925           return MPID_DO_LOOP; 
00926         break; 
00927       case WN_PRAGMA_PARALLEL_BEGIN: 
00928         return MPID_PAR_REGION; 
00929       case WN_PRAGMA_PSECTION_BEGIN: 
00930         return MPID_PAR_SECTION; 
00931       case WN_PRAGMA_SINGLE_PROCESS_BEGIN: 
00932         return MPID_SINGLE_PROCESS; 
00933       case WN_PRAGMA_MASTER_BEGIN: 
00934         return MPID_MASTER; 
00935       case WN_PRAGMA_PARALLEL_SECTIONS: 
00936         return MPID_PAR_SECTIONS; 
00937       }
00938     }
00939   }     
00940   if (opc == OPC_DO_LOOP) {
00941     if (Is_Grandparent_Region(wn_ref, wn_region)) { 
00942       WN* wn_pragma = WN_first(WN_region_pragmas(wn_region));
00943       if (wn_pragma != NULL && WN_opcode(wn_pragma) == OPC_PRAGMA) {
00944         switch (WN_pragma(wn_pragma)) {
00945         case WN_PRAGMA_DOACROSS:
00946         case WN_PRAGMA_PARALLEL_DO:
00947         case WN_PRAGMA_PDO_BEGIN:
00948           if (WN_pragma_arg1(wn_pragma) == 0)
00949             if (is_first != NULL) 
00950               *is_first = FALSE; 
00951         }
00952       }
00953     }
00954     return MPID_DO_LOOP;
00955   }   
00956   if (opc == OPC_PRAGMA || opc == OPC_XPRAGMA) {
00957     switch (WN_pragma(wn_ref)) {
00958     case WN_PRAGMA_PARALLEL_BEGIN:
00959       if (is_first != NULL)
00960         *is_first = FALSE;
00961       return MPID_PAR_REGION;
00962     case WN_PRAGMA_PSECTION_BEGIN:
00963       if (is_first != NULL)
00964         *is_first = FALSE;
00965       return MPID_PAR_SECTION;
00966     case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
00967       if (is_first != NULL)
00968         *is_first = FALSE;
00969       return MPID_SINGLE_PROCESS;
00970     case WN_PRAGMA_MASTER_BEGIN:
00971       if (is_first != NULL)
00972         *is_first = FALSE;
00973       return MPID_MASTER;
00974     case WN_PRAGMA_PARALLEL_SECTIONS:
00975       if (is_first != NULL)
00976         *is_first = FALSE;
00977       return MPID_PAR_SECTIONS; 
00978     case WN_PRAGMA_SECTION:
00979       return MPID_PAR_SECTION;
00980     case WN_PRAGMA_BARRIER:
00981       return MPID_BARRIER;
00982     case WN_PRAGMA_CRITICAL_SECTION_BEGIN:
00983       return MPID_CRITICAL_SECTION;
00984     case WN_PRAGMA_CRITICAL_SECTION_END:
00985       if (is_first != NULL)
00986         *is_first = FALSE;
00987       return MPID_CRITICAL_SECTION;
00988     case WN_PRAGMA_ORDERED_BEGIN:
00989       return MPID_ORDERED;
00990     case WN_PRAGMA_ORDERED_END:
00991       if (is_first != NULL)
00992         *is_first = FALSE;
00993       return MPID_ORDERED;
00994     case WN_PRAGMA_ATOMIC: 
00995       return MPID_ATOMIC; 
00996     } 
00997   } 
00998   return MPID_UNKNOWN; 
00999 }  
01000 
01001 //-----------------------------------------------------------------------
01002 // NAME: Whirl_Symbol_Type
01003 // FUNCTION: Returns a pointer to a printable string of characters
01004 //   describing the symbol of the node 'wn'.  For loads and stores,
01005 //   the symbol is printed, if any.  For do loops, the symbol of the
01006 //   do loop is printed.  For nodes with no symbol information, the
01007 //   type is printed.
01008 //-----------------------------------------------------------------------
01009 
01010 static const char* Whirl_Symbol_Type(WN* wn)
01011 {
01012   WN* wn_symbol = NULL;
01013   OPCODE opc = WN_opcode(wn);
01014   OPERATOR opr = OPCODE_operator(opc);
01015   if (opc == OPC_PRAGMA || opc == OPC_XPRAGMA)
01016     return WN_pragmas[WN_pragma(wn)].name;
01017   wn_symbol = (opc == OPC_DO_LOOP) ? WN_index(wn) : (OPCODE_has_sym(opc))
01018     ? wn : NULL;
01019   if (wn_symbol == NULL)
01020     return (char *) (OPCODE_name(WN_opcode(wn)) + 4);
01021 
01022   const ST* st = WN_st(wn_symbol);
01023   if (st == NULL)
01024       return NULL;
01025 
01026   if (ST_class (st) != CLASS_PREG)
01027       return ST_name (st);
01028   else if (WN_offset(wn_symbol) > Last_Dedicated_Preg_Offset)
01029       return Preg_Name(WN_offset(wn_symbol));
01030   else
01031       return "DEDICATED PREG";
01032 }
01033 
01034 //-----------------------------------------------------------------------
01035 // NAME: PROMPF_INFO::Prompf_Info_Traverse
01036 // FUNCTION: Traverses the 'wn_tree' which is enclosed by the region 
01037 //   'wn_region' and records the PROMPF ids in the PROMPF_INFO.  
01038 //-----------------------------------------------------------------------
01039 
01040 void PROMPF_INFO::Prompf_Info_Traverse(WN* wn_tree,
01041                                        WN* wn_region)
01042 { 
01043   INT32 map_id = WN_MAP32_Get(Prompf_Id_Map, wn_tree);
01044   BOOL is_first = FALSE; 
01045   PROMPF_ID_TYPE pit = Prompf_Id_Type(wn_tree, wn_region, &is_first); 
01046   if (map_id != 0) {
01047     INT i;
01048     for (i = Last_Id() + 1; i < map_id; i++) { 
01049       Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, FALSE, Last_Trans(), _pool), 
01050         _pool)); 
01051     } 
01052     if (is_first) {
01053       Add_Id(CXX_NEW(PROMPF_ID(pit, TRUE, -1, _pool), _pool)); 
01054       FmtAssert(map_id == Last_Id(), 
01055         ("PROMPF_INFO: Prompf map ids not assigned consecutively")); 
01056     } else {
01057       FmtAssert(map_id <= Last_Id() && Id(map_id)->Is_Valid(), 
01058         ("PROMPF_INFO: Expected id %d to be already in table", map_id)); 
01059     }  
01060   } else if (pit != MPID_UNKNOWN) {
01061     DevWarn("Missing Prompf Id for 0x%p %s", wn_tree, 
01062       Whirl_Symbol_Type(wn_tree)); 
01063   }
01064 
01065   if (WN_opcode(wn_tree) == OPC_BLOCK) { 
01066     for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))  
01067       Prompf_Info_Traverse(wn, wn_region); 
01068   } else if (WN_opcode(wn_tree) == OPC_REGION) { 
01069     INT i;
01070     for (i = 0; i < WN_kid_count(wn_tree); i++) 
01071       Prompf_Info_Traverse(WN_kid(wn_tree, i), wn_tree); 
01072   } else { 
01073     INT i;
01074     for (i = 0; i < WN_kid_count(wn_tree); i++) 
01075       Prompf_Info_Traverse(WN_kid(wn_tree, i), wn_region); 
01076   } 
01077 } 
01078 
01079 //-----------------------------------------------------------------------
01080 // NAME: PROMPF_INFO::PROMPF_INFO 
01081 // FUNCTION: Create a PROMPF_INFO for the function rooted at 'wn_func' 
01082 //   using memory from the 'pool'.  
01083 //-----------------------------------------------------------------------
01084 
01085 PROMPF_INFO::PROMPF_INFO(WN* wn_func, MEM_POOL* pool):
01086   _pool(pool), 
01087   _enabled(FALSE), 
01088   _first_id(WN_MAP32_Get(Prompf_Id_Map, wn_func)), 
01089   _trans_stack(pool), 
01090   _id_stack(pool),
01091   _trans_checkpoint(-1)
01092 {
01093   _trans_stack.Clear(); 
01094   _id_stack.Clear(); 
01095   Prompf_Info_Traverse(wn_func, NULL); 
01096   INT i;
01097   for (i = Last_Id() + 1; i < Get_Next_Construct_Id(); i++) {
01098     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, FALSE, Last_Trans(), _pool), 
01099       _pool)); 
01100   }
01101 }
01102 
01103 //-----------------------------------------------------------------------
01104 // NAME: PROMPF_INFO::Check_Old_Ids 
01105 // FUNCTION: Return TRUE if each the 'new_ids' array is a permutation of
01106 //   the 'old_ids' array, FALSE otherwise.  Both of these arrays have 
01107 //   'nloops' elements. 
01108 //-----------------------------------------------------------------------
01109 
01110 BOOL PROMPF_INFO::Check_Old_Ids(INT old_ids[], 
01111                                 INT new_ids[],
01112                                 INT nloops)
01113 {
01114   INT i;
01115   for (i = 0; i < nloops; i++) {
01116     INT j;
01117     for (j = 0; j < nloops; j++) 
01118       if (old_ids[i] == new_ids[j])
01119         break; 
01120     if (j == nloops) 
01121       return FALSE; 
01122   } 
01123   return TRUE; 
01124 }
01125 
01126 //-----------------------------------------------------------------------
01127 // NAME: PROMPF_INFO::Check_New_Ids 
01128 // FUNCTION: Returns TRUE if the 'nloops' values in the array 'new_ids'  
01129 //   are the next 'nloops' id values to be assigned.  Return FALSE 
01130 //   otherwise. 
01131 //-----------------------------------------------------------------------
01132 
01133 BOOL PROMPF_INFO::Check_New_Ids(INT new_ids[], 
01134                                 INT nloops) 
01135 {
01136   INT last_id = Last_Id();  
01137   INT i;
01138   for (i = last_id + 1; i <= last_id + nloops; i++) { 
01139     INT j;
01140     for (j = 0; j < nloops; j++) 
01141       if (new_ids[j] == i) 
01142         break; 
01143     if (j == nloops) 
01144       return FALSE; 
01145   } 
01146   return TRUE; 
01147 }     
01148 
01149 //-----------------------------------------------------------------------
01150 // NAME: PROMPF_INFO::Mark_F90_Lower
01151 // FUNCTION: Indicate that we are about to record transformations from 
01152 //   F90 lowering. 
01153 //-----------------------------------------------------------------------
01154 
01155 void PROMPF_INFO::Mark_F90_Lower()
01156 { 
01157   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01158   pt->Set_Type(MPF_MARK_F90_LOWER); 
01159   Add_Trans(pt); 
01160 } 
01161 
01162 //-----------------------------------------------------------------------
01163 // NAME: PROMPF_INFO::Mark_Omp
01164 // FUNCTION: Indicate that we are about to record transformations from 
01165 //   OMP prelowering. 
01166 //-----------------------------------------------------------------------
01167 
01168 void PROMPF_INFO::Mark_Omp()
01169 { 
01170   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01171   pt->Set_Type(MPF_MARK_OMP); 
01172   Add_Trans(pt); 
01173 } 
01174 
01175 //-----------------------------------------------------------------------
01176 // NAME: PROMPF_INFO::Mark_Preopt
01177 // FUNCTION: Indicate that we are about to record transformations from 
01178 //   the preoptimizer. 
01179 //-----------------------------------------------------------------------
01180 
01181 void PROMPF_INFO::Mark_Preopt()
01182 { 
01183   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01184   pt->Set_Type(MPF_MARK_PREOPT); 
01185   Add_Trans(pt); 
01186 } 
01187 
01188 //-----------------------------------------------------------------------
01189 // NAME: PROMPF_INFO::Mark_Prelno 
01190 // FUNCTION: Indicate that we are about to record transformations from 
01191 //   LNO before and including parallelization. 
01192 //-----------------------------------------------------------------------
01193 
01194 void PROMPF_INFO::Mark_Prelno()
01195 { 
01196   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01197   pt->Set_Type(MPF_MARK_PRELNO); 
01198   Add_Trans(pt); 
01199 } 
01200 
01201 //-----------------------------------------------------------------------
01202 // NAME: PROMPF_INFO::Mark_Postlno 
01203 // FUNCTION: Indicate that we are about to record transformations from 
01204 //   LNO after parallelization.
01205 //-----------------------------------------------------------------------
01206 
01207 void PROMPF_INFO::Mark_Postlno()
01208 { 
01209   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01210   pt->Set_Type(MPF_MARK_POSTLNO); 
01211   Add_Trans(pt); 
01212 } 
01213 
01214 //-----------------------------------------------------------------------
01215 // NAME: PROMPF_INFO::Elimination 
01216 // FUNCTION: Indicate that the construct with the id 'old_loop' has been 
01217 //   eliminated from the program.  
01218 //-----------------------------------------------------------------------
01219 
01220 void PROMPF_INFO::Elimination(INT old_loop) 
01221 {
01222   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool); 
01223   pt->Set_Type(MPF_ELIMINATION); 
01224   pt->Add_Old_Loop(old_loop); 
01225   Add_Trans(pt); 
01226   Id(old_loop)->Set_Last_Trans(Last_Trans());
01227   Id(old_loop)->Invalidate();
01228 } 
01229 
01230 //-----------------------------------------------------------------------
01231 // NAME: PROMPF_INFO::Undo_Elimination
01232 // FUNCTION: Undo the last transformation, which must be an elimination.
01233 //-----------------------------------------------------------------------
01234 
01235 void PROMPF_INFO::Undo_Elimination()
01236 {
01237   PROMPF_TRANS* pt = Remove_Trans();
01238   FmtAssert(pt->Type() == MPF_ELIMINATION,
01239     ("Undo_Elimination: Expected last transaction to be MPF_ELIMINATION"));
01240   Id(pt->Old_Loop(0))->Validate();
01241   Reset_Last_Trans(pt->Old_Loop(0));
01242 } 
01243 
01244 //-----------------------------------------------------------------------
01245 // NAME: PROMPF_INFO::Fusion 
01246 // FUNCTION: Indicate that the two loops with ids given in 'old_loops'
01247 //   have been fused into the single loop with id 'new_loop'.   
01248 //-----------------------------------------------------------------------
01249 
01250 void PROMPF_INFO::Fusion(INT old_loops[],
01251                          INT new_loop)
01252 {
01253   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01254   pt->Set_Type(MPF_FUSION);
01255   INT i;
01256   for (i = 0; i < 2; i++) 
01257     pt->Add_Old_Loop(old_loops[i]); 
01258   pt->Add_New_Loop(new_loop); 
01259   Add_Trans(pt);
01260   Update_Id(new_loop, Last_Trans()); 
01261   for (i = 0; i < 2; i++) {
01262     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01263     if (old_loops[i] != new_loop) 
01264       Id(old_loops[i])->Invalidate(); 
01265   }
01266 } 
01267 
01268 void PROMPF_INFO::Reset_Last_Trans(INT old_id)
01269 {
01270   INT previous_trans = -1; 
01271   INT j;
01272   for (j = Last_Trans() - 1; j >= 0; j--) { 
01273     PROMPF_TRANS* ptt = Trans(j); 
01274     INT k;
01275     for (k = 0; k < ptt->Old_Loop_Count(); k++)  
01276       if (ptt->Old_Loop(k) == old_id)
01277         break; 
01278     if (k < ptt->Old_Loop_Count()) {
01279       previous_trans = k; 
01280       break; 
01281     } 
01282     for (k = 0; k < ptt->New_Loop_Count(); k++)  
01283       if (ptt->New_Loop(k) == old_id)
01284         break; 
01285     if (k < ptt->New_Loop_Count()) {
01286       previous_trans = k;
01287       break;
01288     } 
01289   }
01290   Id(old_id)->Set_Last_Trans(previous_trans);
01291 } 
01292 
01293 //-----------------------------------------------------------------------
01294 // NAME: PROMPF_INFO::Undo_Fusion
01295 // FUNCTION: Undo the last transformation, which must be a fusion. 
01296 //-----------------------------------------------------------------------
01297 
01298 void PROMPF_INFO::Undo_Fusion()
01299 {
01300   PROMPF_TRANS* pt = Remove_Trans();
01301   FmtAssert(pt->Type() == MPF_FUSION, 
01302     ("Undo_fusion: Expected last transaction to be MPF_FUSION"));
01303   INT new_loop = pt->New_Loop(0);
01304   INT i;
01305   for (i = 0; i < pt->Old_Loop_Count(); i++) 
01306     if (pt->Old_Loop(i) != new_loop) 
01307       Id(pt->Old_Loop(i))->Validate();
01308   for (i = 0; i < pt->Old_Loop_Count(); i++)  
01309     Reset_Last_Trans(pt->Old_Loop(i));
01310 }  
01311 
01312 //-----------------------------------------------------------------------
01313 // NAME: PROMPF_INFO::Fission 
01314 // FUNCTION: Indicate that the 'nloops' deep nest of loops with ids in 
01315 //   'old_loops' have been fissioned to produce 'nloops' new loops, 
01316 //   whose ids are given in 'new_loops'. 
01317 //-----------------------------------------------------------------------
01318 
01319 void PROMPF_INFO::Fission(INT old_loops[], 
01320                           PROMPF_LINES* old_lines[], 
01321                           INT new_loops[], 
01322                           PROMPF_LINES* new_lines[], 
01323                           INT nloops)
01324 {
01325   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01326   pt->Set_Type(MPF_FISSION);
01327   INT i;
01328   for (i = 0; i < nloops; i++) {
01329     pt->Add_Old_Loop(old_loops[i]);
01330     pt->Add_Old_Lines(old_lines[i]); 
01331     pt->Add_New_Loop(new_loops[i]); 
01332     pt->Add_New_Lines(new_lines[i]); 
01333   } 
01334   Add_Trans(pt); 
01335   Check_New_Ids(new_loops, nloops); 
01336   for (i = 0; i < nloops; i++) 
01337     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01338       _pool));
01339   for (i = 0; i < nloops; i++)
01340     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01341   for (i = 0; i < nloops; i++)
01342     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01343 }
01344 
01345 //-----------------------------------------------------------------------
01346 // NAME: PROMPF_INFO::Distribution 
01347 // FUNCTION: Indicate that the 'nloops' deep nest of loops with ids in 
01348 //   'old_loops' have been distributed to produce 'nloops' new loops, 
01349 //   whose ids are given in 'new_loops'. 
01350 //-----------------------------------------------------------------------
01351 
01352 void PROMPF_INFO::Distribution(INT old_loops[], 
01353                                PROMPF_LINES* old_lines[], 
01354                                INT new_loops[], 
01355                                PROMPF_LINES* new_lines[], 
01356                                INT nloops)
01357 {
01358   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01359   pt->Set_Type(MPF_DISTRIBUTION); 
01360   INT i;
01361   for (i = 0; i < nloops; i++) {
01362     pt->Add_Old_Loop(old_loops[i]);
01363     pt->Add_Old_Lines(old_lines[i]); 
01364     pt->Add_New_Loop(new_loops[i]); 
01365     pt->Add_New_Lines(new_lines[i]); 
01366   } 
01367   Add_Trans(pt); 
01368   Check_New_Ids(new_loops, nloops); 
01369   for (i = 0; i < nloops; i++) 
01370     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01371       _pool)); 
01372   for (i = 0; i < nloops; i++)
01373     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01374   for (i = 0; i < nloops; i++)
01375     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01376 }
01377 
01378 //-----------------------------------------------------------------------
01379 // NAME: PROMPF_INFO::Interchange 
01380 // FUNCTION: Indicate that the 'nloops' deep nest of loops whose ids are
01381 //   given by 'old_loops' have been interchanged to the order given by 
01382 //   'new_loops'. 
01383 //-----------------------------------------------------------------------
01384 
01385 void PROMPF_INFO::Interchange(INT old_loops[], 
01386                               INT new_loops[], 
01387                               INT nloops)
01388 {
01389   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01390   pt->Set_Type(MPF_INTERCHANGE); 
01391   INT i;
01392   for (i = 0; i < nloops; i++)
01393     pt->Add_Old_Loop(old_loops[i]);
01394   for (i = 0; i < nloops; i++)
01395     pt->Add_New_Loop(new_loops[i]);
01396   Add_Trans(pt);
01397   for (i = 0; i < nloops; i++) 
01398     Update_Id(new_loops[i], Last_Trans());  
01399   for (i = 0; i < nloops; i++)
01400     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01401 }
01402 
01403 //-----------------------------------------------------------------------
01404 // NAME: PROMPF_INFO::Pre_Peel 
01405 // FUNCTION: Indicate that the 'nloops' new loops, whose ids are given 
01406 //   in 'new_loops' have been created from the 'nloops' old loops, whose
01407 //   ids are given by 'old_loops', by peeling off one or more iterations
01408 //   of a loop and placing those iterations before the loop.  
01409 //-----------------------------------------------------------------------
01410 
01411 void PROMPF_INFO::Pre_Peel(INT old_loops[], 
01412                            INT new_loops[], 
01413                            INT nloops)
01414 {
01415   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01416   pt->Set_Type(MPF_PRE_PEEL);
01417   INT i;
01418   for (i = 0; i < nloops; i++)
01419     pt->Add_Old_Loop(old_loops[i]);
01420   for (i = 0; i < nloops; i++)
01421     pt->Add_New_Loop(new_loops[i]);
01422   Add_Trans(pt);
01423   Check_New_Ids(new_loops, nloops); 
01424   for (i = 0; i < nloops; i++) 
01425     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01426       _pool)); 
01427   for (i = 0; i < nloops; i++)
01428     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01429   for (i = 0; i < nloops; i++)
01430     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01431 }
01432 
01433 //-----------------------------------------------------------------------
01434 // NAME: PROMPF_INFO::Undo_Pre_Peel
01435 // FUNCTION: Undo the last transformation, which must be a pre loop peeling. 
01436 //-----------------------------------------------------------------------
01437 
01438 void PROMPF_INFO::Undo_Pre_Peel()
01439 {
01440   PROMPF_TRANS* pt = Remove_Trans();
01441   FmtAssert(pt->Type() == MPF_PRE_PEEL,
01442     ("Undo_Pre_Peel: Expected last transaction to be MPF_PRE_PEEL"));
01443   INT i;
01444   for (i = 0; i < pt->New_Loop_Count(); i++)
01445     Remove_Id();
01446   for (i = 0; i < pt->Old_Loop_Count(); i++) 
01447     Reset_Last_Trans(pt->Old_Loop(i));
01448 } 
01449 
01450 //-----------------------------------------------------------------------
01451 // NAME: PROMPF_INFO::Post_Peel 
01452 // FUNCTION: Indicate that the 'nloops' new loops, whose ids are given 
01453 //   in 'new_loops' have been created from the 'nloops' old loops, whose
01454 //   ids are given by 'old_loops', by peeling off one or more iterations
01455 //   of a loop and placing those iterations after the loop.  
01456 //-----------------------------------------------------------------------
01457 
01458 void PROMPF_INFO::Post_Peel(INT old_loops[], 
01459                             INT new_loops[], 
01460                             INT nloops)
01461 {
01462   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01463   pt->Set_Type(MPF_POST_PEEL);
01464   INT i;
01465   for (i = 0; i < nloops; i++)
01466     pt->Add_Old_Loop(old_loops[i]);
01467   for (i = 0; i < nloops; i++)
01468     pt->Add_New_Loop(new_loops[i]);
01469   Add_Trans(pt);
01470   Check_New_Ids(new_loops, nloops); 
01471   for (i = 0; i < nloops; i++) 
01472     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01473       _pool)); 
01474   for (i = 0; i < nloops; i++)
01475     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01476   for (i = 0; i < nloops; i++)
01477     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01478 }
01479 
01480 //-----------------------------------------------------------------------
01481 // NAME: PROMPF_INFO::Undo_Post_Peel
01482 // FUNCTION: Undo the last transformation, which must be a post loop peeling. 
01483 //-----------------------------------------------------------------------
01484 
01485 void PROMPF_INFO::Undo_Post_Peel()
01486 {
01487   PROMPF_TRANS* pt = Remove_Trans();
01488   FmtAssert(pt->Type() == MPF_POST_PEEL,
01489     ("Undo_Post_Peel: Expected last transaction to be MPF_POST_PEEL"));
01490   INT i;
01491   for (i = 0; i < pt->New_Loop_Count(); i++)
01492     Remove_Id();
01493   for (i = 0; i < pt->Old_Loop_Count(); i++) 
01494     Reset_Last_Trans(pt->Old_Loop(i));
01495 } 
01496 
01497 
01498 //-----------------------------------------------------------------------
01499 // NAME: PROMPF_INFO::Mp_Tile  
01500 // FUNCTION: Indicate that the 'nloops' new loops with ids in 'new_loops' 
01501 //   have been created form the loop with id 'old_loop' by mp tiling.   
01502 //-----------------------------------------------------------------------
01503 
01504 void PROMPF_INFO::Mp_Tile(INT old_loop,
01505                           INT new_loops[], 
01506                           INT nloops)
01507 {
01508   FmtAssert(nloops == 1 || nloops == 2, 
01509     ("PROMPF_INFO::Mp_Tile: Only support 2D and 3D MP Tiling"));  
01510   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01511   pt->Set_Type(MPF_MP_TILE); 
01512   pt->Add_Old_Loop(old_loop); 
01513   INT i;
01514   for (i = 0; i < nloops; i++) 
01515     pt->Add_New_Loop(new_loops[i]); 
01516   Add_Trans(pt); 
01517   Check_New_Ids(new_loops, nloops); 
01518   for (i = 0; i < nloops; i++)
01519     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01520       _pool));
01521   Id(old_loop)->Set_Last_Trans(Last_Trans());
01522   for (i = 0; i < nloops; i++)
01523     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01524 } 
01525    
01526 //-----------------------------------------------------------------------
01527 // NAME: PROMPF_INFO::Dsm_Tile  
01528 // FUNCTION: Indicate that the 'nloops' new loops with ids in 'new_loops' 
01529 //   have been created form the loop with id 'old_loop' by mp tiling.   
01530 //-----------------------------------------------------------------------
01531 
01532 void PROMPF_INFO::Dsm_Tile(INT old_loop,
01533                            INT new_loops[], 
01534                            INT nloops)
01535 {
01536   FmtAssert(nloops == 1 || nloops == 2, 
01537     ("PROMPF_INFO::Mp_Tile: Only support 2D and 3D MP Tiling"));  
01538   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01539   pt->Set_Type(MPF_DSM_TILE); 
01540   pt->Add_Old_Loop(old_loop); 
01541   INT i;
01542   for (i = 0; i < nloops; i++) 
01543     pt->Add_New_Loop(new_loops[i]); 
01544   Add_Trans(pt); 
01545   Check_New_Ids(new_loops, nloops); 
01546   for (i = 0; i < nloops; i++)
01547     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01548       _pool));
01549   Id(old_loop)->Set_Last_Trans(Last_Trans());
01550   for (i = 0; i < nloops; i++)
01551     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01552 } 
01553 
01554 //-----------------------------------------------------------------------
01555 // NAME: PROMPF_INFO::Donest_Outer_Tile  
01556 // FUNCTION: Indicate that the 'nloops' old loops whose ids are in 'old_
01557 //   loops' are converted to a single doacross and the new loop whose id
01558 //   is 'new_loop' is created to be the new single doacross loop.
01559 //-----------------------------------------------------------------------
01560 
01561 void PROMPF_INFO::Donest_Outer_Tile(INT old_loops[], 
01562                                     INT new_loop, 
01563                                     INT nloops)
01564 {
01565   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01566   pt->Set_Type(MPF_DONEST_OUTER_TILE); 
01567   INT i;
01568   for (i = 0; i < nloops; i++)
01569     pt->Add_Old_Loop(old_loops[i]);
01570   pt->Add_New_Loop(new_loop);
01571   Add_Trans(pt); 
01572   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01573   for (i = 0; i < nloops; i++)
01574     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01575   Id(new_loop)->Set_Last_Trans(Last_Trans());
01576 }
01577    
01578 //-----------------------------------------------------------------------
01579 // NAME: PROMPF_INFO::Donest_Middle_Tile 
01580 // FUNCTION: Indicate that the loop whose id is 'old_loop' has been          
01581 //   stripped into a 3D loop, and that a new loop has been created 
01582 //   for the middle of the three loops, whose id is 'new_loop'.
01583 //   loops' are converted to a single doacross and the new loop whose id
01584 //   is 'new_loop' is created to be the new single doacross loop.
01585 //-----------------------------------------------------------------------
01586 
01587 void PROMPF_INFO::Donest_Middle_Tile(INT old_loop, 
01588                                      INT new_loop) 
01589 {
01590   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01591   pt->Set_Type(MPF_DONEST_MIDDLE_TILE);
01592   pt->Add_Old_Loop(old_loop);
01593   pt->Add_New_Loop(new_loop);
01594   Add_Trans(pt); 
01595   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01596   Id(old_loop)->Set_Last_Trans(Last_Trans());
01597   Id(new_loop)->Set_Last_Trans(Last_Trans());
01598 }
01599    
01600 //-----------------------------------------------------------------------
01601 // NAME: PROMPF_INFO::Dsm_Local 
01602 // FUNCTION: Indicate that the loop with id 'new_loop' has been created 
01603 //   to copy back a temporary array to a lego reshaped array which was 
01604 //   named in a LASTLOCAL clause.  The line numbers of the region on  
01605 //   which the LASTLOCAL call appears are contained in 'pl'. 
01606 //-----------------------------------------------------------------------
01607 
01608 void PROMPF_INFO::Dsm_Local(INT new_loop, 
01609                             PROMPF_LINES* pl,
01610                             char* index_name) 
01611 {
01612   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01613   pt->Set_Type(MPF_DSM_LOCAL); 
01614   pt->Add_New_Loop(new_loop);
01615   pt->Add_New_Lines(pl); 
01616   pt->Add_Index_Name(index_name);
01617   Add_Trans(pt);
01618   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01619   Id(new_loop)->Set_Last_Trans(Last_Trans());
01620 }
01621 
01622 //-----------------------------------------------------------------------
01623 // NAME: PROMPF_INFO::Dsm_Io 
01624 // FUNCTION: Indicate that the loop with id 'new_loop' has been created 
01625 //   during an optimization of IO on lego (reshaped) arrays.  The loop has
01626 //   been created for the IO statement on line 'linenum'. 
01627 //-----------------------------------------------------------------------
01628 
01629 void PROMPF_INFO::Dsm_Io(INT new_loop, 
01630                          INT linenum,
01631                          char* index_name) 
01632 {
01633   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01634   pt->Set_Type(MPF_DSM_IO); 
01635   pt->Add_New_Loop(new_loop);
01636   PROMPF_LINES* pl =  CXX_NEW(PROMPF_LINES(_pool), _pool); 
01637   pl->Add_Line(linenum); 
01638   pt->Add_New_Lines(pl); 
01639   pt->Add_Index_Name(index_name);
01640   Add_Trans(pt);
01641   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01642   Id(new_loop)->Set_Last_Trans(Last_Trans());
01643 }
01644 
01645 //-----------------------------------------------------------------------
01646 // NAME: PROMPF_INFO::Single_Process
01647 // FUNCTION: Indicate that the single process with id 'new_loop' has been 
01648 //   created.  
01649 //-----------------------------------------------------------------------
01650 
01651 void PROMPF_INFO::Single_Process(INT new_loop, 
01652                                  PROMPF_LINES* pl)
01653 {
01654   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01655   pt->Set_Type(MPF_SINGLE_PROCESS); 
01656   pt->Add_New_Loop(new_loop);
01657   pt->Add_New_Lines(pl); 
01658   Add_Trans(pt);
01659   Add_Id(CXX_NEW(PROMPF_ID(MPID_SINGLE_PROCESS, TRUE, Last_Trans(), _pool),  
01660     _pool));
01661   Id(new_loop)->Set_Last_Trans(Last_Trans());
01662 }
01663 
01664 //-----------------------------------------------------------------------
01665 // NAME: PROMPF_INFO::Mp_Version 
01666 // FUNCTION: Indicate that the 'nloops' new loops, whose ids are given 
01667 //   in 'new_loops' have been created from the 'nloops' old loops, whose
01668 //   ids are given by 'old_loops', by versioning a doacross loop or par- 
01669 //   allel region into serial and parallel versions.  
01670 //-----------------------------------------------------------------------
01671 
01672 void PROMPF_INFO::Mp_Version(INT old_loops[], 
01673                              INT new_loops[], 
01674                              PROMPF_ID_TYPE id_type[], 
01675                              INT nloops)
01676 {
01677   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01678   pt->Set_Type(MPF_MP_VERSION);
01679   INT i;
01680   for (i = 0; i < nloops; i++)
01681     pt->Add_Old_Loop(old_loops[i]);
01682   for (i = 0; i < nloops; i++)
01683     pt->Add_New_Loop(new_loops[i]);
01684   Add_Trans(pt);
01685   Check_New_Ids(new_loops, nloops); 
01686   for (i = 0; i < nloops; i++) {
01687     INT j;
01688     for (j = 0; j < i; j++) 
01689       if (new_loops[j] == new_loops[i])
01690         break; 
01691     if (j == i)
01692       Add_Id(CXX_NEW(PROMPF_ID(id_type[i], TRUE, Last_Trans(), _pool), 
01693         _pool)); 
01694   } 
01695   for (i = 0; i < nloops; i++)
01696     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01697   for (i = 0; i < nloops; i++)
01698     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01699 }
01700 
01701 //-----------------------------------------------------------------------
01702 // NAME: PROMPF_INFO::Parallel_Region
01703 // FUNCTION: Indicate that the parallel region with id 'new_loop' has been 
01704 //   created for the loop 'old_loop' (which should be converted into a 
01705 //   PDO loop).   
01706 //-----------------------------------------------------------------------
01707 
01708 void PROMPF_INFO::Parallel_Region(INT old_loop, 
01709                                   INT new_loop)
01710 {
01711   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01712   pt->Set_Type(MPF_PARALLEL_REGION); 
01713   pt->Add_Old_Loop(old_loop); 
01714   pt->Add_New_Loop(new_loop);
01715   Add_Trans(pt);
01716   Add_Id(CXX_NEW(PROMPF_ID(MPID_PAR_REGION, TRUE, Last_Trans(), _pool), 
01717     _pool));
01718   Id(new_loop)->Set_Last_Trans(Last_Trans());
01719 }
01720 
01721 //-----------------------------------------------------------------------
01722 // NAME: PROMPF_INFO::Hoist_Messy_Bounds
01723 // FUNCTION: Indicate that the 'nloops' with ids 'old_loops[]' have been 
01724 //   cloned into 'nloops' new loops with ids 'new_loops[]' while promoting
01725 //   messy bounds.  
01726 //-----------------------------------------------------------------------
01727 
01728 void PROMPF_INFO::Hoist_Messy_Bounds(INT old_loops[], 
01729                                      INT new_loops[], 
01730                                      INT nloops)
01731 {
01732   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01733   pt->Set_Type(MPF_HOIST_MESSY_BOUNDS);
01734   INT i;
01735   for (i = 0; i < nloops; i++)
01736     pt->Add_Old_Loop(old_loops[i]);
01737   for (i = 0; i < nloops; i++)
01738     pt->Add_New_Loop(new_loops[i]);
01739   Add_Trans(pt);
01740   Check_New_Ids(new_loops, nloops);
01741   for (i = 0; i < nloops; i++)
01742     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01743       _pool));
01744   for (i = 0; i < nloops; i++)
01745     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01746   for (i = 0; i < nloops; i++)
01747     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01748 }
01749 
01750 //-----------------------------------------------------------------------
01751 // NAME: PROMPF_INFO::Doacross_Sync
01752 // FUNCTION: Indicate that the loop with id 'new_loop' has been created 
01753 //   to initialize an array of synchronization variables for the true 
01754 //   doacross loop 'old_loop'.  
01755 //-----------------------------------------------------------------------
01756 
01757 void PROMPF_INFO::Doacross_Sync(INT old_loop, 
01758                                 INT new_loop) 
01759 {
01760   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01761   pt->Set_Type(MPF_DOACROSS_SYNC);
01762   pt->Add_Old_Loop(old_loop);
01763   pt->Add_New_Loop(new_loop);
01764   Add_Trans(pt);
01765   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01766   Id(old_loop)->Set_Last_Trans(Last_Trans());
01767   Id(new_loop)->Set_Last_Trans(Last_Trans());
01768 }
01769 
01770 //-----------------------------------------------------------------------
01771 // NAME: PROMPF_INFO::Doacross_Outer_Tile
01772 // FUNCTION: Indicate that an outer tile parallel loop with id 'new_loop'
01773 //   has been created from the original loop 'old_loop' to create a do-
01774 //   across with synchronization. 
01775 //-----------------------------------------------------------------------
01776 
01777 void PROMPF_INFO::Doacross_Outer_Tile(INT old_loop, 
01778                                       INT new_loop)
01779 {
01780   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01781   pt->Set_Type(MPF_DOACROSS_OUTER_TILE);
01782   pt->Add_Old_Loop(old_loop);
01783   pt->Add_New_Loop(new_loop);
01784   Add_Trans(pt);
01785   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01786   Id(old_loop)->Set_Last_Trans(Last_Trans());
01787   Id(new_loop)->Set_Last_Trans(Last_Trans());
01788 } 
01789 
01790 //-----------------------------------------------------------------------
01791 // NAME: PROMPF_INFO::Doacross_Sync
01792 // FUNCTION: Indicate that an inner tile serial loop with id 'new_loop'
01793 //   has been created from the original loop 'old_loop' to create a do-
01794 //   across with synchronization. 
01795 //-----------------------------------------------------------------------
01796 
01797 void PROMPF_INFO::Doacross_Inner_Tile(INT old_loop, 
01798                                       INT new_loop)
01799 {
01800   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01801   pt->Set_Type(MPF_DOACROSS_INNER_TILE);
01802   pt->Add_Old_Loop(old_loop);
01803   pt->Add_New_Loop(new_loop);
01804   Add_Trans(pt);
01805   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01806   Id(old_loop)->Set_Last_Trans(Last_Trans());
01807   Id(new_loop)->Set_Last_Trans(Last_Trans());
01808 } 
01809 
01810 //-----------------------------------------------------------------------
01811 // NAME: PROMPF_INFO::Remove_Unity_Trip
01812 // FUNCTION: Indicate that the loop with id 'old_loop' was removed (without
01813 //   removing the enclosed statements) because it was a unity trip loop. 
01814 //-----------------------------------------------------------------------
01815 
01816 void PROMPF_INFO::Remove_Unity_Trip(INT old_loop)
01817 {
01818   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool); 
01819   pt->Set_Type(MPF_REMOVE_UNITY_TRIP); 
01820   pt->Add_Old_Loop(old_loop); 
01821   Add_Trans(pt); 
01822   Id(old_loop)->Set_Last_Trans(Last_Trans());
01823   Id(old_loop)->Invalidate();
01824 }
01825 
01826 //-----------------------------------------------------------------------
01827 // NAME: PROMPF_INFO::Cache_Winddown 
01828 // FUNCTION: Indicate that the nest of 'nloops' loops with ids 'old_loops[]'
01829 //   have been cloned to form a cache winddown of 'nloops' loops with ids
01830 //   'new_loops'.  
01831 //-----------------------------------------------------------------------
01832 
01833 void PROMPF_INFO::Cache_Winddown(INT old_loops[], 
01834                                  INT new_loops[], 
01835                                  INT nloops)
01836 {
01837   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01838   pt->Set_Type(MPF_CACHE_WINDDOWN);
01839   INT i;
01840   for (i = 0; i < nloops; i++)
01841     pt->Add_Old_Loop(old_loops[i]);
01842   for (i = 0; i < nloops; i++)
01843     pt->Add_New_Loop(new_loops[i]);
01844   Add_Trans(pt);
01845   Check_New_Ids(new_loops, nloops);
01846   for (i = 0; i < nloops; i++)
01847     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01848       _pool));
01849   for (i = 0; i < nloops; i++)
01850     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01851   for (i = 0; i < nloops; i++)
01852     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01853 }
01854 
01855 //-----------------------------------------------------------------------
01856 // NAME: PROMPF_INFO::Interleaved_Winddown 
01857 // FUNCTION: Indicate that the nest of 'nloops' loops with ids 'old_loops[]'
01858 //   have been cloned to form a winddown loop nest of 'nloops' loops with ids
01859 //   'new_loops'.  This was done to optimize the inner loop of an MP tiled
01860 //   loop with interleaved scheduling. 
01861 //-----------------------------------------------------------------------
01862 
01863 void PROMPF_INFO::Interleaved_Winddown(INT old_loops[], 
01864                                        INT new_loops[], 
01865                                        INT nloops)
01866 {
01867   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01868   pt->Set_Type(MPF_INTERLEAVED_WINDDOWN);
01869   INT i;
01870   for (i = 0; i < nloops; i++)
01871     pt->Add_Old_Loop(old_loops[i]);
01872   for (i = 0; i < nloops; i++)
01873     pt->Add_New_Loop(new_loops[i]);
01874   Add_Trans(pt);
01875   Check_New_Ids(new_loops, nloops);
01876   for (i = 0; i < nloops; i++)
01877     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01878       _pool));
01879   for (i = 0; i < nloops; i++)
01880     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01881   for (i = 0; i < nloops; i++)
01882     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01883 }
01884 
01885 //-----------------------------------------------------------------------
01886 // NAME: PROMPF_INFO::General_Version
01887 // FUNCTION: Indicate that the 'nloops' with ids 'old_loops[]' have been 
01888 //   cloned into 'nloops' new loops with ids 'new_loops[]' so that a      
01889 //   general SNL transformation could be performed on them.  
01890 //-----------------------------------------------------------------------
01891 
01892 void PROMPF_INFO::General_Version(INT old_loops[], 
01893                                   INT new_loops[], 
01894                                   INT nloops)
01895 {
01896   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01897   pt->Set_Type(MPF_GENERAL_VERSION);
01898   INT i;
01899   for (i = 0; i < nloops; i++)
01900     pt->Add_Old_Loop(old_loops[i]);
01901   for (i = 0; i < nloops; i++)
01902     pt->Add_New_Loop(new_loops[i]);
01903   Add_Trans(pt);
01904   Check_New_Ids(new_loops, nloops);
01905   for (i = 0; i < nloops; i++)
01906     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01907       _pool));
01908   for (i = 0; i < nloops; i++)
01909     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01910   for (i = 0; i < nloops; i++)
01911     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01912 }
01913 
01914 //-----------------------------------------------------------------------
01915 // NAME: PROMPF_INFO::Cache_Tile
01916 // FUNCTION: Indicate that the loop with id 'old_loop' has been cache tiled 
01917 //   to create an outer tile loop with id 'new_loop'. 
01918 //-----------------------------------------------------------------------
01919 
01920 void PROMPF_INFO::Cache_Tile(INT old_loop, 
01921                              INT new_loop)
01922 {
01923   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01924   pt->Set_Type(MPF_CACHE_TILE);
01925   pt->Add_Old_Loop(old_loop);
01926   pt->Add_New_Loop(new_loop);
01927   Add_Trans(pt);
01928   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
01929   Id(old_loop)->Set_Last_Trans(Last_Trans());
01930   Id(new_loop)->Set_Last_Trans(Last_Trans());
01931 }
01932 
01933 //-----------------------------------------------------------------------
01934 // NAME: PROMPF_INFO::Register_Winddown
01935 // FUNCTION: Indicate that the nest of 'nloops' loops with ids 'old_loops[]'
01936 //   have been cloned to  a register winddown form a of 'nloops' loops with 
01937 //   ids 'new_loops[]'.  
01938 //-----------------------------------------------------------------------
01939 
01940 void PROMPF_INFO::Register_Winddown(INT old_loops[], 
01941                                     INT new_loops[], 
01942                                     INT nloops)
01943 {
01944   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01945   pt->Set_Type(MPF_REGISTER_WINDDOWN);
01946   INT i;
01947   for (i = 0; i < nloops; i++)
01948     pt->Add_Old_Loop(old_loops[i]);
01949   for (i = 0; i < nloops; i++)
01950     pt->Add_New_Loop(new_loops[i]);
01951   Add_Trans(pt);
01952   Check_New_Ids(new_loops, nloops);
01953   for (i = 0; i < nloops; i++)
01954     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01955       _pool));
01956   for (i = 0; i < nloops; i++)
01957     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01958   for (i = 0; i < nloops; i++)
01959     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01960 }
01961 
01962 //-----------------------------------------------------------------------
01963 // NAME: PROMPF_INFO::Register_SStrip
01964 // FUNCTION: Indicate that a small strip version of the 'nloops' loops with 
01965 //   ids 'old_loops[]' has been created, with ids stored in 'new_loops[]'. 
01966 //-----------------------------------------------------------------------
01967 
01968 void PROMPF_INFO::Register_SStrip(INT old_loops[], 
01969                                 INT new_loops[], 
01970                                 INT nloops)
01971 {
01972   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01973   pt->Set_Type(MPF_REGISTER_SSTRIP);
01974   INT i;
01975   for (i = 0; i < nloops; i++)
01976     pt->Add_Old_Loop(old_loops[i]);
01977   for (i = 0; i < nloops; i++)
01978     pt->Add_New_Loop(new_loops[i]);
01979   Add_Trans(pt);
01980   Check_New_Ids(new_loops, nloops);
01981   for (i = 0; i < nloops; i++)
01982     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
01983       _pool));
01984   for (i = 0; i < nloops; i++)
01985     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
01986   for (i = 0; i < nloops; i++)
01987     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
01988 }
01989 
01990 //-----------------------------------------------------------------------
01991 // NAME: PROMPF_INFO::Register_Tile
01992 // FUNCTION: Indicate that the loop with id 'loop' has been register tiled.
01993 //-----------------------------------------------------------------------
01994 
01995 void PROMPF_INFO::Register_Tile(INT loop) 
01996 {
01997   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
01998   pt->Set_Type(MPF_REGISTER_TILE);
01999   pt->Add_Old_Loop(loop);
02000   Add_Trans(pt);
02001   Id(loop)->Set_Last_Trans(Last_Trans());
02002 }
02003 
02004 //-----------------------------------------------------------------------
02005 // NAME: PROMPF_INFO::Se_Tile
02006 // FUNCTION: Indicate that the loop with id 'old_loop' has been scalar 
02007 //   expansion tiled to produce the tile loop with id 'new_loop'. 
02008 //-----------------------------------------------------------------------
02009 
02010 void PROMPF_INFO::Se_Tile(INT old_loop, 
02011                           INT new_loop)
02012 {
02013   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02014   pt->Set_Type(MPF_SE_TILE);
02015   pt->Add_Old_Loop(old_loop);
02016   pt->Add_New_Loop(new_loop);
02017   Add_Trans(pt);
02018   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02019     _pool));
02020   Id(old_loop)->Set_Last_Trans(Last_Trans());
02021   Id(new_loop)->Set_Last_Trans(Last_Trans());
02022 }
02023 
02024 //-----------------------------------------------------------------------
02025 // NAME: PROMPF_INFO::Se_Cache_Tile
02026 // FUNCTION: Indicate that the loop with id 'old_loop' has been scalar 
02027 //   expansion and cache tiled to produce the tile loop with id 'new_loop'. 
02028 //-----------------------------------------------------------------------
02029 
02030 void PROMPF_INFO::Se_Cache_Tile(INT old_loop, 
02031                                 INT new_loop)
02032 {
02033   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02034   pt->Set_Type(MPF_SE_CACHE_TILE);
02035   pt->Add_Old_Loop(old_loop);
02036   pt->Add_New_Loop(new_loop);
02037   Add_Trans(pt);
02038   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
02039   Id(old_loop)->Set_Last_Trans(Last_Trans());
02040   Id(new_loop)->Set_Last_Trans(Last_Trans());
02041 }
02042 
02043 //-----------------------------------------------------------------------
02044 // NAME: PROMPF_INFO::Register_Startup
02045 // FUNCTION: Indicate that a startup clone of the 'nloops' loops with 
02046 //   ids 'old_loops[]' has been created, with ids stored in 'new_loops[]'. 
02047 //-----------------------------------------------------------------------
02048 
02049 void PROMPF_INFO::Register_Startup(INT old_loops[], 
02050                                    INT new_loops[], 
02051                                    INT nloops)
02052 {
02053   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02054   pt->Set_Type(MPF_REGISTER_STARTUP);
02055   INT i;
02056   for (i = 0; i < nloops; i++)
02057     pt->Add_Old_Loop(old_loops[i]);
02058   for (i = 0; i < nloops; i++)
02059     pt->Add_New_Loop(new_loops[i]);
02060   Add_Trans(pt);
02061   Check_New_Ids(new_loops, nloops);
02062   for (i = 0; i < nloops; i++)
02063     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02064       _pool));
02065   for (i = 0; i < nloops; i++)
02066     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
02067   for (i = 0; i < nloops; i++)
02068     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
02069 }
02070 
02071 //-----------------------------------------------------------------------
02072 // NAME: PROMPF_INFO::Register_Shutdown
02073 // FUNCTION: Indicate that a shutdown clone of the 'nloops' loops with 
02074 //   ids 'old_loops[]' has been created, with ids stored in 'new_loops[]'. 
02075 //-----------------------------------------------------------------------
02076 
02077 void PROMPF_INFO::Register_Shutdown(INT old_loops[], 
02078                                     INT new_loops[], 
02079                                     INT nloops)
02080 {
02081   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02082   pt->Set_Type(MPF_REGISTER_SHUTDOWN);
02083   INT i;
02084   for (i = 0; i < nloops; i++)
02085     pt->Add_Old_Loop(old_loops[i]);
02086   for (i = 0; i < nloops; i++)
02087     pt->Add_New_Loop(new_loops[i]);
02088   Add_Trans(pt);
02089   Check_New_Ids(new_loops, nloops);
02090   for (i = 0; i < nloops; i++)
02091     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02092       _pool));
02093   for (i = 0; i < nloops; i++)
02094     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
02095   for (i = 0; i < nloops; i++)
02096     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
02097 }
02098 
02099 //-----------------------------------------------------------------------
02100 // NAME: PROMPF_INFO::Inner_Fission 
02101 // FUNCTION: Inficate that the loop with id 'old_loop', has been fissioned
02102 //   into 'nloops' loops with ids 'new_loops' 
02103 //-----------------------------------------------------------------------
02104 
02105 void PROMPF_INFO::Inner_Fission(INT old_loop,
02106                                 PROMPF_LINES* old_lines, 
02107                                 INT new_loops[], 
02108                                 PROMPF_LINES* new_lines[], 
02109                                 INT nloops)
02110 {
02111   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02112   pt->Set_Type(MPF_INNER_FISSION); 
02113   pt->Add_Old_Loop(old_loop); 
02114   pt->Add_Old_Lines(old_lines); 
02115   INT i;
02116   for (i = 0; i < nloops; i++) {
02117     pt->Add_New_Loop(new_loops[i]); 
02118     pt->Add_New_Lines(new_lines[i]); 
02119   } 
02120   Add_Trans(pt); 
02121   Check_New_Ids(new_loops, nloops); 
02122   for (i = 0; i < nloops; i++)
02123     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02124       _pool));
02125   Id(old_loop)->Set_Last_Trans(Last_Trans());
02126   for (i = 0; i < nloops; i++)
02127     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
02128 } 
02129 
02130 //-----------------------------------------------------------------------
02131 // NAME: PROMPF_INFO::Gather_Scatter
02132 // FUNCTION: Inficate that the loop with id 'old_loop', has been fissioned
02133 //   into 'nloops' loops with ids 'new_loops' during gather-scatter.
02134 //-----------------------------------------------------------------------
02135 
02136 void PROMPF_INFO::Gather_Scatter(INT old_loop,
02137                                  PROMPF_LINES* old_lines, 
02138                                  INT new_loops[], 
02139                                  PROMPF_LINES* new_lines[], 
02140                                  INT nloops)
02141 {
02142   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02143   pt->Set_Type(MPF_GATHER_SCATTER); 
02144   pt->Add_Old_Loop(old_loop); 
02145   pt->Add_Old_Lines(old_lines); 
02146   INT i;
02147   for (i = 0; i < nloops; i++) {
02148     pt->Add_New_Loop(new_loops[i]); 
02149     pt->Add_New_Lines(new_lines[i]); 
02150   } 
02151   Add_Trans(pt); 
02152   Check_New_Ids(new_loops, nloops); 
02153   for (i = 0; i < nloops; i++)
02154     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02155       _pool));
02156   Id(old_loop)->Set_Last_Trans(Last_Trans());
02157   for (i = 0; i < nloops; i++)
02158     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
02159 } 
02160 
02161 //-----------------------------------------------------------------------
02162 // NAME: PROMPF_INFO::Vintr_Fission 
02163 // FUNCTION: Inficate that the loop with id 'old_loop', has been fissioned
02164 //   into 'nloops' loops with ids 'new_loops' during vector intrinsic 
02165 //   fission.
02166 //-----------------------------------------------------------------------
02167 
02168 void PROMPF_INFO::Vintr_Fission(INT old_loop,
02169                                 PROMPF_LINES* old_lines, 
02170                                 INT new_loops[], 
02171                                 PROMPF_LINES* new_lines[], 
02172                                 INT nloops)
02173 {
02174   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02175   pt->Set_Type(MPF_VINTR_FISSION); 
02176   pt->Add_Old_Loop(old_loop); 
02177   pt->Add_Old_Lines(old_lines); 
02178   INT i;
02179   for (i = 0; i < nloops; i++) {
02180     pt->Add_New_Loop(new_loops[i]); 
02181     pt->Add_New_Lines(new_lines[i]); 
02182   } 
02183   Add_Trans(pt); 
02184   Check_New_Ids(new_loops, nloops); 
02185   for (i = 0; i < nloops; i++)
02186     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02187       _pool));
02188   Id(old_loop)->Set_Last_Trans(Last_Trans());
02189   for (i = 0; i < nloops; i++)
02190     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
02191 } 
02192 
02193 //-----------------------------------------------------------------------
02194 // NAME: PROMPF_INFO::Prefetch_Version
02195 // FUNCTION: Indicate that a clone of the 'nloops' loops with ids 
02196 //   'old_loops[]' has been created for prefetching, with ids stored in 
02197 //   'new_loops[]'. 
02198 //-----------------------------------------------------------------------
02199 
02200 void PROMPF_INFO::Prefetch_Version(INT old_loops[], 
02201                                    INT new_loops[], 
02202                                    INT nloops)
02203 {
02204   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02205   pt->Set_Type(MPF_PREFETCH_VERSION);
02206   INT i;
02207   for (i = 0; i < nloops; i++)
02208     pt->Add_Old_Loop(old_loops[i]);
02209   for (i = 0; i < nloops; i++)
02210     pt->Add_New_Loop(new_loops[i]);
02211   Add_Trans(pt);
02212   Check_New_Ids(new_loops, nloops);
02213   for (i = 0; i < nloops; i++)
02214     Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), 
02215       _pool));
02216   for (i = 0; i < nloops; i++)
02217     Id(old_loops[i])->Set_Last_Trans(Last_Trans());
02218   for (i = 0; i < nloops; i++)
02219     Id(new_loops[i])->Set_Last_Trans(Last_Trans());
02220 }
02221 
02222 //-----------------------------------------------------------------------
02223 // NAME: PROMPF_INFO::Outer_Shackle
02224 // FUNCTION: Indicate that the loop with id 'new_loop' is a newly 
02225 //   created outer shackle loop.  The line numbers of the loop nest 
02226 //   for which the outer shackle loop is created are contained in 'pl'.
02227 //-----------------------------------------------------------------------
02228 
02229 void PROMPF_INFO::Outer_Shackle(INT new_loop, 
02230                                 PROMPF_LINES* pl,
02231                                 char* index_name) 
02232 {
02233   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02234   pt->Set_Type(MPF_OUTER_SHACKLE); 
02235   pt->Add_New_Loop(new_loop);
02236   pt->Add_New_Lines(pl); 
02237   pt->Add_Index_Name(index_name);
02238   Add_Trans(pt);
02239   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
02240   Id(new_loop)->Set_Last_Trans(Last_Trans());
02241 }
02242 
02243 //-----------------------------------------------------------------------
02244 // NAME: PROMPF_INFO::Inner_Shackle
02245 // FUNCTION: Indicate that the loop whose id is 'old_loop' has been cloned
02246 //   to create a 'new_loop' which is an part of an loop nest nested within
02247 //   a set of outer shackle loops.  
02248 //-----------------------------------------------------------------------
02249 
02250 void PROMPF_INFO::Inner_Shackle(INT old_loop, 
02251                                 INT new_loop) 
02252 {
02253   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02254   pt->Set_Type(MPF_INNER_SHACKLE);
02255   pt->Add_Old_Loop(old_loop);
02256   pt->Add_New_Loop(new_loop);
02257   Add_Trans(pt); 
02258   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
02259   Id(old_loop)->Set_Last_Trans(Last_Trans());
02260   Id(new_loop)->Set_Last_Trans(Last_Trans());
02261 }
02262 
02263 //-----------------------------------------------------------------------
02264 // NAME: PROMPF_INFO::OMPL_Sections_To_Loop
02265 // FUNCTION: Indicate that the SECTIONS construct with the given 'old_id' 
02266 //   has been converted into a loop
02267 //-----------------------------------------------------------------------
02268 
02269 void PROMPF_INFO::OMPL_Sections_To_Loop(INT old_id)
02270 {
02271   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02272   pt->Set_Type(MPF_OMPL_SECTIONS_LOOP);
02273   pt->Add_Old_Loop(old_id);
02274   Add_Trans(pt);
02275   Id(old_id)->Set_Last_Trans(Last_Trans());
02276 }
02277 
02278 //-----------------------------------------------------------------------
02279 // NAME: PROMPF_INFO::OMPL_Eliminate_Section
02280 // FUNCTION: Indicate that the SECTION construct with the given 'old_id'  
02281 //   has been eliminated from the program, because its corresponding 
02282 //   SECTIONS construct has been converted into a loop.
02283 //-----------------------------------------------------------------------
02284 
02285 void PROMPF_INFO::OMPL_Eliminate_Section(INT old_id)
02286 {
02287   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02288   pt->Set_Type(MPF_OMPL_ELIM_SECTION);
02289   pt->Add_Old_Loop(old_id);
02290   Add_Trans(pt);
02291   Id(old_id)->Set_Last_Trans(Last_Trans());
02292   Id(old_id)->Invalidate();
02293 }
02294 
02295 //-----------------------------------------------------------------------
02296 // NAME: PROMPF_INFO::OMPL_Atomic_To_Critical_Section
02297 // FUNCTION: Indicate that the ATOMIC construct with the given 'old_id' 
02298 //   has been converted into a CRIRICAL SECTION.
02299 //-----------------------------------------------------------------------
02300 
02301 void PROMPF_INFO::OMPL_Atomic_To_Critical_Section(INT old_id)
02302 {
02303   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02304   pt->Set_Type(MPF_OMPL_ATOMIC_CSECTION);
02305   pt->Add_Old_Loop(old_id);
02306   Add_Trans(pt);
02307   Id(old_id)->Set_Last_Trans(Last_Trans());
02308 }
02309 
02310 //-----------------------------------------------------------------------
02311 // NAME: PROMPF_INFO::OMPL_Atomic_To_Swap
02312 // FUNCTION: Indicate that the ATOMIC construct with the given 'old_id'
02313 //   has been converted into a compare and swap sequence. 
02314 //-----------------------------------------------------------------------
02315 
02316 void PROMPF_INFO::OMPL_Atomic_To_Swap(INT old_id)
02317 {
02318   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02319   pt->Set_Type(MPF_OMPL_ATOMIC_SWAP);
02320   pt->Add_Old_Loop(old_id);
02321   Add_Trans(pt);
02322   Id(old_id)->Set_Last_Trans(Last_Trans());
02323   Id(old_id)->Invalidate();
02324 }
02325 
02326 //-----------------------------------------------------------------------
02327 // NAME: PROMPF_INFO::OMPL_Atomic_To_FetchAndOp
02328 // FUNCTION: Indicate that the ATOMIC construct with the given 'old_id' 
02329 //   has been converted into a fetch and op sequence. 
02330 //-----------------------------------------------------------------------
02331 
02332 void PROMPF_INFO::OMPL_Atomic_To_FetchAndOp(INT old_id)
02333 {
02334   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02335   pt->Set_Type(MPF_OMPL_ATOMIC_FETCHOP);
02336   pt->Add_Old_Loop(old_id);
02337   Add_Trans(pt);
02338   Id(old_id)->Set_Last_Trans(Last_Trans());
02339   Id(old_id)->Invalidate();
02340 }
02341 
02342 //-----------------------------------------------------------------------
02343 // NAME: PROMPF_INFO::OMPL_Master_To_If
02344 // FUNCTION: Indicate that the MASTER construct with the given 'old_id'  
02345 //   has been converted into an IF test. 
02346 //-----------------------------------------------------------------------
02347 
02348 void PROMPF_INFO::OMPL_Master_To_If(INT old_id)
02349 {
02350   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02351   pt->Set_Type(MPF_OMPL_MASTER_IF);
02352   pt->Add_Old_Loop(old_id);
02353   Add_Trans(pt);
02354   Id(old_id)->Set_Last_Trans(Last_Trans());
02355   Id(old_id)->Invalidate();
02356 }
02357 
02358 //-----------------------------------------------------------------------
02359 // NAME: PROMPF_INFO::OMPL_Fetchop_Atomic
02360 // FUNCTION: Indicate that an unsupported fetch and op intrinsic has been 
02361 //   lowered to an ATOMIC directive. 
02362 //-----------------------------------------------------------------------
02363 
02364 void PROMPF_INFO::OMPL_Fetchop_Atomic(INT new_id,
02365                                       PROMPF_LINES* pl) 
02366 {
02367   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02368   pt->Set_Type(MPF_OMPL_FETCHOP_ATOMIC); 
02369   pt->Add_New_Loop(new_id);
02370   pt->Add_New_Lines(pl); 
02371   Add_Trans(pt);
02372   Add_Id(CXX_NEW(PROMPF_ID(MPID_ATOMIC, TRUE, Last_Trans(), _pool),  
02373     _pool));
02374   Id(new_id)->Set_Last_Trans(Last_Trans());
02375 }
02376 
02377 //-----------------------------------------------------------------------
02378 // NAME: PROMPF_INFO::F90_Array_Stmt 
02379 // FUNCTION: Indicate that the loop with id 'new_loop' has been created 
02380 //   from the F90 array statement which appears on the lines contained 
02381 //   in 'pl'. 
02382 //-----------------------------------------------------------------------
02383 
02384 void PROMPF_INFO::F90_Array_Stmt(INT new_loop, 
02385                                  PROMPF_LINES* pl,
02386                                  char* index_name) 
02387 {
02388   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02389   pt->Set_Type(MPF_F90_ARRAY_STMT); 
02390   pt->Add_New_Loop(new_loop);
02391   pt->Add_New_Lines(pl); 
02392   pt->Add_Index_Name(index_name);
02393   Add_Trans(pt);
02394   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
02395   Id(new_loop)->Set_Last_Trans(Last_Trans());
02396 }
02397 
02398 //-----------------------------------------------------------------------
02399 // NAME: PROMPF_INFO::Preopt_Create
02400 // FUNCTION: Indicate that the loop with id 'new_loop' has been created 
02401 //   by raising a WHILE or unstructed control flow loop into a DO_LOOP.  
02402 //   The line numbers of the region on which the LASTLOCAL call appears 
02403 //   are contained in 'pl'. 
02404 //-----------------------------------------------------------------------
02405 
02406 void PROMPF_INFO::Preopt_Create(INT new_loop, 
02407                                 PROMPF_LINES* pl,
02408                                 char* index_name) 
02409 {
02410   PROMPF_TRANS* pt = CXX_NEW(PROMPF_TRANS(_pool), _pool);
02411   pt->Set_Type(MPF_PREOPT_CREATE); 
02412   pt->Add_New_Loop(new_loop);
02413   pt->Add_New_Lines(pl); 
02414   pt->Add_Index_Name(index_name);
02415   Add_Trans(pt);
02416   Add_Id(CXX_NEW(PROMPF_ID(MPID_DO_LOOP, TRUE, Last_Trans(), _pool), _pool));
02417   Id(new_loop)->Set_Last_Trans(Last_Trans());
02418 }
02419 
02420 //-----------------------------------------------------------------------
02421 // NAME: PROMPF_INFO::Print 
02422 // FUNCTION: Print the PROMPF_INFO to the file 'fp'.  
02423 //-----------------------------------------------------------------------
02424 
02425 void PROMPF_INFO::Print(FILE* fp) 
02426 {
02427   fprintf(fp, "TRANSFORMATION LIST:\n"); 
02428   INT i;
02429   for (i = 0; i < _trans_stack.Elements(); i++) {
02430     fprintf(fp, "  %2d ", i); 
02431     _trans_stack.Bottom_nth(i)->Print(fp); 
02432   } 
02433   fprintf(fp, "ID LIST:\n"); 
02434   for (i = First_Id(); i <= Last_Id(); i++) {
02435     fprintf(fp, "  "); 
02436     Id(i)->Print(fp, i); 
02437   }
02438   if (_trans_checkpoint != -1)
02439     fprintf(fp, "CHECKPOINT: %d\n", _trans_checkpoint);
02440 }
02441 
02442 //-----------------------------------------------------------------------
02443 // NAME: PROMPF_INFO::Check_Traverse
02444 // FUNCTION: Traverse the 'wn_tree' (whose closest enclosing region is 
02445 //   'wn_region', and check the consistency of the PROMPF information in 
02446 //   that tree. Here 'ids[]' is a BOOL array in which 'ids[i - First_Id()]' 
02447 //   is TRUE if i-th id has been seen.  
02448 //-----------------------------------------------------------------------
02449 
02450 static INT check_error_count = 0; 
02451 
02452 #define PM_ASSERT(a, b) \
02453   ((a) ? 0 : (fprintf b, fprintf(fp, "\n"), check_error_count++))
02454 
02455 void PROMPF_INFO::Check_Traverse(FILE* fp,
02456                                  WN* wn_tree, 
02457                                  BOOL ids[], 
02458                                  WN* wn_region)
02459 { 
02460   INT map_id = WN_MAP32_Get(Prompf_Id_Map, wn_tree); 
02461   if (map_id != 0) {
02462     PM_ASSERT(map_id >= First_Id() && map_id <= Last_Id(),
02463       (fp, "PROMPF_INFO: Id in program out of range %d", map_id)); 
02464     if (map_id >= First_Id() && map_id <= Last_Id()) 
02465       ids[map_id - First_Id()] = TRUE; 
02466   } else { 
02467     BOOL is_first = FALSE; 
02468     PM_ASSERT(Prompf_Id_Type(wn_tree, wn_region, &is_first) == MPID_UNKNOWN, 
02469       (fp, "PROMPF_INFO: Missing Prompf Id for 0x%p %s", 
02470       wn_tree, Whirl_Symbol_Type(wn_tree)));
02471   }
02472 
02473   if (WN_opcode(wn_tree) == OPC_BLOCK) { 
02474     for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))  
02475       Check_Traverse(fp, wn, ids, wn_region); 
02476   } else if (WN_opcode(wn_tree) == OPC_REGION) { 
02477     INT i;
02478     for (i = 0; i < WN_kid_count(wn_tree); i++) 
02479       Check_Traverse(fp, WN_kid(wn_tree, i), ids, wn_tree); 
02480   } else { 
02481     INT i;
02482     for (i = 0; i < WN_kid_count(wn_tree); i++) 
02483       Check_Traverse(fp, WN_kid(wn_tree, i), ids, wn_region); 
02484   } 
02485 } 
02486 
02487 //-----------------------------------------------------------------------
02488 // NAME: PROMPF_INFO::Check 
02489 // FUNCTION: Return the number of errors encountered while checking the 
02490 //   PROMPF_INFO for internal consistency and consistency with the func-
02491 //   tion 'wn_func', and print a message to the file 'fp' for each error
02492 //   encountered.   
02493 //-----------------------------------------------------------------------
02494 
02495 INT PROMPF_INFO::Check(FILE* fp,
02496                        WN* wn_func) 
02497 {
02498   INT check_error_count = 0; 
02499   INT nids = Last_Id() - First_Id() + 1; 
02500   INT* ids = CXX_NEW_ARRAY(BOOL, nids, _pool);  
02501   INT i;
02502   for (i = 0; i < nids; i++) 
02503     ids[i] = FALSE; 
02504   Check_Traverse(fp, wn_func, ids, NULL); 
02505   for (i = First_Id(); i < Last_Id(); i++) {
02506     PM_ASSERT(!Id(i)->Is_Valid() || ids[i - First_Id()],  
02507       (fp, "PROMPF_INFO: Valid id %d not in program", i)); 
02508     PM_ASSERT(Id(i)->Is_Valid() || !ids[i - First_Id()],  
02509       (fp, "PROMPF_INFO: Invalid id %d in program", i)); 
02510   } 
02511   for (i = First_Id(); i < Last_Id(); i++) {
02512     INT j = Id(i)->Last_Trans();  
02513     if (j != -1) { 
02514       PM_ASSERT(j >= 0 && j <= Last_Trans(), 
02515         (fp, "PROMPF_INFO: Trans Index %d out of range", j));  
02516       PROMPF_TRANS* pt = Trans(j); 
02517       if (Id(i)->Is_Valid()) { 
02518         INT k;
02519         for (k = 0; k < pt->Old_Loop_Count(); k++) 
02520           if (pt->Old_Loop(k) == i)
02521             break; 
02522         if (k == pt->Old_Loop_Count()) {
02523           for (k = 0; k < pt->New_Loop_Count(); k++) 
02524             if (pt->New_Loop(k) == i)
02525               break; 
02526           PM_ASSERT(k != pt->New_Loop_Count(), 
02527             (fp, "PROMPF_INFO: Trans Index %d does not match LHS or RHS", i)); 
02528         } 
02529       } else { 
02530         INT k;
02531         for (k = 0; k < pt->Old_Loop_Count(); k++) 
02532           if (pt->Old_Loop(k) == i)
02533             break; 
02534         PM_ASSERT(k != pt->Old_Loop_Count(), 
02535           (fp, "PROMPF_INFO: Trans Index %d does not match LHS", i)); 
02536       }  
02537     }
02538   }
02539   for (i = 0; i < Last_Trans(); i++) { 
02540     PROMPF_TRANS* pt = Trans(i); 
02541     PM_ASSERT(pt->Old_Loop_Count() == pt->Prev_Loop_Count(), 
02542       (fp, "PROMPF_INFO: Old_Loop_Count != Prev_Loop_Count for trans %d", i));
02543     INT j;
02544     for (j = 0; j < pt->Prev_Loop_Count(); j++) {
02545       PM_ASSERT(pt->Prev_Loop(j) >= -1 && pt->Prev_Loop(j) <= Last_Trans(), 
02546         (fp, "PROMPF_INFO: Prev_Loop(%d) for trans %d out of range", j, i));
02547       if (pt->Prev_Loop(j) >= 0) {
02548         PROMPF_TRANS* ptt = Trans(pt->Prev_Loop(j));
02549         INT k;
02550         for (k = 0; k < ptt->New_Loop_Count(); k++) 
02551           if (ptt->New_Loop(k) == pt->Old_Loop(j))
02552             break;
02553         PM_ASSERT(k != ptt->New_Loop_Count(), 
02554           (fp, "PROMPF_INFO: Prev_Loop(%d) for trans %d has no new loop match",
02555              j, i));
02556       }
02557     }
02558   }
02559   return check_error_count; 
02560 }
02561 
02562 //-----------------------------------------------------------------------
02563 // NAME: Is_Mark_Type
02564 // FUNCTION: Returns TRUE if 'ptt' one of the transformation log mark        
02565 //   types, returns FALSE otherwise. 
02566 //-----------------------------------------------------------------------
02567 
02568 static BOOL Is_Mark_Type(PROMPF_TRANS_TYPE ptt)      
02569 {
02570   switch (ptt) { 
02571   case MPF_MARK_OMP: 
02572   case MPF_MARK_PREOPT: 
02573   case MPF_MARK_PRELNO: 
02574   case MPF_MARK_POSTLNO: 
02575     return TRUE; 
02576   default: 
02577     return FALSE; 
02578   } 
02579 } 
02580 
02581 //-----------------------------------------------------------------------
02582 // NAME: PROMPF_INFO::Print_Compact 
02583 // FUNCTION: Print the transaction log for PROMP_INFO in compact form 
02584 //   to the file 'fp'. (This is the form used by the PROMPF anl file.)  
02585 //-----------------------------------------------------------------------
02586 
02587 void PROMPF_INFO::Print_Compact(FILE *fp, 
02588                                 PROMPF_TRANS_LOG ptl)
02589 {
02590   if (Last_Trans() == -1)
02591     return; 
02592   INT i = 0; 
02593   switch (ptl) {
02594   case PTL_F90_LOWER:
02595     for (i = 0; i <= Last_Trans(); i++)
02596       if (Trans(i)->Type() == MPF_MARK_F90_LOWER)
02597         break; 
02598     if (i >= Last_Trans())
02599       break; 
02600     fprintf(fp, "F90_LOWER_TRANSFORMATION_LOG_BEGIN\n"); 
02601     for (i++ ; i <= Last_Trans(); i++) {
02602       if (Is_Mark_Type(Trans(i)->Type()))
02603         break; 
02604       Trans(i)->Print_Compact(fp); 
02605     } 
02606     fprintf(fp, "F90_LOWER_TRANSFORMATION_LOG_END\n\n"); 
02607     break; 
02608   case PTL_OMP:
02609     for (i = 0; i <= Last_Trans(); i++)
02610       if (Trans(i)->Type() == MPF_MARK_OMP)
02611         break; 
02612     if (i >= Last_Trans())
02613       break; 
02614     fprintf(fp, "OMP_TRANSFORMATION_LOG_BEGIN\n"); 
02615     for (i++ ; i <= Last_Trans(); i++) {
02616       if (Is_Mark_Type(Trans(i)->Type()))
02617         break; 
02618       Trans(i)->Print_Compact(fp); 
02619     } 
02620     fprintf(fp, "OMP_TRANSFORMATION_LOG_END\n\n"); 
02621     break; 
02622   case PTL_PREOPT:
02623     for (i = 0; i <= Last_Trans(); i++)
02624       if (Trans(i)->Type() == MPF_MARK_PREOPT)
02625         break; 
02626     if (i >= Last_Trans() || Is_Mark_Type(Trans(i+1)->Type()))
02627       break; 
02628     fprintf(fp, "PREOPT_TRANSFORMATION_LOG_BEGIN\n");
02629     for (i++; i <= Last_Trans(); i++) {
02630       if (Is_Mark_Type(Trans(i)->Type()))
02631         break; 
02632       Trans(i)->Print_Compact(fp); 
02633     } 
02634     fprintf(fp, "PREOPT_TRANSFORMATION_LOG_END\n\n");
02635     break;  
02636   case PTL_PRELNO: 
02637     for (i = 0; i <= Last_Trans(); i++)
02638       if (Trans(i)->Type() == MPF_MARK_PRELNO)
02639         break; 
02640     if (i >= Last_Trans() || Is_Mark_Type(Trans(i+1)->Type()))
02641       break; 
02642     fprintf(fp, "TRANSFORMATION_LOG_BEGIN\n"); 
02643     for (i++; i <= Last_Trans(); i++) {
02644       if (Is_Mark_Type(Trans(i)->Type()))
02645         break; 
02646       Trans(i)->Print_Compact(fp); 
02647     } 
02648     fprintf(fp, "TRANSFORMATION_LOG_END\n\n"); 
02649     break;  
02650   case PTL_POSTLNO: 
02651     for (i = 0; i <= Last_Trans(); i++)
02652       if (Trans(i)->Type() == MPF_MARK_POSTLNO)
02653         break; 
02654     if (i >= Last_Trans() || Is_Mark_Type(Trans(i+1)->Type()))
02655       break; 
02656     fprintf(fp, "POST_TRANSFORMATION_LOG_BEGIN\n"); 
02657     for (i++; i <= Last_Trans(); i++) {
02658       if (Is_Mark_Type(Trans(i)->Type()))
02659         break; 
02660       Trans(i)->Print_Compact(fp); 
02661     } 
02662     fprintf(fp, "POST_TRANSFORMATION_LOG_END\n\n"); 
02663     break;  
02664   } 
02665 }
02666 
02667 //-----------------------------------------------------------------------
02668 // NAME: PROMPF_INFO::Save
02669 // FUNCTION: Set a checkpoint to which the PROMPF log may be restored. 
02670 //-----------------------------------------------------------------------
02671 
02672 void PROMPF_INFO::Save()
02673 { 
02674   FmtAssert(_trans_checkpoint == -1, 
02675     ("PROMPF_INFO::Save: Transformation Checkpoint Already Saved"));
02676   _trans_checkpoint = Last_Trans();
02677 } 
02678 
02679 //-----------------------------------------------------------------------
02680 // NAME: PROMPF_INFO::Restore
02681 // FUNCTION: Restore the PROMPF log to the stored checkpoint. 
02682 //-----------------------------------------------------------------------
02683 
02684 void PROMPF_INFO::Restore()
02685 { 
02686   FmtAssert(_trans_checkpoint != -1,
02687     ("PROMPF_INFO::Restore: Transformation Checkpoint Not Saved"));
02688   while (Last_Trans() > _trans_checkpoint) { 
02689     PROMPF_TRANS* pt = Trans(Last_Trans());
02690     switch(pt->Type()) { 
02691     case MPF_PRE_PEEL: 
02692       Undo_Pre_Peel();
02693       break;
02694     case MPF_POST_PEEL: 
02695       Undo_Post_Peel();
02696       break;
02697     case MPF_FUSION: 
02698       Undo_Fusion();
02699       break;
02700     case MPF_ELIMINATION: 
02701       Undo_Elimination();
02702       break; 
02703     default: 
02704       FmtAssert(FALSE, ("Restore: Cannot undo PROMPF transformation"));
02705     } 
02706   } 
02707   _trans_checkpoint = -1; 
02708 } 
02709 
02710 //-----------------------------------------------------------------------
02711 // NAME: PROMPF_INFO::Clear
02712 // FUNCTION: Reset the PROMPF stored checkpoint. 
02713 //-----------------------------------------------------------------------
02714 
02715 void PROMPF_INFO::Clear()
02716 {
02717   _trans_checkpoint = -1;
02718 } 
02719 
02720 //-----------------------------------------------------------------------
02721 // NAME: Prompf_Assign_Ids_Traverse 
02722 // FUNCTION: Recursive traversal for the function Prompf_Assign_Ids().
02723 //   (See below for full description, function arguments are the same.)   
02724 //-----------------------------------------------------------------------
02725 
02726 static void Prompf_Assign_Ids_Traverse(WN* wn_old, 
02727                                        WN* wn_new, 
02728                                        STACK<WN*>* old_stack, 
02729                                        STACK<WN*>* new_stack, 
02730                                        BOOL copy_ids,
02731                                        INT max_ids)
02732 {
02733   if (old_stack->Elements() == max_ids)
02734     return; 
02735   FmtAssert(old_stack->Elements() < max_ids, 
02736     ("Prompf_Assign_Ids: Too many ids assigned")); 
02737   FmtAssert(WN_opcode(wn_old) == WN_opcode(wn_new), 
02738     ("Prompf_Assign_Ids: Cloned node type does not match original"));
02739   if (!OPCODE_is_scf(WN_opcode(wn_old)))
02740     return; 
02741 
02742   INT old_id = WN_MAP32_Get(Prompf_Id_Map, wn_old); 
02743   INT new_id = WN_MAP32_Get(Prompf_Id_Map, wn_new); 
02744   if (old_id != 0 && new_id == 0) {
02745     if (copy_ids) { 
02746       WN_MAP32_Set(Prompf_Id_Map, wn_new, old_id);
02747     } else { 
02748       INT new_id = New_Construct_Id(); 
02749       WN_MAP32_Set(Prompf_Id_Map, wn_new, new_id); 
02750     } 
02751     old_stack->Push(wn_old);
02752     new_stack->Push(wn_new); 
02753   } 
02754 
02755   if (WN_opcode(wn_old) == OPC_BLOCK) {
02756     WN* wn2 = WN_first(wn_new); 
02757     for (WN* wn1 = WN_first(wn_old); wn1 != NULL; wn1 = WN_next(wn1)) { 
02758       Prompf_Assign_Ids_Traverse(wn1, wn2, old_stack, new_stack, 
02759         copy_ids, max_ids); 
02760       wn2 = WN_next(wn2);  
02761     }
02762   } else { 
02763     INT i;
02764     for (i = 0; i < WN_kid_count(wn_old); i++) { 
02765       WN* wn1 = WN_kid(wn_old, i);  
02766       WN* wn2 = WN_kid(wn_new, i);  
02767       Prompf_Assign_Ids_Traverse(wn1, wn2, old_stack, new_stack, 
02768         copy_ids, max_ids);
02769     }
02770   }
02771 
02772   FmtAssert(old_stack->Elements() == new_stack->Elements(), 
02773     ("Prompf_Assign_Ids: Old and new stacks must have same element count")); 
02774 }
02775 
02776 //-----------------------------------------------------------------------
02777 // NAME: Prompf_Assign_Ids 
02778 // FUNCTION: Traverse the old code 'wn_old' and the new code 'wn_new' 
02779 //   simulanteously, and assign new PROMPF ids to nodes in the new code 
02780 //   which don't have them, but which correspond to nodes in the old code.
02781 //   When a new id is assigned in the new code, push the old WN* on the 
02782 //   'old_stack' and the new WN* on the 'new_stack'.  Assign a maximum of
02783 //   'max_ids' new ids in the new code. If 'copy_ids', then duplicate the
02784 //   ids in the new code rather than assigning new ids. 
02785 //-----------------------------------------------------------------------
02786 
02787 extern void Prompf_Assign_Ids(WN* wn_old,
02788                               WN* wn_new,
02789                               STACK<WN*>* old_stack, 
02790                               STACK<WN*>* new_stack,
02791                               BOOL copy_ids,
02792                               INT max_ids)
02793 {
02794   Prompf_Assign_Ids_Traverse(wn_old, wn_new, old_stack, new_stack, 
02795     copy_ids, max_ids); 
02796 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines