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 #include <vector>
00031
00032 #ifdef USE_PCH
00033 #include "be_com_pch.h"
00034 #endif
00035
00036 #include "defs.h"
00037 #include "config.h"
00038 #include "config_opt.h"
00039 #include "stab.h"
00040 #include "wn.h"
00041 #include "pu_info.h"
00042 #include "opt_points_to.h"
00043 #include "opt_alias_rule.h"
00044 #include "opt_points_to_summary.h"
00045
00046 using idmap::ID_MAP;
00047 using std::vector;
00048
00049
00050
00051 void
00052 UNAME_SPACE::Append_new_name (UNIFORM_NAME* name) {
00053
00054 Is_True (_all_names.size () == _next_id-1,
00055 ("next_id-1 should be equal to the size of vector"));
00056
00057 name->Set_unique_id (_next_id++);
00058 _all_names.push_back (name);
00059
00060 switch (name->Type()) {
00061 case UN_NAMED_GLOBAL:
00062 _global_map.Insert (ST_index(name->ST_for_named_global ()), name);
00063 break;
00064
00065 case UN_MALLOC:
00066 case UN_ALLOCA:
00067 _malloc_alloca.push_back (name); break;
00068
00069 case UN_FORMAL:
00070 _formals.push_back (name); break;
00071
00072 case UN_CALLER_LOCAL:
00073 _caller_locals.push_back (name); break;
00074
00075 default:
00076 FmtAssert (FALSE, ("Unknown type %d", (INT)name->Type()));
00077 }
00078 }
00079
00080 UNIFORM_NAME*
00081 UNAME_SPACE::Add_global (ST* st) {
00082 UNIFORM_NAME* na = Get_global (st);
00083 if (na == NULL) {
00084 na = CXX_NEW (UNIFORM_NAME(st, UN_NAMED_GLOBAL), _mp);
00085 Append_new_name (na);
00086 }
00087 return na;
00088 }
00089
00090 UNIFORM_NAME*
00091 UNAME_SPACE::Add_malloc (mUINT64 mallocid) {
00092 UNIFORM_NAME* na = Get_malloc (mallocid);
00093 if (na == NULL) {
00094 na = CXX_NEW(UNIFORM_NAME(mallocid, UN_MALLOC), _mp);
00095 Append_new_name (na);
00096 }
00097 return na;
00098 }
00099
00100 UNIFORM_NAME*
00101 UNAME_SPACE::Add_alloca (mUINT64 allocaid) {
00102 UNIFORM_NAME* na = Get_alloca (allocaid);
00103 if (na == NULL) {
00104 na = CXX_NEW(UNIFORM_NAME(allocaid, UN_ALLOCA), _mp);
00105 Append_new_name (na);
00106 }
00107 return na;
00108 }
00109
00110 void
00111 PT_SET::Copy (PT_SET& that) {
00112
00113 _all_points_to.clear ();
00114
00115 for (PT_VECTOR_ITER iter = that._all_points_to.begin ();
00116 iter != that._all_points_to.end (); iter++) {
00117 POINTS_TO* t = CXX_NEW(POINTS_TO, _mp);
00118 t->Copy_fully(*iter);
00119
00120
00121 _all_points_to.push_back (t);
00122 }
00123 _addr_space = that._addr_space;
00124 _may_or_must = that._may_or_must;
00125 _has_unknown_pt = that._has_unknown_pt;
00126 _certainty = that._certainty;
00127 }
00128
00129 PT_SET::PT_SET(PT_SET& pts, MEM_POOL* mp) :
00130 _mp(mp), _all_points_to(mp) {
00131 Copy (pts);
00132 }
00133
00134
00135 void
00136 PT_SET::Add_points_to (POINTS_TO* pt, PT_CERTAINTY, PT_MAY_OR_MUST) {
00137
00138 POINTS_TO* t = CXX_NEW(POINTS_TO, _mp);
00139 t->Copy_fully(pt);
00140
00141
00142 _all_points_to.push_back (t);
00143
00144
00145 if (pt->Base() == NULL && pt->Malloc_id() == 0) {
00146 _has_unknown_pt = TRUE;
00147 }
00148 }
00149
00150
00151
00152
00153 BOOL
00154 PT_SET::Aliased (ALIAS_RULE* al, POINTS_TO* pt) {
00155
00156 if (Has_unknown_pt ()) { return TRUE; }
00157
00158 for (PT_VECTOR_ITER iter = _all_points_to.begin ();
00159 iter != _all_points_to.end (); iter++) {
00160 if (al->Aliased_Memop (*iter, pt))
00161 return TRUE;
00162 }
00163 return FALSE;
00164 }
00165
00166 void
00167 PT_SET::Meet (POINTS_TO* pt) {
00168 pt->Init();
00169 pt->Set_expr_kind (EXPR_IS_INVALID);
00170
00171 if (Cardinality () != 0) {
00172 PT_VECTOR_ITER iter = _all_points_to.begin ();
00173 pt->Copy_fully (*iter);
00174
00175 for (iter++; iter != _all_points_to.end (); iter++) {
00176 pt->Meet (*iter, NULL);
00177 }
00178 }
00179 }
00180
00181 BOOL
00182 PT_SET::Aliased (ALIAS_RULE* al, PT_SET* pt_set) {
00183
00184 if (Has_unknown_pt() || pt_set->Has_unknown_pt()) {
00185 return TRUE;
00186 }
00187
00188 for (PT_VECTOR_ITER iter = _all_points_to.begin ();
00189 iter != _all_points_to.end (); iter++) {
00190 if (pt_set->Aliased(al, *iter))
00191 return TRUE;
00192 }
00193
00194 return FALSE;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204 class PU_POINTS_TO_SUMMARY_MGR {
00205 private:
00206 ID_MAP<PU_POINTS_TO_SUMMARY*, UINT32> _st_idx_to_summary;
00207 typedef mempool_allocator<PU_POINTS_TO_SUMMARY*> PU_SUM_ALLOC;
00208 vector<PU_POINTS_TO_SUMMARY*, PU_SUM_ALLOC> _summaries;
00209
00210 public:
00211 PU_POINTS_TO_SUMMARY_MGR (void) :
00212 _st_idx_to_summary(256, NULL,
00213 &MEM_src_pool, FALSE),
00214 _summaries (&MEM_src_pool) { _st_idx_to_summary.Init(); }
00215
00216 ~PU_POINTS_TO_SUMMARY_MGR (void) {};
00217
00218 PU_POINTS_TO_SUMMARY* Get (ST* pu_st) {
00219 FmtAssert (ST_class(pu_st) == CLASS_FUNC,
00220 ("symbol '%s' is not function", ST_name(pu_st)));
00221 return _st_idx_to_summary.Lookup (ST_index(pu_st));
00222 }
00223
00224 void Set (ST* pu_st, PU_POINTS_TO_SUMMARY* sum) {
00225 FmtAssert (ST_class(pu_st) == CLASS_FUNC,
00226 ("symbol '%s' is not function", ST_name(pu_st)));
00227 _st_idx_to_summary.Insert (ST_index(pu_st), sum);
00228 }
00229
00230 PU_POINTS_TO_SUMMARY* Allocate_PU_Points_To_Summary (ST* pu) {
00231 FmtAssert (ST_class(pu) == CLASS_FUNC,
00232 ("symbol '%s' is not function", ST_name(pu)));
00233 PU_POINTS_TO_SUMMARY* t =
00234 CXX_NEW(PU_POINTS_TO_SUMMARY(&MEM_src_pool), &MEM_src_pool);
00235 _summaries.push_back (t);
00236 Set (pu, t);
00237 return t;
00238 }
00239
00240 void Print (FILE* f);
00241 };
00242
00243 static PU_POINTS_TO_SUMMARY_MGR* Pu_pt_summary_mgr = NULL;
00244
00245 PU_POINTS_TO_SUMMARY*
00246 Allocate_PU_Points_To_Summary (ST* pu) {
00247 if (Pu_pt_summary_mgr == NULL) {
00248 Pu_pt_summary_mgr = CXX_NEW(PU_POINTS_TO_SUMMARY_MGR, &MEM_src_pool);
00249 }
00250 return Pu_pt_summary_mgr->Allocate_PU_Points_To_Summary (pu);
00251 }
00252
00253 PU_POINTS_TO_SUMMARY*
00254 Allocate_PU_Points_To_Summary (void) {
00255 if (Pu_pt_summary_mgr == NULL) {
00256 Pu_pt_summary_mgr = CXX_NEW(PU_POINTS_TO_SUMMARY_MGR, &MEM_src_pool);
00257 }
00258 ST& st = St_Table[PU_Info_proc_sym(Current_PU_Info)];
00259 return Pu_pt_summary_mgr->Allocate_PU_Points_To_Summary (&st);
00260 }
00261
00262 PU_POINTS_TO_SUMMARY*
00263 Get_points_to_summary (ST* pu) {
00264 if (Pu_pt_summary_mgr)
00265 return Pu_pt_summary_mgr->Get (pu);
00266 return NULL;
00267 }
00268
00269 PU_POINTS_TO_SUMMARY*
00270 Get_points_to_summary (void) {
00271 ST& st = St_Table[PU_Info_proc_sym(Current_PU_Info)];
00272 return Get_points_to_summary (&st);
00273 }
00274
00275 void
00276 UNIFORM_NAME::Print (FILE* f) {
00277 fprintf (f, "[%-3d] ", _unique_id);
00278 switch (_type) {
00279 case UN_NAMED_GLOBAL:
00280 fprintf (f, "%s (global)", ST_name(_name.sym)); break;
00281 case UN_MALLOC:
00282 fprintf (f, "%llx (malloc)", (unsigned long long)_name.line_num); break;
00283 case UN_ALLOCA:
00284 fprintf (f, "%llx (alloca)", (unsigned long long)_name.line_num); break;
00285 case UN_FORMAL:
00286 fprintf (f, "%d (formal)", _name.idx); break;
00287 case UN_CALLER_LOCAL:
00288 fprintf (f, "%p (local)", _name.sym); break;
00289 default:
00290 fprintf (f, "unknown");
00291 }
00292 }
00293
00294 void
00295 UNAME_SPACE::Print (FILE* f, BOOL verbose) {
00296
00297
00298 if (verbose) {
00299 fprintf (f, "G : global sym, M : malloc, A : alloca, F : "
00300 "formal idx, CL : caller local ST");
00301 }
00302
00303 INT idx = 0;
00304 for (UNAME_VECTOR_ITER iter = _all_names.begin ();
00305 iter != _all_names.end (); iter++) {
00306 fprintf (f, "%d:", idx);
00307 (*iter)->Print(stderr);
00308 fprintf (f, "\n");
00309 }
00310 }
00311
00312 void
00313 PT_SET::Print (FILE* f) {
00314
00315 fprintf (f, "ADDRSPACE:");
00316 switch (_addr_space) {
00317 case PTAS_INVALID: fprintf (f, "inval,"); break;
00318 case PTAS_UNKNOWN: fprintf (f, "unknown,"); break;
00319 case PTAS_TEXT: fprintf (f, "text,"); break;
00320 case PTAS_GLOBAL: fprintf (f, "global,"); break;
00321 case PTAS_FSTATIC: fprintf (f, "file static,"); break;
00322 case PTAS_LOCAL: fprintf (f, "local,"); break;
00323 case PTAS_INVISIBLE: fprintf (f, "invisible,"); break;
00324 default:
00325 FmtAssert (FALSE, ("invalid address space"));
00326 };
00327
00328 fprintf (f, "CERTAINTY:%s,",
00329 (_certainty == PTC_POSSIBLE) ? "possible" : "definite");
00330
00331 fprintf (f, "MAY/MUST:%s,",
00332 (_may_or_must == PT_MAY_POINTS_TO) ? "may" : "must");
00333
00334 if (_has_unknown_pt != 0)
00335 fprintf (f, "has unknown pt,");
00336
00337 fprintf (f, "Pt as follows:\n");
00338
00339 for (PT_VECTOR_ITER iter = _all_points_to.begin ();
00340 iter != _all_points_to.end (); iter++) {
00341 fprintf (f, " -.");
00342 (*iter)->Print(f);
00343 }
00344 }
00345
00346 void
00347 PU_POINTS_TO_SUMMARY::Print (FILE* f) {
00348
00349 fprintf (f, "Points-to hold at entry:\n");
00350 PT_SET_MGR& in = In_set ();
00351 UNAME_VECTOR& in_names = in.Name_space()->All_names ();
00352
00353
00354 for (UNAME_VECTOR_ITER iter = in_names.begin ();
00355 iter != in_names.end (); iter++) {
00356 UNIFORM_NAME* name = *iter;
00357 fprintf (f, "PTR-NAME: ");
00358 name->Print(f);
00359 fprintf (f, "\n");
00360
00361 fprintf (f, "POINTS-TOs: ");
00362 PT_SET* pt_sets = in.Points_to_set (name);
00363 if (pt_sets)
00364 pt_sets->Print (f);
00365 }
00366
00367 fprintf (f, "Points-to hold at exit:\n");
00368 PT_SET_MGR& out = Out_set ();
00369 UNAME_VECTOR& out_names = out.Name_space()->All_names ();
00370 for (UNAME_VECTOR_ITER iter = out_names.begin ();
00371 iter != out_names.end (); iter++) {
00372 UNIFORM_NAME* name = *iter;
00373 fprintf (f, "PTR-NAME: ");
00374 name->Print(f);
00375 fprintf (f, "\n");
00376
00377 fprintf (f, "POINTS-TOs: ");
00378 PT_SET* pt_sets = out.Points_to_set (name);
00379 if (pt_sets)
00380 pt_sets->Print (f);
00381 }
00382 }