00001
00002 #include "Program.h"
00003 #include "ProgramUnit.h"
00004 #include "Timer.h"
00005 #include "Collection/Iterator.h"
00006 #include "Statement/Statement.h"
00007 #include "Expression/Expression.h"
00008 #include "Symbol/FunctionSymbol.h"
00009 #include "utilities/gsa_util.h"
00010 #include "utilities/switches_util.h"
00011 #include "p-setjmp.h"
00012 #include "HeapStats.h"
00013
00014 #include "AIRangeDict.h"
00015 #include "ControlRangeDict.h"
00016 #include "GSAControlRangeDict.h"
00017 #include "GSAFullRangeDict.h"
00018 #include "RangeAccessor.h"
00019 #include "range.h"
00020
00021 #include "constant/InterProcConstProp.h"
00022
00023 extern int dbx_warn_overflow;
00024
00025 static void
00026 _add_intrinsic(ProgramUnit &pgm, const char *intrin_name)
00027 {
00028 if (! pgm.symtab().find_ref(intrin_name)) {
00029 Symbol *s = new FunctionSymbol(intrin_name, make_type(INTEGER_TYPE),
00030 NOT_EXTERNAL, IS_INTRINSIC, NOT_FORMAL);
00031 pgm.symtab().ins(s);
00032 }
00033 }
00034
00035 void
00036 accessor_test(const ProgramUnit &pgm, RangeDict &ranges)
00037 {
00038 Iterator<Statement> stmt1_iter = pgm.stmts();
00039
00040 for ( ; stmt1_iter.valid(); ++stmt1_iter) {
00041 const Statement &stmt1 = stmt1_iter.current();
00042 Iterator<Statement> stmt2_iter = pgm.stmts();
00043
00044 for ( ; stmt2_iter.valid(); ++stmt2_iter) {
00045 const Statement &stmt2 = stmt2_iter.current();
00046 RangeAccessor accessor(ranges, stmt1, stmt2);
00047 accessor.debug_level(10);
00048 Iterator<Expression> expr1_iter = stmt1.out_refs();
00049
00050 for ( ; expr1_iter.valid(); ++expr1_iter) {
00051 const Expression &expr1 = expr1_iter.current();
00052
00053 if (expr1.op() == ARRAY_REF_OP) {
00054 Iterator<Expression> expr2_iter = stmt2.in_refs();
00055
00056 for ( ; expr2_iter.valid(); ++expr2_iter) {
00057 const Expression &expr2 = expr2_iter.current();
00058
00059 if (expr2.op() == ARRAY_REF_OP
00060 && &expr1.array().symbol() == &expr2.array().symbol()) {
00061 cout << "Testing: "
00062 << stmt1.tag() << ": " << expr1 << " --> "
00063 << stmt2.tag() << ": " << expr2 << endl;
00064 Relation rel = accessor.compare(
00065 expr1.subscript().arg_list()[0],
00066 expr2.subscript().arg_list()[0]);
00067 cout << expr1.subscript().arg_list()[0]
00068 << " " << rel << " "
00069 << expr2.subscript().arg_list()[0] << endl;
00070 accessor.print(cout);
00071 cout << endl;
00072 }
00073 }
00074 }
00075 }
00076 }
00077 }
00078 }
00079
00080 void
00081 print_gsa_control_range_stats(GSAControlRangeDict &ranges)
00082 {
00083 float avg_num_icdoms = 0.0;
00084 int max_num_icdoms = 0;
00085 int tot_num_icdoms = 0;
00086 float avg_num_ranges = 0.0;
00087 int max_num_ranges = 0;
00088 int tot_num_ranges = 0;
00089
00090 ranges.stats(avg_num_icdoms, max_num_icdoms, tot_num_icdoms,
00091 avg_num_ranges, max_num_ranges, tot_num_ranges);
00092
00093 cout << "\n--- Statistics for GSAControlRangeDict ---\n";
00094
00095 cout << "avg. num. icdoms = " << avg_num_icdoms << endl;
00096 cout << "max. num. icdoms = " << max_num_icdoms << endl;
00097 cout << "tot. num. icdoms = " << tot_num_icdoms << endl;
00098
00099 cout << "avg. num. ranges = " << avg_num_ranges << endl;
00100 cout << "max. num. ranges = " << max_num_ranges << endl;
00101 cout << "tot. num. ranges = " << tot_num_ranges << endl;
00102 }
00103
00104 void
00105 print_gsa_data_range_stats(GSAFullRangeDict &ranges,
00106 const ProgramUnit &pgm)
00107 {
00108 ranges.touch();
00109
00110 int max_control_ranges = 0;
00111 int tot_control_ranges = ranges.control_range_dict().num_computed_ranges();
00112 int sum_control_ranges = 0;
00113 int max_data_ranges = 0;
00114 int tot_data_ranges = ranges.num_data_ranges();
00115 int sum_data_ranges = 0;
00116 int max_poisoned_ranges = 0;
00117 int sum_poisoned_ranges = 0;
00118
00119 for (KeyIterator<Symbol,DefLoc> def_iter = pgm.gsa_deflocs_guarded().iterator();
00120 def_iter.valid(); ++def_iter) {
00121
00122 const DefLoc & curr_def = def_iter.current_data();
00123 if (curr_def.stmt_valid()) {
00124
00125 const Symbol &var = def_iter.current_key();
00126
00127 if (var.type().data_type() == INTEGER_TYPE && ! var.is_array()) {
00128 ranges.clear_ranges();
00129 RangeAccessor accessor(ranges, curr_def.stmt_guarded());
00130 accessor.get_range_ref(var);
00131
00132 int num_control_ranges = ranges.control_range_dict().num_computed_ranges();
00133 sum_control_ranges += num_control_ranges;
00134 max_control_ranges = max(max_control_ranges, num_control_ranges);
00135
00136 int num_data_ranges = ranges.num_data_ranges();
00137 sum_data_ranges += num_data_ranges;
00138 max_data_ranges = max(max_data_ranges, num_data_ranges);
00139
00140 int num_poisoned_ranges = ranges.num_poisoned_ranges();
00141 sum_poisoned_ranges += num_poisoned_ranges;
00142 max_poisoned_ranges = max(max_poisoned_ranges, num_poisoned_ranges);
00143 }
00144 }
00145 }
00146
00147 float avg_control_ranges = 0.0;
00148 float avg_data_ranges = 0.0;
00149 float avg_poisoned_ranges = 0.0;
00150
00151 if (tot_data_ranges > 0) {
00152 avg_control_ranges = (float) sum_control_ranges / (float) tot_data_ranges;
00153 avg_data_ranges = (float) sum_data_ranges / (float) tot_data_ranges;
00154 avg_poisoned_ranges = (float) sum_poisoned_ranges / (float) tot_data_ranges;
00155 }
00156
00157 cout << "\n--- Statistics for GSAFullRangeDict ---\n";
00158
00159 cout << "avg. control ranges = " << avg_control_ranges << endl;
00160 cout << "max. control ranges = " << max_control_ranges << endl;
00161 cout << "tot. control ranges = " << tot_control_ranges << endl;
00162
00163 cout << "avg. data ranges = " << avg_data_ranges << endl;
00164 cout << "max. data ranges = " << max_data_ranges << endl;
00165 cout << "tot. data ranges = " << tot_data_ranges << endl;
00166
00167 cout << "avg. poisoned ranges = " << avg_poisoned_ranges << endl;
00168 cout << "max. poisoned ranges = " << max_poisoned_ranges << endl;
00169 }
00170
00171 int
00172 main(int argc, char *argv[])
00173 {
00174 dbx_warn_overflow = 0;
00175
00176 P_ASSERT_HANDLER(0);
00177
00178
00179 char * foobar_ptr;
00180
00181 int index = parse_switches( argc, argv, "snixty-eleven",
00182 &foobar_ptr);
00183
00184 if (index < 0) {
00185 cerr << "Error: can not open switches database, aborting.\n";
00186 exit(1);
00187 }
00188
00189 int debug = 0;
00190
00191 if (index < argc - 1 && strcmp(argv[index], "debug") == 0) {
00192 ++index;
00193 debug = atoi(argv[index]);
00194 ++index;
00195 }
00196
00197 bool test_accessor = false;
00198
00199 if (index < argc && strcmp(argv[index], "accessor") == 0) {
00200 ++index;
00201 test_accessor = true;
00202 }
00203
00204 bool stats = false;
00205
00206 if (index < argc && strcmp(argv[index], "stats") == 0) {
00207 ++index;
00208 stats = true;
00209 }
00210
00211 bool test_gsa = false;
00212
00213 if (index < argc && strcmp(argv[index], "gsa") == 0) {
00214 ++index;
00215 test_gsa = true;
00216 }
00217
00218 bool test_control_range_dict = false;
00219
00220 if (index < argc && strcmp(argv[index], "control") == 0) {
00221 ++index;
00222 test_control_range_dict = true;
00223 }
00224
00225 bool constant = false;
00226
00227 if (index < argc && strcmp(argv[index], "const") == 0) {
00228 ++index;
00229 constant = true;
00230 }
00231
00232 bool no_source = false;
00233
00234 if (index < argc && strcmp(argv[index], "no_source") == 0) {
00235 ++index;
00236 no_source = true;
00237 }
00238
00239 if (index >= argc) {
00240 cerr << "Usage: constant_test [debug <debug level>] <fortran file> ...\n";
00241 exit(1);
00242 }
00243
00244 Timer pgm_timer;
00245 Program bunch_of_pgms;
00246
00247 for (int i = index; i < argc; ++i) {
00248 Program *some_pgms = new Program;
00249 some_pgms->read(argv[i]);
00250 bunch_of_pgms.absorb(some_pgms);
00251 }
00252
00253 cout << "Reading in program units: " << pgm_timer << endl;
00254
00255 if (constant) {
00256 Timer const_timer;
00257 InterProcConstProp propagator(bunch_of_pgms,
00258 (PC_REAL_BOOL) switch_value("pc_real"),
00259 (PC_ARRAY_BOOL) switch_value("pc_array"),
00260 0, 0);
00261 propagator.iter_clone_and_propagate((PC_UNREACH_BOOL) switch_value("pc_unreach"));
00262 propagator.expand_all_substituted();
00263
00264 cout << "Propagating constants: " << const_timer << endl;
00265 }
00266
00267 if (stats)
00268 HeapStats::restart();
00269
00270 KeyIterator<String,ProgramUnit> iter = bunch_of_pgms;
00271
00272 for ( ; iter.valid(); ++iter) {
00273 ProgramUnit &pgm = iter.current_data();
00274 Timer timer;
00275
00276 cout << "Program unit: " << pgm.routine_name_ref() << endl;
00277 cout << "Number of statements = " << pgm.stmts().entries() << endl;
00278
00279 timer.reset();
00280
00281 if (stats) {
00282 collect_range_stats();
00283 _add_intrinsic(pgm, "MIN");
00284 _add_intrinsic(pgm, "MAX");
00285 _add_intrinsic(pgm, "MOD");
00286 HeapStats::reset();
00287 }
00288
00289 RangeDict *ranges = 0;
00290
00291 if (test_gsa) {
00292 if (stats)
00293 HeapStats::stop();
00294
00295 MakeGSA(pgm);
00296
00297 if (stats)
00298 HeapStats::restart();
00299
00300 cout << "converting to GSA: " << timer << endl;
00301 cout << "Number of GSA statements = " << pgm.stmts().entries() << endl;
00302 timer.reset();
00303
00304 if (test_control_range_dict) {
00305 ranges = new GSAControlRangeDict(pgm, debug);
00306
00307 cout << "initializing range dict: " << timer << endl;
00308 timer.reset();
00309
00310 ((GSAControlRangeDict *) ranges)->icdom_touch();
00311 cout << "computing icdoms: " << timer << endl;
00312 timer.reset();
00313
00314 ((GSAControlRangeDict *) ranges)->touch();
00315 cout << "computing ranges: " << timer << endl;
00316
00317 print_gsa_control_range_stats(* ((GSAControlRangeDict *) ranges));
00318 }
00319 else {
00320 ranges = new GSAFullRangeDict(pgm, debug);
00321
00322 cout << "initializing range dict: " << timer << endl;
00323 timer.reset();
00324
00325 ((GSAFullRangeDict *) ranges)->control_touch();
00326 cout << "computing control ranges: " << timer << endl;
00327 timer.reset();
00328
00329 ((GSAFullRangeDict *) ranges)->data_touch();
00330 cout << "computing data ranges: " << timer << endl;
00331 timer.reset();
00332
00333 ((GSAFullRangeDict *) ranges)->touch();
00334 cout << "merging control and data ranges: " << timer << endl;
00335
00336 print_gsa_control_range_stats(((GSAFullRangeDict *) ranges)->control_range_dict());
00337 print_gsa_data_range_stats(* (GSAFullRangeDict *) ranges, pgm);
00338
00339 if (! no_source)
00340 ((GSAFullRangeDict *) ranges)->touch();
00341 }
00342
00343 if (debug >= 5)
00344 ranges->print(cout);
00345
00346 if (! no_source) {
00347 cout << "\n----- Ranges:\n\n";
00348 ranges->pretty_print(cout, pgm.stmts());
00349 }
00350
00351 if (test_accessor) {
00352 cout << "\n----- Accessor test:\n\n";
00353 accessor_test(pgm, *ranges);
00354 }
00355
00356 if (stats)
00357 HeapStats::stop();
00358
00359 DeGSA(pgm);
00360
00361 if (stats)
00362 HeapStats::restart();
00363 }
00364 else {
00365 if (test_control_range_dict)
00366 ranges = new ControlRangeDict(pgm, debug);
00367 else
00368 ranges = new AIRangeDict(pgm, debug);
00369
00370 cout << "propagating ranges: " << timer << endl;
00371
00372 if (! no_source) {
00373 cout << "\n----- Ranges:\n\n";
00374 ranges->pretty_print(cout, pgm.stmts());
00375 }
00376
00377 if (test_accessor) {
00378 cout << "\n----- Accessor test:\n\n";
00379 accessor_test(pgm, *ranges);
00380 }
00381 }
00382
00383 delete ranges;
00384
00385 if (stats) {
00386 cout << "\n----- Statistics:\n\n";
00387 print_range_stats(cout);
00388 stop_range_stats();
00389 HeapStats::report(cout);
00390 }
00391 }
00392
00393 return 0;
00394 }
00395