Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 // This may look like C code, but it is really -*- C++ -*- 00037 // 00038 // ==================================================================== 00039 // ==================================================================== 00040 // 00041 // Revision history: 00042 // 14-Nov-96 - Original Version, copied from cache_parameters.cxx. 00043 // 00044 // Description: 00045 // 00046 // This is the description of the memory hierarcy. It is only used 00047 // to determine how to SNL transform and for prefetching. There's no 00048 // need to model memory hierarchy levels that are to be ignored during 00049 // transformation. E.g. typically, there's no need to model main 00050 // memory. 00051 // 00052 // ==================================================================== 00053 // ==================================================================== 00054 00055 #ifdef _KEEP_RCS_ID 00056 static const char source_file[] = __FILE__; 00057 #endif /* _KEEP_RCS_ID */ 00058 00059 #include <sys/types.h> 00060 #include <math.h> 00061 00062 #include "defs.h" 00063 #include "errors.h" 00064 #include "config_cache.h" 00065 00066 //--------------------------------------------------------------------------- 00067 00068 MHD_LEVEL::MHD_LEVEL(MHD_TYPE type, INT64 cs, INT32 ls, 00069 INT32 cmp, INT32 dmp, INT32 assoc, 00070 INT32 tlb_entries, INT32 ps, 00071 INT32 tlb_cmp, INT32 tlb_dmp, 00072 double outstanding, 00073 double op_overlap_1, double op_overlap_2, 00074 INT pct_xwrites_nonhidable) : 00075 Type(type), Size(cs), Line_Size(ls), 00076 Clean_Miss_Penalty(cmp), Dirty_Miss_Penalty(dmp), Associativity(assoc), 00077 TLB_Entries(tlb_entries), Page_Size(ps), Prefetch_Level (-1), 00078 TLB_Clean_Miss_Penalty(tlb_cmp), TLB_Dirty_Miss_Penalty(tlb_dmp), 00079 Typical_Outstanding(outstanding), 00080 Load_Op_Overlap_1(op_overlap_1), Load_Op_Overlap_2(op_overlap_2), 00081 Pct_Excess_Writes_Nonhidable(pct_xwrites_nonhidable), 00082 CS_string (NULL), CMP_Set (FALSE), DMP_Set (FALSE), 00083 Is_Mem_Level(-1), Is_Mem_Level_Set(FALSE), 00084 Miss_Penalty(-1), Miss_Penalty_Set(FALSE), 00085 TLB_CMP_Set (FALSE), TLB_DMP_Set (FALSE), 00086 TLB_Miss_Penalty(-1), TLB_MP_Set(FALSE) 00087 { 00088 Compute_Effective_Size(); 00089 } 00090 00091 MHD_LEVEL& MHD_LEVEL::operator = (const MHD_LEVEL& a) 00092 { 00093 Type = a.Type; 00094 Line_Size = a.Line_Size; 00095 Size = a.Size; 00096 Clean_Miss_Penalty = a.Clean_Miss_Penalty; 00097 Dirty_Miss_Penalty = a.Dirty_Miss_Penalty; 00098 Associativity = a.Associativity; 00099 Effective_Size = a.Effective_Size; 00100 TLB_Entries = a.TLB_Entries; 00101 Page_Size = a.Page_Size; 00102 Prefetch_Level = a.Prefetch_Level; 00103 TLB_Clean_Miss_Penalty = a.TLB_Clean_Miss_Penalty; 00104 TLB_Dirty_Miss_Penalty = a.TLB_Dirty_Miss_Penalty; 00105 Typical_Outstanding = a.Typical_Outstanding; 00106 Load_Op_Overlap_1 = a.Load_Op_Overlap_1; 00107 Load_Op_Overlap_2 = a.Load_Op_Overlap_2; 00108 Pct_Excess_Writes_Nonhidable = a.Pct_Excess_Writes_Nonhidable; 00109 00110 // The following are to be used only during option setting; 00111 // simply reset them to defaults: 00112 CS_string = NULL; 00113 CMP_Set = FALSE; 00114 DMP_Set = FALSE; 00115 Is_Mem_Level = -1; 00116 Is_Mem_Level_Set = FALSE; 00117 Miss_Penalty = -1; 00118 Miss_Penalty_Set = FALSE; 00119 TLB_CMP_Set = FALSE; 00120 TLB_DMP_Set = FALSE; 00121 TLB_Miss_Penalty = -1; 00122 TLB_MP_Set = FALSE; 00123 00124 return *this; 00125 } 00126 00127 BOOL MHD_LEVEL::Valid() const 00128 { 00129 return Size >= 1 && 00130 Line_Size >= 1 && 00131 (Associativity >= 1 || Type == MHD_TYPE_MEM) && 00132 Clean_Miss_Penalty >= 1 && Dirty_Miss_Penalty >= 1; 00133 } 00134 00135 BOOL MHD_LEVEL::TLB_Valid() const 00136 { 00137 return TLB_Entries >= 1 && 00138 Page_Size >= 1 && 00139 TLB_Clean_Miss_Penalty >= 1 && 00140 TLB_Dirty_Miss_Penalty >= 1 && 00141 Valid(); 00142 } 00143 00144 void MHD_LEVEL::Merge_Options(const MHD_LEVEL& o) 00145 { 00146 BOOL recompute_ecs = FALSE; 00147 00148 if (o.Type != MHD_TYPE_NONE) { 00149 Type = o.Type; 00150 recompute_ecs = TRUE; 00151 } 00152 00153 if (o.Line_Size != -1) { 00154 Line_Size = o.Line_Size; 00155 recompute_ecs = TRUE; 00156 } 00157 if (o.Size != -1) { 00158 Size = o.Size; 00159 recompute_ecs = TRUE; 00160 } 00161 if (o.Associativity != -1) { 00162 Associativity = o.Associativity; 00163 recompute_ecs = TRUE; 00164 } 00165 if (o.Clean_Miss_Penalty != -1) 00166 Clean_Miss_Penalty = o.Clean_Miss_Penalty; 00167 if (o.Dirty_Miss_Penalty != -1) 00168 Dirty_Miss_Penalty = o.Dirty_Miss_Penalty; 00169 00170 if (o.TLB_Entries != -1) 00171 TLB_Entries = o.TLB_Entries; 00172 if (o.Page_Size != -1) 00173 Page_Size = o.Page_Size; 00174 if (o.Prefetch_Level != -1) 00175 Prefetch_Level = o.Prefetch_Level; 00176 if (o.TLB_Clean_Miss_Penalty != -1) 00177 TLB_Clean_Miss_Penalty = o.TLB_Clean_Miss_Penalty; 00178 if (o.TLB_Dirty_Miss_Penalty != -1) 00179 TLB_Dirty_Miss_Penalty = o.TLB_Dirty_Miss_Penalty; 00180 00181 if (o.Typical_Outstanding >= 0.0) 00182 Typical_Outstanding = o.Typical_Outstanding; 00183 if (o.Load_Op_Overlap_1 >= 0.0) 00184 Load_Op_Overlap_1 = o.Load_Op_Overlap_1; 00185 if (o.Load_Op_Overlap_2 >= 0.0) 00186 Load_Op_Overlap_2 = o.Load_Op_Overlap_2; 00187 if (o.Pct_Excess_Writes_Nonhidable >= 0) 00188 Pct_Excess_Writes_Nonhidable = o.Pct_Excess_Writes_Nonhidable; 00189 00190 if (Valid() && recompute_ecs) 00191 Compute_Effective_Size(); 00192 } 00193 00194 void MHD_LEVEL::Compute_Effective_Size() 00195 { 00196 // Make the effective cache fraction increases by 2% per 10x decrease in 00197 // cache size. 5% per 10x decrease in 00198 // line size, and 8% per 10x decrease of assoc. Also, if it drops 00199 // below 7%, move it half way towards 7% and don't let it drop below 00200 // 3.5% (a real anomaly, but the user can specify any oddball cache). 00201 // Basis is 16% for a 64kB direct mapped cache with 16b lines. 00202 00203 // For a memory, the associativity (and all other parameters, come to 00204 // think of it) are ignored, and we use use the effective cache size 00205 // as 90% of the cache. (conservative, in case I miscomputed the area, 00206 // better to err on that side). 00207 00208 double pct; 00209 00210 switch (Type) { 00211 case MHD_TYPE_MEM: 00212 pct = 0.9; 00213 break; 00214 case MHD_TYPE_CACHE: 00215 pct = 0.16 - 0.02*log10(double(Size)/(64*1024)) 00216 - 0.05*log10(double(Line_Size)/16) 00217 + 0.07*log10(double(MIN(Associativity,64))); 00218 00219 if (pct < 0.0) 00220 pct = 0.035; 00221 else if (pct <= 0.07) 00222 pct += (0.07 - pct)/2; 00223 else if (pct > 0.50) 00224 pct = 0.50; 00225 break; 00226 } 00227 00228 Effective_Size = pct*Size; 00229 } 00230 00231 void MHD_LEVEL::Print(FILE* f) const 00232 { 00233 fprintf(f, "sz=%lld(%lld,%.1f%%)\n", 00234 Size, Effective_Size, 100.0*Effective_Size/Size); 00235 fprintf(f, " ls=%d cmp=%d dmp=%d\n", 00236 Line_Size, Clean_Miss_Penalty, Dirty_Miss_Penalty); 00237 if (Type == MHD_TYPE_MEM) 00238 fprintf(f, "<mem> "); 00239 else 00240 fprintf(f, " a=%d ", Associativity); 00241 fprintf(f, "tlbsz=%d ps=%d tlbcmp=%d tlbdmp=%d\n", 00242 TLB_Entries, Page_Size, 00243 TLB_Clean_Miss_Penalty, TLB_Dirty_Miss_Penalty); 00244 fprintf(f, " out=%g, ovlp1=%g, ovlp2=%g\n", 00245 Typical_Outstanding, Load_Op_Overlap_1, Load_Op_Overlap_2); 00246 } 00247 00248 //--------------------------------------------------------------------------- 00249 00250 MHD Mhd; 00251 MHD Mhd_Options; 00252 00253 //--------------------------------------------------------------------------- 00254 00255 INT MHD::Next(INT i) 00256 { 00257 if (i != -1) { 00258 for (i++; i < MHD_MAX_LEVELS; i++) { 00259 if (L[i].Valid()) 00260 return i; 00261 } 00262 } 00263 return -1; 00264 } 00265 00266 INT MHD::First() 00267 { 00268 for (INT i = 0; i < MHD_MAX_LEVELS; i++) { 00269 if (L[i].Valid()) 00270 return i; 00271 } 00272 return -1; 00273 } 00274 00275 void MHD::Merge_Options(const MHD& o) 00276 { 00277 for (INT i = 0; i < MHD_MAX_LEVELS; i++) 00278 L[i].Merge_Options(o.L[i]); 00279 00280 if (o.Non_Blocking_Loads != -1) 00281 Non_Blocking_Loads = o.Non_Blocking_Loads; 00282 if (o.Loop_Overhead_Base >= 0) 00283 Loop_Overhead_Base = o.Loop_Overhead_Base; 00284 if (o.Loop_Overhead_Memref >= 0) 00285 Loop_Overhead_Memref = o.Loop_Overhead_Memref; 00286 } 00287 00288 void MHD::Print(FILE* f) const 00289 { 00290 fprintf(f, "CACHE PARAMETERS: non_blocking_loads=%d loop_overhead=(%d,%d)\n", 00291 Non_Blocking_Loads, Loop_Overhead_Base, Loop_Overhead_Memref); 00292 for (INT i = 0; i < MHD_MAX_LEVELS; i++) { 00293 if (L[i].Valid()) { 00294 fprintf(f, "L[%d]: ", i); 00295 L[i].Print(f); 00296 } 00297 } 00298 fprintf(f, "\n"); 00299 } 00300