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 "print_walker.h"
00042 #include "constants.h"
00043
00044 constantAnalyzer::constantAnalyzer()
00045 : _schar_constants(),
00046 _uchar_constants(),
00047 _sshort_constants(),
00048 _ushort_constants(),
00049 _sint_constants(),
00050 _uint_constants(),
00051 _slong_constants(),
00052 _ulong_constants(),
00053 _float_constants(),
00054 _double_constants(),
00055 _null(0),
00056 _top(new constant()),
00057 _bottom(new constant()),
00058 _non_null(new constant()),
00059 _expr_values()
00060 {}
00061
00062 void constantAnalyzer::clear()
00063 {
00064 _expr_values.clear();
00065 }
00066
00067 constantAnalyzer::~constantAnalyzer()
00068 {
00069
00070
00071
00072
00073
00074 delete _top;
00075 delete _bottom;
00076 delete _non_null;
00077 }
00078
00083 bool constantAnalyzer::has_truth_value(const constant * val, bool & value)
00084 {
00085 if (val == _non_null) {
00086 value = true;
00087 return true;
00088 }
00089
00090 if ((val == _top) ||
00091 (val == _bottom))
00092 {
00093 return false;
00094 }
00095
00096
00097 value = val->Boolean();
00098 return true;
00099 }
00100
00101 const constant * constantAnalyzer::lookup(const constant & value)
00102 {
00103 pair< constant_set_p, bool > result;
00104
00105 bool found_type = false;
00106
00107 const basic_type & bt = value.basic();
00108
00109 if (bt == basic_type::SChar) {
00110 result = _schar_constants.insert(value);
00111 found_type = true;
00112 }
00113
00114 if (bt == basic_type::UChar) {
00115 result = _uchar_constants.insert(value);
00116 found_type = true;
00117 }
00118
00119 if (bt == basic_type::SShort) {
00120 result = _sshort_constants.insert(value);
00121 found_type = true;
00122 }
00123
00124 if (bt == basic_type::UShort) {
00125 result = _ushort_constants.insert(value);
00126 found_type = true;
00127 }
00128
00129 if (bt == basic_type::SInt) {
00130 result = _sint_constants.insert(value);
00131 found_type = true;
00132 }
00133
00134 if (bt == basic_type::UInt) {
00135 result = _uint_constants.insert(value);
00136 found_type = true;
00137 }
00138
00139 if (bt == basic_type::SLong) {
00140 result = _slong_constants.insert(value);
00141 found_type = true;
00142 }
00143
00144 if (bt == basic_type::ULong) {
00145 result = _ulong_constants.insert(value);
00146 found_type = true;
00147 }
00148
00149 if (bt == basic_type::Float) {
00150 result = _float_constants.insert(value);
00151 found_type = true;
00152 }
00153
00154 if (bt == basic_type::Double) {
00155 result = _double_constants.insert(value);
00156 found_type = true;
00157 }
00158
00159 if (found_type) {
00160 constant_set_p p = result.first;
00161 return & (*p);
00162 }
00163 else
00164 return _bottom;
00165 }
00166
00167 const constant * constantAnalyzer::lookup_flowvalue(memoryDef * def)
00168 {
00169
00170
00171 if (def == 0)
00172 return _bottom;
00173
00174
00175
00176 const constant * result = def->value();
00177
00178 if ( ! result)
00179 result = _bottom;
00180
00181
00182
00183 const memoryblock_set & points_to = def->points_to();
00184
00185 if (points_to.size() > 0)
00186 result = evaluate_points_to(points_to);
00187
00188 return result;
00189 }
00190
00191 bool constantAnalyzer::update_flowvalue(const constant * val, memoryDef * def)
00192 {
00193 bool change = false;
00194
00195
00196
00197
00198
00199
00200 const constant * old = def->value();
00201
00202 if ( ! old)
00203 old = _top;
00204
00205
00206
00207 if (! val)
00208 val = _top;
00209
00210
00211
00212
00213 const constant * res = meet(val, old);
00214
00215 if (res != _top) {
00216 def->set_value(res);
00217 change = (old != res);
00218
00219 if (pointerOptions::Verbose_constants) {
00220 cout << " + Update value of " << def->owner()->name()
00221 << ": old = " << to_string(old)
00222 << ", new = " << to_string(val)
00223 << ", res = " << to_string(res) << endl;
00224 }
00225 }
00226
00227 return change;
00228 }
00229
00230 const constant * constantAnalyzer::meet(const constant * one, const constant * two)
00231 {
00232
00233
00234 if ((one == _bottom) ||
00235 (two == _bottom))
00236 return _bottom;
00237
00238
00239
00240 if (one == _top)
00241 return two;
00242
00243 if (two == _top)
00244 return one;
00245
00246
00247
00248 if ((one == _non_null) &&
00249 (two == _non_null))
00250 return _non_null;
00251
00252
00253
00254 if (one == _non_null) {
00255 if (two->is_zero())
00256 return _bottom;
00257 else
00258 return _non_null;
00259 }
00260
00261 if (two == _non_null) {
00262 if (one->is_zero())
00263 return _bottom;
00264 else
00265 return _non_null;
00266 }
00267
00268
00269
00270 if (one == two)
00271 return one;
00272
00273 return _bottom;
00274 }
00275
00276 const constant * constantAnalyzer::rebuild_flowvalue(pointerValue & pointer)
00277 {
00278 const constant * result = _top;
00279
00280 if (pointerOptions::Verbose_constants)
00281 cout << " + Rebuild constant:" << endl;
00282
00283 if (pointer.is_address)
00284 result = evaluate_points_to(pointer.blocks);
00285 else
00286 if (pointer.blocks.empty())
00287 result = _bottom;
00288 else {
00289 for (memoryblock_set_p p = pointer.blocks.begin();
00290 p != pointer.blocks.end();
00291 ++p)
00292 {
00293 memoryBlock * block = *p;
00294
00295 if (block->decl()->decl_location() == declNode::ENUM) {
00296 declNode * ed = block->decl();
00297 exprNode * in = ed->init();
00298 if (! in)
00299 cout << "No init for " << block->name() << " decl = 0x" << ed << endl;
00300 else {
00301 const constant * enum_val = lookup(in->value());
00302
00303 if (pointerOptions::Verbose_constants)
00304 cout << " - Enum " << block->name() << " = " << to_string(enum_val) << endl;
00305
00306 result = meet(result, enum_val);
00307 }
00308 }
00309 else {
00310
00311 memoryUse * use = block->current_use();
00312 if (use) {
00313
00314
00315
00316 const constant * val = 0;
00317
00318 memoryDef * def = use->reaching_def();
00319 if (def)
00320 val = lookup_flowvalue(def);
00321 else
00322 val = bottom();
00323
00324
00325
00326 result = meet(result, val);
00327
00328 if (pointerOptions::Verbose_constants) {
00329 cout << " - Value of " << block->name() << " = " << to_string(val) << endl;
00330 cout << " + use at " << * (use->where());
00331
00332 if (def)
00333 cout << " def at " << * (def->where()) << endl;
00334 else
00335 cout << " (no def)" << endl;
00336 }
00337 }
00338 }
00339 }
00340 }
00341
00342 if (pointerOptions::Verbose_constants)
00343 cout << " => " << to_string(result) << endl;
00344
00345 return result;
00346 }
00347
00348 void constantAnalyzer::record_expression(exprNode * expr, const constant * val)
00349 {
00350 if (val && (val != _top)) {
00351 expr_value_map_p p = _expr_values.find(expr);
00352 if (p == _expr_values.end())
00353 _expr_values[expr] = val;
00354 else
00355 _expr_values[expr] = meet((*p).second, val);
00356
00357 if (pointerOptions::Verbose_constants) {
00358
00359 const constant * newval = _expr_values[expr];
00360
00361 cout << " + Record constant expression = " << to_string(val) << endl;
00362 cout << " - Accumulated value = " << to_string(newval) << endl;
00363 }
00364 }
00365 }
00366
00367 void constantAnalyzer::record_stmt(stmtNode * stmt, const constant * val)
00368 {
00369 if (val && (val != _top)) {
00370 stmt_value_map_p p = _stmt_values.find(stmt);
00371 if (p == _stmt_values.end())
00372 _stmt_values[stmt] = val;
00373 else
00374 _stmt_values[stmt] = meet((*p).second, val);
00375
00376 if (pointerOptions::Verbose_constants) {
00377
00378 const constant * newval = _stmt_values[stmt];
00379
00380 cout << " + Record constant expression = " << to_string(val) << endl;
00381 cout << " - Accumulated value = " << to_string(newval) << endl;
00382 }
00383 }
00384 }
00385
00395 const constant * constantAnalyzer::evaluate_points_to(const memoryblock_set & points_to)
00396 {
00397
00398
00399 bool points_to_null = false;
00400 bool points_to_heap = false;
00401
00402 for (memoryblock_set_cp p = points_to.begin();
00403 p != points_to.end();
00404 ++p)
00405 {
00406 memoryBlock * target = *p;
00407
00408 if (target == _null)
00409 points_to_null = true;
00410
00411 if (target->is_heap_object())
00412 points_to_heap = true;
00413 }
00414
00415 if (points_to_null &&
00416 (points_to.size() == 1)) {
00417
00418
00419
00420 return lookup(constant(0));
00421 }
00422
00423 if (points_to_heap) {
00424
00425
00426
00427 return _bottom;
00428 }
00429
00430
00431
00432 return _non_null;
00433 }
00434
00435
00436 const constant * constantAnalyzer::lookup_expression(exprNode * expr)
00437 {
00438 expr_value_map_p p = _expr_values.find(expr);
00439
00440 const constant * result = 0;
00441
00442 if (p == _expr_values.end())
00443 result = _bottom;
00444 else
00445 result = (*p).second;
00446
00447 if (pointerOptions::Verbose_constants) {
00448 if (p != _expr_values.end())
00449 cout << " + Lookup constant expression = " << to_string(result) << endl;
00450 }
00451
00452 return result;
00453 }
00454
00455 const constant * constantAnalyzer::lookup_stmt(stmtNode * stmt)
00456 {
00457 stmt_value_map_p p = _stmt_values.find(stmt);
00458
00459 const constant * result = 0;
00460
00461 if (p == _stmt_values.end())
00462 result = _bottom;
00463 else
00464 result = (*p).second;
00465
00466 if (pointerOptions::Verbose_constants) {
00467 if (p != _stmt_values.end())
00468 cout << " + Lookup constant statement = " << to_string(result) << endl;
00469 }
00470
00471 return result;
00472 }
00473
00474
00475
00476 void constantAnalyzer::at_id(stmtLocation * current, idNode * id,
00477 pointerValue & block)
00478 {
00479 const constant * val = rebuild_flowvalue(block);
00480 block.constant_value = val;
00481
00482 if (block.is_a_use)
00483 record_expression(id, val);
00484 }
00485
00486 void constantAnalyzer::at_sizeof(stmtLocation * current,
00487 threeAddrNode *t,
00488 pointerValue & operand,
00489 pointerValue & result)
00490 {
00491 const constant * result_c = _bottom;
00492
00493 typeNode *type = t->sizeof_type();
00494 if(!type && t->rhs1()) type = t->rhs1()->type();
00495
00496 if (type && (type->typ() == Prim)) {
00497 primNode * prim = (primNode *) type;
00498 basic_type & basic = prim->basic();
00499 constant size(basic.size());
00500 result_c = lookup(size);
00501 }
00502 record_stmt(t, result_c);
00503 }
00504
00505 void constantAnalyzer::at_unary(stmtLocation * current,
00506 stmtNode *s,
00507 pointerValue & operand,
00508 pointerValue & result)
00509 {
00510 assert(s->typ() == Condition || s->typ() == ThreeAddr);
00511 Operator *op = s->typ()==Condition ? ((conditiongotoNode*)s)->op() :
00512 ((threeAddrNode*)s)->op();
00513 assert(op && op->is_unary());
00514 assert (op->id() != Operator::SIZEOF);
00515
00516 const constant * result_c = _bottom;
00517 const constant * operand_c = operand.constant_value;
00518
00519 if (operand_c == _non_null) {
00520
00521
00522
00523 if (op->id() == '!') {
00524
00525
00526
00527 result_c = lookup(constant(0));
00528 }
00529 else {
00530
00531
00532
00533 result_c = _bottom;
00534 }
00535 }
00536 else {
00537
00538
00539
00540 if ((operand_c == _bottom) ||
00541 (operand_c == _top))
00542 result_c = operand_c;
00543 else {
00544
00545
00546
00547 constant unary_result = constant::eval(op, * operand_c);
00548 result_c = lookup(unary_result);
00549 }
00550 }
00551
00552 result.constant_value = result_c;
00553
00554 if (result.is_a_use)
00555 if(s) record_stmt(s, result_c);
00556 }
00557
00558 void constantAnalyzer::at_binary(stmtLocation * current,
00559 stmtNode *s,
00560 pointerValue & left,
00561 pointerValue & right,
00562 pointerValue & result)
00563 {
00564 const constant * result_c = _bottom;
00565 const constant * left_c = left.constant_value;
00566 const constant * right_c = right.constant_value;
00567
00568 assert(s->typ() == Condition || s->typ() == ThreeAddr);
00569 Operator *op = s->typ()==Condition ? ((conditiongotoNode*)s)->op() :
00570 ((threeAddrNode*)s)->op();
00571 assert(op && ! op->is_unary());
00572
00573 if ((left_c == _non_null) ||
00574 (right_c == _non_null))
00575 {
00576
00577
00578 switch (op->id()) {
00579
00580 case '+':
00581 case '-':
00582
00583
00584
00585 result_c = _non_null;
00586 break;
00587
00588 case Operator::EQ:
00589
00590
00591
00592
00593 if (left_c->is_zero() ||
00594 right_c->is_zero())
00595 result_c = lookup(constant(0));
00596 else
00597 result_c = _bottom;
00598 break;
00599
00600 case Operator::NE:
00601
00602
00603
00604
00605 if (left_c->is_zero() ||
00606 right_c->is_zero())
00607 result_c = lookup(constant(1));
00608 else
00609 result_c = _bottom;
00610 break;
00611
00612 default:
00613 result_c = _bottom;
00614 }
00615 }
00616 else
00617 {
00618
00619
00620 if ((left_c != _bottom) &&
00621 (left_c != _top) &&
00622 (right_c != _bottom) &&
00623 (right_c != _top))
00624 {
00625 if ((op->id() == '/') &&
00626 right_c->is_zero())
00627 {
00628
00629
00630
00631
00632
00633
00634 }
00635 else {
00636
00637
00638
00639 constant binary_result = constant::eval(op, *left_c, *right_c);
00640 result_c = lookup(binary_result);
00641 }
00642 }
00643 }
00644
00645 result.constant_value = result_c;
00646
00647 if (result.is_a_use)
00648 if(s) record_stmt(s, result_c);
00649 }
00650
00651
00652 void constantAnalyzer::at_const(stmtLocation * current, constNode * cons,
00653 pointerValue & result)
00654 {
00655
00656
00657 if (cons->value().is_str()) {
00658 if (pointerOptions::Verbose_constants)
00659 cout << "String constant; skipping" << endl;
00660 result.constant_value = _bottom;
00661 }
00662 else {
00663 typeNode * type = cons->type();
00664 if (type->typ() == Prim) {
00665
00666 primNode * prim = (primNode *) type;
00667 result.constant_value = lookup(constant::cast(prim->basic(), cons->value()));
00668 }
00669 else
00670 result.constant_value = lookup(cons->value());
00671 }
00672 }
00673
00674
00675
00676 void constantAnalyzer::at_address(stmtLocation * current,
00677 operandNode * operand,
00678 pointerValue & result) {
00679 if(operand->addr())
00680 result.constant_value = _bottom;
00681 }
00682
00683 void constantAnalyzer::at_cast(stmtLocation * current,
00684 operandNode * operand,
00685 pointerValue & operand_val,
00686 pointerValue & result) {
00687 if(! operand->cast()) return;
00688
00689 const constant * result_c = _bottom;
00690 const constant * operand_c = operand_val.constant_value;
00691
00692
00693 if (operand_c) {
00694
00695
00696
00697 if (operand_c == _non_null)
00698 {
00699 result_c = _non_null;
00700 }
00701 else {
00702
00703
00704
00705 if ((operand_c == _bottom) ||
00706 (operand_c == _top))
00707 result_c = operand_c;
00708 else {
00709
00710
00711
00712 typeNode * type = operand->cast();
00713
00714 if (type->typ() == Prim) {
00715 primNode * prim = (primNode *) type;
00716 constant cast_result = constant::cast(prim->basic(), * operand_c);
00717 result_c = lookup(cast_result);
00718 }
00719 else
00720 result_c = operand_c;
00721 }
00722 }
00723 }
00724
00725 result.constant_value = result_c;
00726
00727 if (result.is_a_use)
00728 record_expression(operand, result_c);
00729 }
00730
00731
00732 void constantAnalyzer::at_dereference(stmtLocation * current,
00733 operandNode * operand,
00734 pointerValue & result) {
00735 if(operand->star()) {
00736 const constant * val = rebuild_flowvalue(result);
00737 result.constant_value = val;
00738
00739 if (result.is_a_use)
00740 record_expression(operand, val);
00741 }
00742 }
00743
00744
00745 void constantAnalyzer::at_field_access(stmtLocation * current,
00746 operandNode * operand,
00747 pointerValue & result) {
00748 if(! operand->fields().empty()) {
00749 const constant * val = rebuild_flowvalue(result);
00750 result.constant_value = val;
00751
00752 if (result.is_a_use)
00753 record_expression(operand, val);
00754 }
00755 }
00756
00757
00758 void constantAnalyzer::at_index(stmtLocation * current,
00759 operandNode * operand,
00760 pointerValue & result) {
00761 if(operand->index()) {
00762 const constant * val = rebuild_flowvalue(result);
00763 result.constant_value = val;
00764
00765 if (result.is_a_use)
00766 record_expression(operand, val);
00767 }
00768 }
00769
00770
00771
00772 void constantAnalyzer::at_assignment(stmtLocation * current,
00773 pointerValue & left,
00774 pointerValue & right,
00775 pointerValue & result,
00776 memoryblock_set & changes)
00777 {
00778 const constant * right_c = right.constant_value;
00779
00780 if (! right_c)
00781 right_c = _bottom;
00782
00783 result.constant_value = right_c;
00784
00785 for (memoryblock_set_p p = left.blocks.begin();
00786 p != left.blocks.end();
00787 ++p)
00788 {
00789 memoryBlock * block = *p;
00790
00791
00792
00793 if ( ! block->write_protected()) {
00794
00795 memoryDef * def = block->current_def();
00796
00797 const constant * newval = _top;
00798
00799 if (def->is_weak()) {
00800
00801 memoryUse * weak_use = block->current_use();
00802 memoryDef * previous_def = weak_use->reaching_def();
00803
00804 if (previous_def)
00805 newval = meet(right_c, lookup_flowvalue(previous_def));
00806 else
00807 newval = right_c;
00808 }
00809 else {
00810 newval = right_c;
00811 }
00812
00813 bool change = update_flowvalue(newval, def);
00814
00815 if (change)
00816 changes.insert(block);
00817 }
00818 }
00819 }
00820
00821 void constantAnalyzer::at_self_assignment(Location * source,
00822 Location * target,
00823 memoryBlock * block,
00824 memoryblock_set & changes)
00825 {
00826
00827 if ( ! block->write_protected()) {
00828
00829
00830
00831
00832 pointerValue temp(block);
00833 const constant * cur_val = rebuild_flowvalue(temp);
00834
00835
00836
00837
00838 memoryDef * def = block->current_def();
00839
00840 const constant * newval = _top;
00841
00842 if (def->is_weak()) {
00843
00844
00845 memoryUse * weak_use = block->current_use();
00846 memoryDef * previous_def =weak_use->reaching_def();
00847
00848 if (previous_def)
00849 newval = meet(cur_val, lookup_flowvalue(previous_def));
00850 else
00851 newval = cur_val;
00852 }
00853 else {
00854 newval = cur_val;
00855 }
00856
00857 bool change = update_flowvalue(newval, def);
00858
00859 if (change) {
00860 changes.insert(block);
00861 }
00862 }
00863 }
00864
00865
00866 void constantAnalyzer::at_parameter_pass(Location * current,
00867 pointerValue & left,
00868 pointerValue & right,
00869 memoryblock_set & changes)
00870 {
00871 if (right.is_address)
00872 return;
00873
00874 const constant * right_c = right.constant_value;
00875
00876 if (! right_c)
00877 right_c = _top;
00878
00879 for (memoryblock_set_p p = left.blocks.begin();
00880 p != left.blocks.end();
00881 ++p)
00882 {
00883 memoryBlock * block = *p;
00884 memoryDef * def = block->current_def();
00885
00886 if (def) {
00887
00888 bool change = update_flowvalue(right_c, def);
00889
00890 if (change) {
00891 changes.insert(block);
00892 }
00893 }
00894 else {
00895
00896
00897 }
00898 }
00899 }
00900
00901
00902
00903 void constantAnalyzer::at_return(stmtLocation * stmt,
00904 returnNode * ret,
00905 pointerValue & result,
00906 pointerValue & return_val)
00907 {
00908 return_val.constant_value = result.constant_value;
00909 }
00910
00911
00912
00913 void constantAnalyzer::at_merge(Location * where,
00914 memoryBlock * block,
00915 memoryuse_list & phi_uses,
00916 pointerValue & result,
00917 memoryblock_set & changes)
00918 {
00919 memoryDef * def = block->current_def();
00920
00921 const constant * merged_val = _top;
00922
00923 for (memoryuse_list_p p = phi_uses.begin();
00924 p != phi_uses.end();
00925 ++p)
00926 {
00927 memoryUse * phi_use = *p;
00928 memoryDef * reaching_def = phi_use->reaching_def();
00929
00930 if (reaching_def)
00931 merged_val = meet(merged_val, lookup_flowvalue(reaching_def));
00932 }
00933
00934 bool change = update_flowvalue(merged_val, def);
00935
00936 if (change) {
00937 changes.insert(block);
00938 }
00939 }
00940
00941
00942
00943 void constantAnalyzer::at_basicblock_entry(basicblockLocation * block,
00944 procedureInfo * info,
00945 pointerValue & initial)
00946 {
00947 initial.constant_value = _top;
00948 }
00949
00950 void constantAnalyzer::at_stmt_entry(stmtLocation * stmt,
00951 pointerValue & result)
00952 {
00953 result.constant_value = _top;
00954 }
00955
00956
00957
00958 void constantAnalyzer::at_conservative_procedure_call(stmtLocation * current,
00959 operandNode * call,
00960 operand_list & args,
00961 pointerValue & call_target,
00962 pointervalue_list & arguments,
00963 memoryblock_set & reachable_blocks,
00964 pointerValue & return_val,
00965 memoryblock_set & changes)
00966 {
00967
00968
00969
00970 for (memoryblock_set_p p = reachable_blocks.begin();
00971 p != reachable_blocks.end();
00972 ++p)
00973 {
00974 memoryBlock * block = *p;
00975
00976 if ( ! block->write_protected()) {
00977
00978 memoryDef * def = block->current_def();
00979
00980 bool change = update_flowvalue(bottom(), def);
00981
00982 if (change) {
00983 changes.insert(block);
00984 }
00985 }
00986 }
00987 }
00988
00989
00990
00991
00992
00993 constantsChanger::constantsChanger(constantAnalyzer * constants,
00994 bool simplify)
00995 : Changer( Postorder, Subtree, true),
00996 _constants(constants),
00997 _simplify(simplify)
00998 {}
00999
01000 Node * constantsChanger::at_id(idNode * id, Order ord)
01001 {
01002
01003
01004 const constant * val = _constants->lookup_expression(id);
01005
01006
01007
01008 if (_constants->has_value(val))
01009 {
01010
01011
01012 if (pointerOptions::Verbose_constants) {
01013 cout << "--- Replace constant -----------------------------------" << endl;
01014 output_context oc(cout);
01015 id->output(oc,0);
01016 cout << endl;
01017 cout << val->to_string() << endl;
01018 }
01019
01020 return new constNode( *val );
01021 }
01022 else {
01023
01024
01025
01026
01027
01028 id->eval();
01029 if ( ! id->value().no_val()) {
01030 constNode * out = new constNode(id->value());
01031 return out;
01032 }
01033 }
01034
01035 return id;
01036 }
01037
01038
01039 Node * constantsChanger::at_threeAddr(threeAddrNode * t, Order ord)
01040 {
01041
01042
01043 const constant * val = _constants->lookup_stmt(t);
01044
01045
01046
01047 if (_constants->has_value(val))
01048 {
01049
01050
01051 if (pointerOptions::Verbose_constants) {
01052 cout << "--- Replace constant -----------------------------------" << endl;
01053 output_context oc(cout);
01054 if(t->rhs1()) {
01055 if(! t->rhs2() && t->op()) {
01056 oc << t->op()->print(); oc.space();
01057 }
01058 t->rhs1()->output(oc,0);
01059 if(t->rhs2()) {
01060 oc.space(); oc << t->op()->print(); oc.space();
01061 t->rhs2()->output(oc,0);
01062 }
01063 }
01064 cout << endl;
01065 cout << val->to_string() << endl;
01066 }
01067
01068 operandNode *rhs = t->rhs1();
01069 rhs->var( new constNode( *val ) );
01070 rhs->star(false); rhs->addr(false); rhs->fields().clear();
01071 rhs->index(NULL);
01072 t->rhs2(NULL); t->op(NULL); t->sizeof_type(NULL);
01073 }
01074 else {
01075
01076
01077
01078
01079
01080 exprNode *expr = NULL;
01081 if(t->rhs1()) {
01082 if(! t->rhs2()) {
01083 if(t->op())
01084 expr = new unaryNode(t->op()->id(), t->rhs1());
01085 else
01086 expr = t->rhs1();
01087 } else if(t->rhs2())
01088 expr = new binaryNode(t->op()->id(), t->rhs1(), t->rhs2());
01089 }
01090
01091 if(expr) {
01092 expr->eval();
01093 if ( ! expr->value().no_val()) {
01094 operandNode *rhs = t->rhs1();
01095 rhs->var( new constNode( *val ) );
01096 rhs->star(false); rhs->addr(false); rhs->fields().clear();
01097 rhs->index(NULL);
01098 t->rhs2(NULL); t->op(NULL); t->sizeof_type(NULL);
01099 }
01100 if(expr != t->rhs1()) delete expr;
01101 }
01102 }
01103
01104 return t;
01105 }
01106
01107
01108 Node * constantsChanger::at_conditiongoto(conditiongotoNode * C, Order ord)
01109 {
01110
01111
01112 if ( ! _simplify)
01113 return C;
01114
01115
01116
01117 const constant * val = _constants->lookup_stmt(C);
01118
01119 bool is_constant = false;
01120 bool which_branch;
01121
01122
01123
01124 if (_constants->has_truth_value(val, which_branch))
01125 {
01126
01127
01128 is_constant = true;
01129 }
01130 else {
01131
01132
01133
01134
01135 exprNode * expr = NULL;
01136 if(C->left()) {
01137 if(! C->right()) {
01138 if(C->op())
01139 expr = new unaryNode(C->op()->id(), C->left());
01140 else
01141 expr = C->left();
01142 } else if(C->right())
01143 expr = new binaryNode(C->op()->id(), C->left(), C->right());
01144 }
01145
01146 if(expr) {
01147 expr->eval();
01148 if ( ! expr->value().no_val()) {
01149 is_constant = true;
01150 which_branch = expr->value().Boolean();
01151 }
01152 if(expr != C->left()) delete expr;
01153 }
01154 }
01155
01156
01157
01158
01159 if (is_constant) {
01160 if (! which_branch)
01161 return new exprstmtNode(0);
01162
01163 return new gotoNode(C->label(), C->coord());
01164 } else
01165 return C;
01166 }