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
00041 #ifndef CBZ_CONSTANTS_H
00042 #define CBZ_CONSTANTS_H
00043
00044 #include "pointeroptions.h"
00045 #include "location.h"
00046 #include "memoryblock.h"
00047 #include "pointervalue.h"
00048
00049 class constantAnalyzer
00050 {
00051 private:
00052
00053 typedef set< constant > constant_set;
00054 typedef constant_set::iterator constant_set_p;
00055
00056 typedef map< exprNode *, const constant * > expr_value_map;
00057 typedef expr_value_map::iterator expr_value_map_p;
00058
00059 typedef map< stmtNode *, const constant * > stmt_value_map;
00060 typedef stmt_value_map::iterator stmt_value_map_p;
00061
00068 TREE constant_set _schar_constants;
00069 TREE constant_set _uchar_constants;
00070 TREE constant_set _sshort_constants;
00071 TREE constant_set _ushort_constants;
00072 TREE constant_set _sint_constants;
00073 TREE constant_set _uint_constants;
00074 TREE constant_set _slong_constants;
00075 TREE constant_set _ulong_constants;
00076 TREE constant_set _float_constants;
00077 TREE constant_set _double_constants;
00078
00083 REF memoryBlock * _null;
00084
00087 const constant * _top;
00088
00091 const constant * _bottom;
00092
00095 const constant * _non_null;
00096
00101 expr_value_map _expr_values;
00102 stmt_value_map _stmt_values;
00103
00104 public:
00105
00108 constantAnalyzer();
00109
00112 ~constantAnalyzer();
00113
00118 void clear();
00119
00125 void set_null_object(memoryBlock * null_object) { _null = null_object; }
00126
00129 inline const constant * top() const { return _top; }
00130
00133 inline const constant * bottom() const { return _bottom; }
00134
00139 inline bool has_value(const constant * val)
00140 {
00141 return ((val != _top) && (val != _bottom) && (val != _non_null));
00142 }
00143
00148 bool has_truth_value(const constant * val, bool & value);
00149
00155 const constant * lookup(const constant & value);
00156
00162 const constant * lookup_flowvalue(memoryDef * def);
00163
00170 bool update_flowvalue(const constant * val, memoryDef * def);
00171
00174 const constant * meet(const constant * one, const constant * two);
00175
00181 const constant * rebuild_flowvalue(pointerValue & pointer);
00182
00185 void record_expression(exprNode * expr, const constant * val);
00186
00189 void record_stmt(stmtNode * stmt, const constant * val);
00190
00200 const constant * evaluate_points_to(const memoryblock_set & points_to);
00201
00202 public:
00203
00206 const constant * lookup_expression(exprNode * expr);
00207 const constant * lookup_stmt(stmtNode * expr);
00208
00209
00210
00211
00212
00213 void at_id(stmtLocation * current, idNode * id,
00214 pointerValue & value);
00215
00216 void at_unary(stmtLocation * current,
00217 stmtNode *t,
00218 pointerValue & operand,
00219 pointerValue & result);
00220
00221 void at_sizeof(stmtLocation * current,
00222 threeAddrNode *t,
00223 pointerValue & operand,
00224 pointerValue & result);
00225
00226 void at_binary(stmtLocation * current,
00227 stmtNode *s,
00228 pointerValue & left,
00229 pointerValue & right,
00230 pointerValue & result);
00231
00232 void at_const(stmtLocation * current, constNode * cons,
00233 pointerValue & result);
00234
00235
00236
00237 void at_address(stmtLocation * current,
00238 operandNode * operand,
00239 pointerValue & result);
00240
00241 void at_cast(stmtLocation * current,
00242 operandNode *operand,
00243 pointerValue & operand_val,
00244 pointerValue & result);
00245
00246 void at_dereference(stmtLocation * current,
00247 operandNode *operand,
00248 pointerValue & result);
00249
00250 void at_field_access(stmtLocation * current,
00251 operandNode *operand,
00252 pointerValue & result);
00253
00254 void at_index(stmtLocation * current,
00255 operandNode *operand,
00256 pointerValue & result);
00257
00258
00259
00260 void at_assignment(stmtLocation * current,
00261 pointerValue & left,
00262 pointerValue & right,
00263 pointerValue & result,
00264 memoryblock_set & changes);
00265
00266 void at_parameter_pass(Location * current,
00267 pointerValue & left,
00268 pointerValue & right,
00269 memoryblock_set & changes);
00270
00271 void at_self_assignment(Location * source,
00272 Location * target,
00273 memoryBlock * block,
00274 memoryblock_set & changes);
00275
00276
00277
00278 void at_return(stmtLocation * stmt,
00279 returnNode * ret,
00280 pointerValue & result,
00281 pointerValue & return_val);
00282
00283
00284
00285 void at_merge(Location * where,
00286 memoryBlock * block,
00287 memoryuse_list & phi_uses,
00288 pointerValue & result,
00289 memoryblock_set & changes);
00290
00291
00292
00293 void at_basicblock_entry(basicblockLocation * block,
00294 procedureInfo * info,
00295 pointerValue & initial);
00296
00297 void at_stmt_entry(stmtLocation * stmt,
00298 pointerValue & result);
00299
00300
00301
00302 void at_conservative_procedure_call(stmtLocation * current,
00303 operandNode * call,
00304 operand_list & args,
00305 pointerValue & call_target,
00306 pointervalue_list & arguments,
00307 memoryblock_set & reachable_blocks,
00308 pointerValue & return_val,
00309 memoryblock_set & changes);
00310
00311
00312
00313 void print(ostream & o, const constant * val) {
00314 if (val == _bottom)
00315 o << "(bottom)";
00316 else
00317 if (val == _top)
00318 o << "(top)";
00319 else {
00320 constant temp = *val;
00321 o << temp.to_string();
00322 }
00323 }
00324
00325 string to_string(const constant * val) {
00326 if (val == _bottom)
00327 return string("(bottom)");
00328 else
00329 if (val == _top)
00330 return string("(top)");
00331 else
00332 if (val == _non_null)
00333 return string("(non-null)");
00334 else {
00335 constant temp = *val;
00336 return temp.to_string();
00337 }
00338 }
00339
00340
00341 private:
00342
00345 void record_change(memoryDef * def);
00346
00347
00348 };
00349
00350
00351 class constantsChanger : public Changer
00352 {
00353 public:
00354
00355 static void optimize(unitNode * u,
00356 constantAnalyzer * constants,
00357 bool simplify)
00358 {
00359 constantsChanger ipcc(constants, simplify);
00360 u->change(ipcc);
00361 }
00362
00363 private:
00364
00367 constantAnalyzer * _constants;
00368
00374 bool _simplify;
00375
00378 constantsChanger(constantAnalyzer * constants, bool simplify);
00379
00380 public:
00381
00382 Node * at_id(idNode * id, Order ord);
00383 Node * at_threeAddr(threeAddrNode * operand, Order ord);
00384 Node * at_conditiongoto(conditiongotoNode * C, Order ord);
00385 };
00386
00387 #endif // CBZ_CONSTANTS_H