00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "c_breeze.h"
00041 #include "liveness.h"
00042
00043 livenessAnalyzer::livenessAnalyzer()
00044 : analysisProblem(Backward),
00045 _live_stmts(),
00046 _live_stmtlocations(),
00047 _live_mergepoints(),
00048 _defs(),
00049 _change(false),
00050 _change_stack(),
00051 _visited_procedures()
00052 {}
00053
00054 void livenessAnalyzer::clear()
00055 {
00056 _live_stmts.clear();
00057 _live_stmtlocations.clear();
00058 _live_mergepoints.clear();
00059 _defs.clear();
00060 _change = false;
00061 _change_stack.clear();
00062 }
00063
00064 bool livenessAnalyzer::isLive(stmtNode * stmt)
00065 {
00066 stmt_liveness_set_p p = _live_stmts.find(stmt);
00067 return (p != _live_stmts.end());
00068 }
00069
00070 void livenessAnalyzer::collectDefs(pointerValue & pointer)
00071 {
00072 for (memoryblock_set_p p = pointer.blocks.begin();
00073 p != pointer.blocks.end();
00074 ++p)
00075 {
00076 memoryBlock * block = *p;
00077 if ( ! block->write_protected()) {
00078 memoryDef * def = block->current_def();
00079 _defs.insert(def);
00080 }
00081 }
00082 }
00083
00084 void livenessAnalyzer::addDef(memoryDef * def)
00085 {
00086 _defs.insert(def);
00087 }
00088
00089 bool livenessAnalyzer::determineLiveness()
00090 {
00091 if (pointerOptions::Verbose_liveness)
00092 cout << " + Determine liveness..." << endl;
00093
00094
00095
00096 for (memorydef_set_p p = _defs.begin();
00097 p != _defs.end();
00098 ++p)
00099 {
00100 memoryDef * def = *p;
00101 memoryBlock * owner = def->owner();
00102
00103 if (pointerOptions::Verbose_liveness)
00104 cout << " - Def of " << owner->name() << " at " << * (def->where()) << endl;
00105
00106
00107
00108 memoryuse_list uses;
00109 owner->def_uses(def, uses);
00110
00111 for (memoryuse_list_p q = uses.begin();
00112 q != uses.end();
00113 ++q)
00114 {
00115 memoryUse * use = *q;
00116
00117
00118
00119 if (isLive(use, owner)) {
00120
00121 if (pointerOptions::Verbose_liveness) {
00122 cout << " + Use at " << * (use->where()) << " is live." << endl;
00123 cout << " => Live" << endl;
00124 }
00125
00126
00127
00128 return true;
00129 }
00130
00131 if (pointerOptions::Verbose_liveness)
00132 cout << " + Use at " << * (use->where()) << " is dead." << endl;
00133 }
00134 }
00135
00136
00137
00138 if (pointerOptions::Verbose_liveness)
00139 cout << " => Dead" << endl;
00140
00141 return false;
00142 }
00143
00144 bool livenessAnalyzer::isLive(memoryUse * use, memoryBlock * owner)
00145 {
00146 Location * where = use->where();
00147 bool is_live = true;
00148
00149 switch (where->kind()) {
00150
00151 case Location::Procedure:
00152 {
00153
00154
00155 is_live = true;
00156 }
00157 break;
00158
00159 case Location::BasicBlock:
00160 {
00161
00162
00163 basicblockLocation * bb_loc = (basicblockLocation *) where;
00164 mergepoint_pair merge_point(bb_loc, owner);
00165
00166 mergepoint_liveness_set_p p = _live_mergepoints.find(merge_point);
00167 is_live = (p != _live_mergepoints.end());
00168 }
00169 break;
00170
00171 case Location::Statement:
00172 {
00173
00174
00175 stmtLocation * stmt_loc = (stmtLocation *) where;
00176
00177 stmtlocation_liveness_set_p p = _live_stmtlocations.find(stmt_loc);
00178 is_live = (p != _live_stmtlocations.end());
00179 }
00180 break;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 return is_live;
00192 }
00193
00194 void livenessAnalyzer::setLive(Location * where, memoryBlock * block)
00195 {
00196 pair< mergepoint_liveness_set_p, bool > result = _live_mergepoints.insert(mergepoint_pair(where, block));
00197
00198
00199
00200 if (result.second)
00201 _change = true;
00202 }
00203
00204
00205 void livenessAnalyzer::setLive(stmtLocation * stmt_loc)
00206 {
00207 pair< stmtlocation_liveness_set_p, bool > result = _live_stmtlocations.insert(stmt_loc);
00208
00209
00210
00211 if (result.second) {
00212 _change = true;
00213
00214 if (pointerOptions::Verbose_liveness)
00215 cout << " + Live statement at " << * stmt_loc << endl;
00216 }
00217
00218
00219
00220 _live_stmts.insert(stmt_loc->stmt());
00221 }
00222
00223 void livenessAnalyzer::at_index(stmtLocation * current,
00224 operandNode * operand,
00225 pointerValue & left,
00226 pointerValue & right,
00227 pointerValue & result)
00228 {
00229 setLive(current);
00230 }
00231
00232
00233
00234 void livenessAnalyzer::at_call(stmtLocation * current, operandNode * call,
00235 pointerValue & call_target,
00236 procNode * callee,
00237 pointervalue_list & arguments,
00238 pointerValue & return_val)
00239 {
00240
00241
00242 setLive(current);
00243 }
00244
00245
00246
00247 void livenessAnalyzer::at_assignment(stmtLocation * current,
00248 pointerValue & left,
00249 pointerValue & right,
00250 pointerValue & result,
00251 memoryblock_set & changes)
00252 {
00253 collectDefs(left);
00254 }
00255
00256
00257
00258 void livenessAnalyzer::at_return(stmtLocation * stmt,
00259 returnNode * ret,
00260 pointerValue & result,
00261 pointerValue & return_val)
00262 {
00263
00264
00265 setLive(stmt);
00266 }
00267
00268 void livenessAnalyzer::at_threeAddr(stmtLocation * stmt,
00269 threeAddrNode *threeaddr,
00270 pointerValue & result)
00271 {
00272
00273
00274
00275 if (determineLiveness())
00276 setLive(stmt);
00277 }
00278
00279 void livenessAnalyzer::at_conditiongoto(stmtLocation * stmt,
00280 conditiongotoNode * c,
00281 pointerValue & result)
00282 {
00283
00284
00285 setLive(stmt);
00286 }
00287
00288
00289
00290 void livenessAnalyzer::at_allocation(stmtLocation * stmt,
00291 pointervalue_list & arguments,
00292 memoryBlock * block,
00293 memoryblock_set & changes)
00294 {
00295 setLive(stmt);
00296 }
00297
00298 void livenessAnalyzer::at_deallocation(stmtLocation * stmt,
00299 pointerValue & to_deallocate,
00300 memoryblock_set & changes)
00301 {
00302 setLive(stmt);
00303 }
00304
00305
00306
00307 void livenessAnalyzer::at_merge(Location * where,
00308 memoryBlock * block,
00309 memoryuse_list & phi_uses,
00310 pointerValue & result,
00311 memoryblock_set & changes)
00312 {
00313
00314
00315 _defs.clear();
00316 _defs.insert(block->current_def());
00317
00318 if (determineLiveness())
00319 setLive(where, block);
00320 }
00321
00322
00323
00324 void livenessAnalyzer::at_stmt_exit(stmtLocation * stmt,
00325 pointerValue & result)
00326 {
00327
00328
00329 _defs.clear();
00330 }
00331
00332 void livenessAnalyzer::at_basicblock_entry(basicblockLocation * blockloc,
00333 procedureInfo * info,
00334 pointerValue & initial)
00335 {
00336
00337
00338
00339 if (_change) {
00340 info->add_reachable_blocks(blockloc->block(), Backward);
00341 _change = false;
00342 }
00343 }
00344
00345
00346
00347 void livenessAnalyzer::at_procedure_entry(procLocation * proc,
00348 procedureInfo * info,
00349 pointerValue & return_val)
00350 {
00351
00352
00353 _change = _change_stack.front();
00354 _change_stack.pop_front();
00355
00356
00357
00358 _visited_procedures.insert(info->proc());
00359 }
00360
00361 void livenessAnalyzer::at_procedure_exit(procLocation * proc,
00362 procedureInfo * info,
00363 pointerValue & return_val)
00364 {
00365
00366
00367 _change_stack.push_front(_change);
00368 _change = false;
00369 }
00370
00371
00372
00373 void deadcodeChanger::optimize(unitNode * u,
00374 livenessAnalyzer * liveness)
00375 {
00376 deadcodeChanger ipcc(liveness);
00377
00378
00379
00380
00381 const procedure_set & procs = liveness->visited_procedures();
00382
00383 for (procedure_set_cp p = procs.begin();
00384 p != procs.end();
00385 ++p)
00386 {
00387 procNode * proc = *p;
00388
00389 proc->change(ipcc);
00390 }
00391 }
00392
00393 deadcodeChanger::deadcodeChanger(livenessAnalyzer * liveness)
00394 : Changer( Preorder, Subtree, true),
00395 _liveness(liveness)
00396 {}
00397
00398 Node * deadcodeChanger::at_threeAddr(threeAddrNode * stmt, Order ord)
00399 {
00400
00401
00402 if (_liveness->isLive(stmt))
00403 return stmt;
00404 else {
00405
00406
00407
00408 ostringstream ostr;
00409 output_context oc(ostr);
00410 stmt->output(oc, 0);
00411
00412 exprstmtNode * repl = new exprstmtNode((exprNode *)0);
00413 repl->comment() = string("--- DEAD :") + ostr.str();
00414
00415
00416 if (pointerOptions::Verbose_liveness) {
00417 cout << "--- DEAD CODE -------------------------------------" << endl;
00418
00419 output_context oc2(cout);
00420 stmt->output(oc2, 0);
00421 cout << endl;
00422 }
00423
00424 return repl;
00425 }
00426
00427 return stmt;
00428 }
00429