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
00042
00043
00044
00045
00046
00047
00048 #ifdef USE_PCH
00049 #include "cg_pch.h"
00050 #endif // USE_PCH
00051 #pragma hdrstop
00052
00053 #include <algorithm>
00054 #include <vector>
00055 #if ! defined(BUILD_OS_DARWIN)
00056 #include "libelf/libelf.h"
00057 #endif
00058 #include "dwarf_stuff.h"
00059 #include "defs.h"
00060 #include "errors.h"
00061 #include "tracing.h"
00062 #include "mempool.h"
00063 #include "symtab.h"
00064 #include "wn.h"
00065 #include "irbdata.h"
00066 #include "strtab.h"
00067 #include "stblock.h"
00068 #include "config.h"
00069 #include "config_opt.h"
00070 #include "xstats.h"
00071 #include "eh_region.h"
00072 #include "data_layout.h"
00073 #include "region_util.h"
00074 #include "region_main.h"
00075 #include "bb.h"
00076 #include "whirl2ops.h"
00077 #include "label_util.h"
00078
00079 #ifdef TARG_IA64
00080 #include "dwarf_stuff.h"
00081 #endif
00082 extern "C" {
00083 #include "pro_encode_nm.h"
00084 }
00085 #include <map>
00086 #include <set>
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 class RID_POST_ITER {
00171 private:
00172 RID * start;
00173 RID * own;
00174 public:
00175 typedef std::forward_iterator_tag iterator_category;
00176 typedef RID * value_type;
00177 typedef ptrdiff_t difference_type;
00178 typedef value_type * pointer;
00179 typedef value_type & reference;
00180 RID_POST_ITER(RID* p = NULL);
00181 RID * operator*() const {return own;}
00182 RID_POST_ITER& operator++();
00183 RID_POST_ITER operator++(int);
00184 friend bool operator==(const RID_POST_ITER&, const RID_POST_ITER&);
00185 #ifdef KEY
00186 friend bool operator!=(const RID_POST_ITER&, const RID_POST_ITER&);
00187 #endif
00188 };
00189
00190 RID_POST_ITER::RID_POST_ITER(RID * p): start(p), own(p) {
00191 if (own != NULL) {
00192 while (RID_first_kid(own) != NULL)
00193 own = RID_first_kid(own);
00194 }
00195 }
00196
00197 RID_POST_ITER& RID_POST_ITER::operator++()
00198 {
00199 if (own == start) {
00200 own = NULL;
00201 }
00202 else
00203 if (RID_next(own) != NULL) {
00204 own = RID_next(own);
00205 while (RID_first_kid(own) != NULL)
00206 own = RID_first_kid(own);
00207 }
00208 else
00209 own = RID_parent(own);
00210
00211 return *this;
00212 }
00213
00214 RID_POST_ITER RID_POST_ITER::operator++(int)
00215 {
00216 RID_POST_ITER tmp(*this);
00217 ++*this;
00218 return tmp;
00219 }
00220
00221 inline bool operator==(const RID_POST_ITER& x, const RID_POST_ITER & y)
00222 {
00223 return x.own == y.own;
00224 }
00225
00226 #ifdef KEY
00227 inline bool operator!=(const RID_POST_ITER& x, const RID_POST_ITER & y)
00228 {
00229 return x.own != y.own;
00230 }
00231 #endif
00232
00233 class RID_PARENT_ITER {
00234 private:
00235 RID * p;
00236 public:
00237 typedef std::forward_iterator_tag iterator_category;
00238 typedef RID * value_type;
00239 typedef ptrdiff_t difference_type;
00240 typedef value_type * pointer;
00241 typedef value_type & reference;
00242 RID_PARENT_ITER(RID* x = NULL): p(x) {}
00243 RID * operator*() const {return p;}
00244 RID_PARENT_ITER& operator++() {p = RID_parent(p); return *this;}
00245 RID_PARENT_ITER operator++(int) {
00246 RID_PARENT_ITER tmp = *this;
00247 ++*this;
00248 return tmp;
00249 }
00250 friend bool operator==(const RID_PARENT_ITER&, const RID_PARENT_ITER &);
00251 #ifdef KEY
00252 friend bool operator!=(const RID_PARENT_ITER&, const RID_PARENT_ITER &);
00253 #endif
00254 };
00255
00256 bool operator==(const RID_PARENT_ITER& x, const RID_PARENT_ITER& y) {
00257 return x.p == y.p;
00258 }
00259
00260 #ifdef KEY
00261 bool operator!=(const RID_PARENT_ITER& x, const RID_PARENT_ITER& y) {
00262 return x.p != y.p;
00263 }
00264 #endif
00265
00266 struct IS_EH_RID
00267 {
00268 bool operator()(const RID* rid) {
00269 return RID_TYPE_eh(rid);}
00270 };
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 enum eh_range_kind {
00281 ehk_try_block,
00282 ehk_exc_spec,
00283 ehk_cleanup,
00284 ehk_mask,
00285 ehk_guard,
00286 ehk_last};
00287
00288 static eh_range_kind Range_Kind(RID * rid)
00289 {
00290 if (RID_TYPE_try(rid))
00291 return ehk_try_block;
00292 if (RID_TYPE_exc_spec(rid))
00293 return ehk_exc_spec;
00294 if (RID_TYPE_cleanup(rid))
00295 return ehk_cleanup;
00296 if (RID_TYPE_null_cleanup(rid))
00297 return ehk_cleanup;
00298 if (RID_TYPE_mask(rid))
00299 return ehk_mask;
00300 if (RID_TYPE_guard(rid))
00301 return ehk_guard;
00302 return ehk_last;
00303 }
00304
00305 struct EH_RANGE {
00306
00307 INITO_IDX ereg_supp;
00308 LABEL_IDX start_label;
00309 LABEL_IDX end_label;
00310 EH_RANGE *parent;
00311 eh_range_kind kind;
00312
00313
00314 RID * rid;
00315 BB *end_bb;
00316 EH_RANGE* id;
00317 INT32 key;
00318 INT32 adjustment;
00319 bool has_call;
00320
00321
00322 EH_RANGE(RID * x):
00323 ereg_supp(WN_ereg_supp(RID_rwn(x))),
00324 start_label(LABEL_IDX_ZERO),
00325 end_label(LABEL_IDX_ZERO),
00326 parent(NULL),
00327 kind(Range_Kind(x)),
00328 rid(x),
00329 end_bb(NULL),
00330 id(this),
00331 key(0),
00332 adjustment(0),
00333 has_call(false) {}
00334 };
00335
00336
00337
00338
00339
00340
00341 class EH_RANGE_LIST {
00342 private:
00343 std::vector<EH_RANGE> v;
00344 public:
00345 EH_RANGE_LIST(): v() {}
00346 void add_range(EH_RANGE range) {
00347 v.push_back(range);
00348 }
00349 void clear() {v.clear();}
00350 size_t size() {return v.size();}
00351 EH_RANGE& operator[](size_t i) {return v[i];}
00352 typedef std::vector<EH_RANGE>::iterator iterator;
00353 typedef std::vector<EH_RANGE>::reverse_iterator reverse_iterator;
00354 iterator begin() {return v.begin();}
00355 iterator end() {return v.end();}
00356 reverse_iterator rbegin() {return v.rbegin();}
00357 reverse_iterator rend() {return v.rend();}
00358 iterator erase(iterator first, iterator last) {
00359 return v.erase(first, last);}
00360 };
00361
00362 class EH_RANGE_LIST_PARENT_ITER {
00363 private:
00364 EH_RANGE_LIST::iterator iter;
00365 public:
00366 typedef std::forward_iterator_tag iterator_category;
00367 typedef EH_RANGE value_type;
00368 typedef ptrdiff_t difference_type;
00369 typedef value_type * pointer;
00370 typedef value_type & reference;
00371 EH_RANGE_LIST_PARENT_ITER(): iter() {}
00372 EH_RANGE_LIST_PARENT_ITER(EH_RANGE_LIST::iterator x): iter(x) {}
00373 EH_RANGE& operator*() {return *iter;}
00374 EH_RANGE_LIST_PARENT_ITER& operator++() {
00375 #ifdef KEY // workaround g++ 3.2 problem
00376 iter = EH_RANGE_LIST::iterator(iter->parent); return *this;}
00377 #else
00378 iter = iter->parent; return *this;}
00379 #endif
00380 EH_RANGE_LIST_PARENT_ITER operator++(int) {
00381 EH_RANGE_LIST_PARENT_ITER tmp = *this;
00382 ++*this;
00383 return tmp;
00384 }
00385 friend bool operator==(const EH_RANGE_LIST_PARENT_ITER&,
00386 const EH_RANGE_LIST_PARENT_ITER&);
00387 #ifdef KEY
00388 friend bool operator!=(const EH_RANGE_LIST_PARENT_ITER&,
00389 const EH_RANGE_LIST_PARENT_ITER&);
00390 #endif
00391 };
00392
00393 inline bool operator==(const EH_RANGE_LIST_PARENT_ITER & x,
00394 const EH_RANGE_LIST_PARENT_ITER &y) {
00395 return x.iter == y.iter;
00396 }
00397
00398 #ifdef KEY
00399 inline bool operator!=(const EH_RANGE_LIST_PARENT_ITER & x,
00400 const EH_RANGE_LIST_PARENT_ITER &y) {
00401 return x.iter != y.iter;
00402 }
00403 #endif
00404
00405
00406
00407
00408
00409
00410 static EH_RANGE_LIST range_list;
00411
00412
00413
00414
00415
00416 #ifdef KEY
00417
00418
00419 void ADD_EH_RANGE (RID * rid)
00420 {
00421 if (RID_TYPE_eh(rid)) {
00422 if (WN_block_empty(WN_region_pragmas(RID_rwn(rid))))
00423 range_list.add_range(rid);
00424 else
00425 Set_ST_is_not_used (INITO_st(WN_ereg_supp(RID_rwn(rid))));
00426 }
00427 }
00428 #else
00429 struct ADD_EH_RANGE {
00430 void operator()(RID * rid) {
00431 if (RID_TYPE_eh(rid)) {
00432 range_list.add_range(rid);
00433 }
00434 }
00435 };
00436 #endif // KEY
00437
00438
00439
00440
00441
00442 struct SET_PARENT {
00443 void operator()(EH_RANGE& r) {
00444 RID_PARENT_ITER first(r.rid);
00445 RID_PARENT_ITER last(NULL);
00446 #if (__GNUC__ < 4 ||(__GNUC__ == 4 && __GNUC_MINOR__ == 0))
00447 first = find_if(++first, last, IS_EH_RID(), std::__iterator_category(first));
00448 #else
00449 first = std::__find_if(++first, last, IS_EH_RID(), std::__iterator_category(first));
00450 #endif
00451 if (first == last)
00452 r.parent = NULL;
00453 else
00454 r.parent = RID_eh_range_ptr(*first);
00455 }
00456 };
00457
00458
00459
00460
00461
00462
00463 void
00464 EH_Generate_Range_List(WN * pu)
00465 {
00466 range_list.clear();
00467
00468 RID * rid = (RID *) WN_MAP_Get(RID_map, pu);
00469 RID_POST_ITER rid_first(rid);
00470 RID_POST_ITER rid_last(NULL);
00471
00472 while (rid_first != rid_last)
00473 {
00474 ADD_EH_RANGE(*rid_first);
00475 ++rid_first;
00476 }
00477
00478 EH_RANGE_LIST::iterator list_first(range_list.begin());
00479 EH_RANGE_LIST::iterator list_last (range_list.end());
00480
00481 for (EH_RANGE_LIST::iterator p = list_first; p!=list_last; p++)
00482 #ifdef KEY
00483 RID_eh_range_ptr(p->rid) = &(*p);
00484 #else
00485 RID_eh_range_ptr(p->rid) = p;
00486 #endif
00487
00488 std::for_each(list_first, list_last, SET_PARENT());
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 struct IS_SIB_RANGE {
00507 const EH_RANGE* me;
00508 IS_SIB_RANGE(const EH_RANGE * x): me(x) {}
00509 bool operator()(const EH_RANGE& r) const {
00510 return (r.rid != me->rid) &&
00511 (r.parent == me->parent) &&
00512 (r.end_label != (LABEL_IDX)NULL);
00513 }
00514 };
00515
00516
00517 static LABEL_IDX Duplicate_LABEL (LABEL_IDX oldi)
00518 {
00519 LABEL_IDX lbi;
00520 LABEL& lab = New_LABEL (CURRENT_SYMTAB, lbi);
00521 LABEL old = Label_Table[oldi];
00522 Set_LABEL_name_idx(lab, Save_Str2(LABEL_name(old), ".dup"));
00523 Set_LABEL_kind(lab, LABEL_kind(old));
00524 return lbi;
00525 }
00526
00527
00528
00529 bool
00530 EH_Has_Landing_Pad (EH_RANGE *range)
00531 {
00532 if (range->ereg_supp == 0) return false;
00533 ST* st = INITO_st(range->ereg_supp);
00534 if (ST_is_not_used(st)) return false;
00535
00536 INITV_IDX blk = INITO_val(range->ereg_supp);
00537 if (INITV_kind(blk) != INITVKIND_BLOCK)
00538 return false;
00539
00540 INITV_IDX first = INITV_blk(blk);
00541 if (INITV_kind(first) == INITVKIND_LABEL)
00542 return true;
00543 else
00544 return false;
00545 }
00546
00547 void
00548 EH_Set_Start_Label(EH_RANGE* p)
00549 {
00550 LABEL_IDX label;
00551 #ifdef TARG_IA64
00552
00553
00554
00555 if (!EH_Has_Landing_Pad (p) && PU_is_mainpu (Get_Current_PU ()))
00556 return;
00557 #endif
00558 if (p->kind == ehk_guard) {
00559 #ifdef KEY
00560 EH_RANGE_LIST::reverse_iterator rfirst = range_list.rbegin();
00561 while (&(*rfirst) != p)
00562 rfirst++;
00563 #else
00564 EH_RANGE_LIST::reverse_iterator rfirst(p);
00565 #endif
00566 EH_RANGE_LIST::reverse_iterator rlast = range_list.rend();
00567 EH_RANGE_LIST::reverse_iterator riter =
00568 std::find_if(rfirst, rlast, IS_SIB_RANGE(p));
00569 if (riter == rlast) {
00570 if (p->parent != NULL) {
00571 label = Duplicate_LABEL(p->parent->start_label);
00572 Set_Label_BB(label, NULL);
00573 }
00574 }
00575
00576 else {
00577 label = Duplicate_LABEL(riter->end_label);
00578 Set_Label_BB(label, NULL);
00579 Set_LABEL_kind(Label_Table[label], LKIND_DEFAULT);
00580 Set_LABEL_begin_eh_range(label);
00581 }
00582 Add_Label(label);
00583 }
00584
00585 else {
00586 label = Gen_Temp_Label();
00587 BB * bb = Add_Label(label);
00588 Set_LABEL_begin_eh_range(label);
00589 }
00590
00591 p->start_label = label;
00592 }
00593
00594
00595
00596 void
00597 EH_Set_End_Label(EH_RANGE* p)
00598 {
00599 LABEL_IDX label;
00600 #ifdef TARG_IA64
00601
00602
00603
00604 if (!EH_Has_Landing_Pad (p) && PU_is_mainpu (Get_Current_PU ()))
00605 return;
00606 #endif
00607 label = Gen_Temp_Label();
00608 BB * bb = Add_Label(label);
00609 p->end_label = label;
00610 p->end_bb = bb;
00611 Set_LABEL_end_eh_range(label);
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621 void EH_Set_Has_Call(EH_RANGE* p)
00622 {
00623 p->has_call = TRUE;
00624 if (p->kind == ehk_mask) {
00625
00626 #ifdef KEY // workaround constructor call bug in g++ 3.2
00627 EH_RANGE_LIST::reverse_iterator rfirst = range_list.rbegin();
00628 while (&(*rfirst) != p)
00629 rfirst++;
00630 #else
00631 EH_RANGE_LIST::reverse_iterator rfirst(p);
00632 #endif
00633 EH_RANGE_LIST::reverse_iterator rlast = range_list.rend();
00634 rfirst = std::find_if(rfirst, rlast, IS_SIB_RANGE(p));
00635 Is_True(rfirst != rlast && rfirst->kind == ehk_guard,
00636 ("mask region must have guard"));
00637 rfirst->has_call = TRUE;
00638 }
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 struct HAS_NO_CALL_OR_HAS_NULL_OR_UNREACHABLE_LABEL {
00663 bool operator()(const EH_RANGE& r) {
00664 if (Inhibit_EH_opt) return false;
00665 if (r.has_call && r.start_label != (LABEL_IDX)NULL) {
00666 BB *start_bb = Get_Label_BB(r.start_label);
00667 if (start_bb && !BB_unreachable(start_bb)) return false;
00668 }
00669 return true;
00670 }
00671 };
00672
00673 #ifdef KEY
00674 struct FIX_PARENT
00675 {
00676 bool operator() (EH_RANGE& r)
00677 {
00678 while (r.parent &&
00679 HAS_NO_CALL_OR_HAS_NULL_OR_UNREACHABLE_LABEL() (*(r.parent)))
00680 r.parent = r.parent->parent;
00681 }
00682 };
00683 #endif // KEY
00684
00685 struct SET_ADJUSTMENT {
00686 INT32 amount;
00687 SET_ADJUSTMENT(): amount(0) {}
00688 void operator()(EH_RANGE& r) {
00689 if (HAS_NO_CALL_OR_HAS_NULL_OR_UNREACHABLE_LABEL()(r)) {
00690 ++amount;
00691 if (r.start_label != (LABEL_IDX) NULL)
00692 Set_LABEL_kind(Label_Table[r.start_label], LKIND_DEFAULT);
00693 if (r.end_label != (LABEL_IDX) NULL)
00694 Set_LABEL_kind(Label_Table[r.end_label], LKIND_DEFAULT);
00695 Set_ST_is_not_used(INITO_st(r.ereg_supp));
00696 }
00697 r.adjustment = amount;
00698 }
00699 };
00700
00701 struct CLEAR_USED {
00702 CLEAR_USED() {}
00703 void operator()(EH_RANGE& r) {
00704 if (!HAS_NO_CALL_OR_HAS_NULL_OR_UNREACHABLE_LABEL()(r))
00705 Clear_ST_is_not_used(INITO_st(r.ereg_supp));
00706 }
00707 };
00708
00709 struct SET_ADJUSTMENT_TO_PARENT_ADJUSTMENT {
00710 void operator()(EH_RANGE & r) {
00711 if (r.parent == NULL) {
00712 r.adjustment = 0;
00713 }
00714 else {
00715 r.adjustment = r.parent->adjustment;
00716 }
00717 }
00718 };
00719
00720 struct ADJUST_PARENT {
00721 void operator()(EH_RANGE&r) {r.parent -= r.adjustment;}
00722 };
00723
00724
00725 void
00726 EH_Prune_Range_List(void)
00727 {
00728 EH_RANGE_LIST::iterator first(range_list.begin());
00729 EH_RANGE_LIST::iterator last(range_list.end());
00730 if (first == last) return;
00731 if (!PU_has_exc_scopes(Get_Current_PU()) && !Inhibit_EH_opt) {
00732 range_list.erase(first, last);
00733 return;
00734 }
00735 for_each (first, last, FIX_PARENT());
00736 std::for_each (first, last, SET_ADJUSTMENT());
00737 std::for_each (first, last, CLEAR_USED());
00738 std::for_each (first, last, SET_ADJUSTMENT_TO_PARENT_ADJUSTMENT());
00739
00740 range_list.erase(
00741 remove_if (first, last,
00742 HAS_NO_CALL_OR_HAS_NULL_OR_UNREACHABLE_LABEL()),
00743 last);
00744 std::for_each (range_list.begin(), range_list.end(), ADJUST_PARENT());
00745
00746 #if defined(KEY) && defined(Is_True_On)
00747 for (INT i=0; i<range_list.size(); i++)
00748 Is_True (&range_list[i] != range_list[i].parent,
00749 ("EH_Prune_Range_List end: kid == parent"));
00750 #endif // Is_True_On
00751 }
00752
00753 struct COMPARE_RANGES {
00754 bool operator()(const EH_RANGE& r1, const EH_RANGE& r2) {
00755 if (r1.key < r2.key) return true;
00756 if (r1.key > r2.key) return false;
00757 return r1.id < r2.id;
00758 }
00759 };
00760
00761 void
00762 reorder_range_list()
00763 {
00764 BB * bb;
00765 INT32 bb_count;
00766 size_t i;
00767
00768 #ifdef KEY // Speed up the original code. Bug 10289.
00769 {
00770 INT32 *bb_counts = (INT32 *) alloca(sizeof(INT32) * (PU_BB_Count + 1));
00771 #if Is_True_On
00772 memset(bb_counts, 0, sizeof(INT32) * (PU_BB_Count + 1));
00773 #endif
00774 for (bb = REGION_First_BB, bb_count = 0;
00775 bb != NULL;
00776 bb = BB_next(bb), ++bb_count) {
00777 bb_counts[BB_id(bb)] = bb_count;
00778 }
00779 for (i = 0; i < range_list.size(); ++i) {
00780 bb_count = bb_counts[BB_id(range_list[i].end_bb)];
00781 Is_True(bb_count != 0,("reorder_range_list: bad bb_count"));
00782 range_list[i].key = bb_count;
00783 range_list[i].id = &range_list[i];
00784 }
00785 }
00786 #else
00787 for (bb = REGION_First_BB, bb_count = 0;
00788 bb != NULL;
00789 bb = BB_next(bb), ++bb_count) {
00790 for (i = 0; i < range_list.size(); ++i) {
00791 if (range_list[i].end_bb == bb)
00792 range_list[i].key = bb_count;
00793 range_list[i].id = &range_list[i];
00794 }
00795 }
00796 #endif
00797
00798 EH_RANGE_LIST::iterator first(range_list.begin());
00799 EH_RANGE_LIST::iterator last (range_list.end());
00800
00801 stable_sort(first, last, COMPARE_RANGES());
00802
00803
00804
00805 std::vector<int> inv(range_list.size());
00806 for (i = 0; i < range_list.size(); ++i)
00807 inv[range_list[i].id - &range_list[0]] = i;
00808
00809 for (i = 0; i < range_list.size(); ++i)
00810 if (range_list[i].parent != NULL)
00811 range_list[i].parent = &range_list[0] +
00812 inv[range_list[i].parent - &range_list[0]];
00813 }
00814
00815 struct IS_CLEANUP_RANGE {
00816 bool operator()(const EH_RANGE& r) const {return r.kind == ehk_cleanup;}
00817 };
00818
00819 struct FIX_MASK_PARENT {
00820 void operator()(EH_RANGE& r) {
00821 if (r.kind == ehk_mask) {
00822 #ifdef KEY
00823 EH_RANGE_LIST_PARENT_ITER first(EH_RANGE_LIST::iterator(r.parent));
00824 EH_RANGE_LIST_PARENT_ITER last(EH_RANGE_LIST::iterator(NULL));
00825 #else
00826 EH_RANGE_LIST_PARENT_ITER first(r.parent);
00827 EH_RANGE_LIST_PARENT_ITER last (NULL);
00828 #endif
00829 #if (__GNUC__ < 4 || __GNUC_MINOR__ == 0)
00830 first = find_if(first, last, IS_CLEANUP_RANGE(), std::__iterator_category(first));
00831 #else
00832 first = std::__find_if(first, last, IS_CLEANUP_RANGE(), std::__iterator_category(first));
00833 #endif
00834 Is_True(first != last, ("mask region must have cleanup ancestor"));
00835 r.parent = (*first).parent;
00836 }
00837 }
00838 };
00839
00840 struct CHANGE_MASK_OR_GUARD_TO_CLEANUP {
00841 void operator()(EH_RANGE& r) {
00842 if (r.kind == ehk_mask || r.kind == ehk_guard)
00843 r.kind = ehk_cleanup;
00844 }
00845 };
00846
00847 static void
00848 fix_mask_ranges(void)
00849 {
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 EH_RANGE_LIST::reverse_iterator rfirst(range_list.rbegin());
00860 EH_RANGE_LIST::reverse_iterator rlast (range_list.rend());
00861
00862 std::for_each(rfirst, rlast, FIX_MASK_PARENT());
00863 std::for_each(range_list.begin(), range_list.end(),
00864 CHANGE_MASK_OR_GUARD_TO_CLEANUP());
00865 }
00866
00867 static ST * eh_pu_range_st;
00868
00869 extern ST* EH_Get_PU_Range_ST(void)
00870 {
00871 return eh_pu_range_st;
00872 }
00873
00874 inline BOOL Use_Long_EH_Range_Offsets(void)
00875 {
00876 return Force_Long_EH_Range_Offsets ||
00877 PU_WN_BB_Cnt + PU_WN_Stmt_Cnt > 2000;
00878 }
00879
00880 static ST*
00881 ST_For_Range_Table(WN * wn)
00882 {
00883 ST * pu = WN_st(wn);
00884 ST * st;
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 UINT32 header_size = 8;
00895 UINT32 number_of_ranges = range_list.size();
00896 UINT32 parent_size = 2;
00897 UINT32 kind_size = 2;
00898 UINT32 offset_size = Use_Long_EH_Range_Offsets() ? 4 : 2;
00899 UINT32 range_size = Pointer_Size + parent_size + kind_size +
00900 2 * offset_size;
00901 UINT32 size = header_size + number_of_ranges * range_size;
00902
00903 #ifdef KEY
00904
00905
00906 size = 0;
00907 #endif // KEY
00908
00909 TY_IDX tyi;
00910 TY& ty = New_TY(tyi);
00911 TY_Init(ty, size, KIND_STRUCT, MTYPE_M,
00912 Save_Str2(".range_table.",ST_name(pu)));
00913 #ifdef KEY
00914 if (Is_Target_64bit())
00915 Set_TY_align(tyi, 8);
00916 else
00917 Set_TY_align(tyi, 4);
00918 #else
00919 Set_TY_align(tyi, 4);
00920 #endif
00921 st = New_ST(CURRENT_SYMTAB);
00922 ST_Init(st, TY_name_idx(ty),
00923 CLASS_VAR, SCLASS_EH_REGION, EXPORT_LOCAL, tyi);
00924 Set_ST_is_initialized(st);
00925 Allocate_Object(st);
00926 return st;
00927 }
00928
00929 #define SHORT_OFFSETS 0
00930 #define LONG_OFFSETS 1
00931 #define HEADER_VERSION 1
00932
00933 inline INT16 parent_offset(INT32 i)
00934 {
00935 if (range_list[i].parent == NULL)
00936 return 0;
00937 else
00938 return (INT16) (range_list[i].parent - &range_list[i]);
00939 }
00940
00941
00942
00943
00944
00945
00946
00947
00948 #include <map>
00949 #include <set>
00950 using namespace std;
00951
00952 typedef std::map< ST_IDX, int > TF_MAP;
00953 typedef std::map< int, ST_IDX > FT_MAP;
00954 typedef std::set< ST_IDX > EH_PTS;
00955
00956 TF_MAP tfmap;
00957 FT_MAP ftmap;
00958
00959
00960 static void
00961 EH_Build_PIC_Type(ST_IDX idx)
00962 {
00963 static EH_PTS pts;
00964 if (pts.find(idx) != pts.end())
00965 return;
00966 pts.insert(idx);
00967
00968 ST* st = &St_Table[idx];
00969 ST* pst = New_ST(GLOBAL_SYMTAB);
00970 STR_IDX pname = Save_Str2 ("DW.ref.", ST_name (st));
00971 ST_Init(pst, pname, CLASS_VAR, SCLASS_DGLOBAL, EXPORT_HIDDEN, MTYPE_TO_TY_array[MTYPE_U8]);
00972 Set_ST_is_weak_symbol (pst);
00973 Set_ST_is_initialized (pst);
00974
00975 ST_ATTR_IDX st_attr_idx;
00976 ST_ATTR& st_attr = New_ST_ATTR(GLOBAL_SYMTAB, st_attr_idx);
00977 ST_ATTR_Init(st_attr, ST_st_idx(pst), ST_ATTR_SECTION_NAME,
00978 Save_Str2 (".gnu.linkonce.d.", ST_name(pst)));
00979
00980 INITV_IDX iv = New_INITV();
00981 INITV_Init_Symoff(iv, st, 0, 1);
00982 New_INITO (ST_st_idx(pst), iv);
00983 Assign_ST_To_Named_Section (pst, ST_ATTR_section_name (st_attr));
00984 }
00985
00986 static int
00987 Get_EH_Filter_By_Type(ST_IDX idx, TF_MAP& tfmap)
00988 {
00989 TF_MAP::iterator it;
00990 it = tfmap.find(idx);
00991 return (it != tfmap.end()) ? it->second : 0;
00992 }
00993
00994 static ST_IDX
00995 Get_EH_ST_By_Filter(int filter, FT_MAP& ftmap)
00996 {
00997 FT_MAP::iterator it;
00998 it = ftmap.find(filter);
00999 return (it != ftmap.end() ? it->second : 0);
01000 }
01001
01002
01003 static int
01004 Convert_TF_Map_To_FT_Map(TF_MAP& src, FT_MAP& dst)
01005 {
01006 TF_MAP::iterator it;
01007 int filter = 0;
01008
01009 dst.clear();
01010 for (it = src.begin(); it != src.end(); it++)
01011 {
01012 dst.insert(std::make_pair(it->second, it->first));
01013 if (it->second > filter) filter = it->second;
01014 }
01015 return filter;
01016 }
01017
01018 static INITV_IDX
01019 Get_TF_Map_and_EH_Spec_List(PU& pu, TF_MAP& tfmap)
01020 {
01021 INITO_IDX ino_idx = pu.misc;
01022 tfmap.clear();
01023
01024 if (ino_idx == INITO_IDX_ZERO) {
01025 return INITV_IDX_ZERO;
01026 }
01027
01028 INITV_IDX exc_ptr_iv = INITO_val(ino_idx);
01029 INITV_IDX filter_iv = INITV_next(exc_ptr_iv);
01030 INITV_IDX tinfo = INITV_next(filter_iv);
01031 INITV_IDX eh_spec = INITV_next(tinfo);
01032
01033 INITO_IDX id = TCON_uval(INITV_tc_val(tinfo));
01034
01035
01036 if (id != INITO_IDX_ZERO) {
01037 ST *st = INITO_st(id);
01038 INITV_IDX blk = INITO_val(id);
01039
01040 while (blk != INITV_IDX_ZERO) {
01041 INITV_IDX type_st_iv = INITV_blk(blk);
01042 int filter = TCON_ival(INITV_tc_val(INITV_next(type_st_iv)));
01043 ST_IDX type_st_idx = 0;
01044 if (INITVKIND_ZERO != INITV_kind(type_st_iv))
01045 type_st_idx = TCON_uval(INITV_tc_val(type_st_iv));
01046
01047 if ( type_st_idx != 0)
01048 EH_Build_PIC_Type(type_st_idx);
01049 tfmap.insert(std::make_pair(type_st_idx, filter));
01050 blk = INITV_next(blk);
01051 }
01052 }
01053
01054
01055 id = TCON_uval(INITV_tc_val(eh_spec));
01056 return (id != 0) ? INITV_blk(INITO_val(id)) : INITV_IDX_ZERO;
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 static void flatten_regions (void)
01081 {
01082 vector<EH_RANGE> new_ranges;
01083 int i=0;
01084 while (i < range_list.size() - 1)
01085 {
01086 if (range_list[i].parent)
01087 {
01088 int first_child, last_child;
01089 first_child = last_child = i++;
01090
01091 while (range_list[first_child].parent != &range_list[i])
01092 {
01093 if (range_list[i].parent == range_list[first_child].parent)
01094 {
01095 range_list[i].parent = NULL;
01096 last_child = i;
01097 }
01098 i++;
01099 }
01100
01101 EH_RANGE new_range (range_list[i].rid);
01102 new_range.start_label = range_list[last_child].end_label;
01103 new_range.end_label = range_list[i].end_label;
01104 new_range.end_bb = range_list[i].end_bb;
01105 new_range.has_call = range_list[i].has_call;
01106 new_ranges.push_back (new_range);
01107
01108
01109 range_list[i].end_label = range_list[first_child].start_label;
01110 range_list[i].end_bb = Get_Label_BB (range_list[i].end_label);
01111 range_list[first_child].parent = NULL;
01112 i = first_child + 1;
01113 }
01114 else i++;
01115 }
01116
01117 for (vector<EH_RANGE>::iterator iter = new_ranges.begin();
01118 iter != new_ranges.end(); ++iter)
01119 range_list.add_range (*iter);
01120 }
01121
01122 #include <map>
01123 using namespace std;
01124
01125 struct cmpst
01126 {
01127 bool operator() (const ST_IDX i1, const ST_IDX i2) const
01128 {
01129 return (i1 < i2);
01130 }
01131 };
01132
01133
01134
01135
01136 map<ST_IDX, int, cmpst> type_filter_map;
01137
01138 struct type_filter_entry {
01139 ST_IDX st;
01140 int filter;
01141 };
01142
01143 struct sort_on_filter : public binary_function<type_filter_entry,
01144 type_filter_entry, bool>
01145 {
01146 bool operator() (const type_filter_entry t1,
01147 const type_filter_entry t2) const
01148 {
01149 return t1.filter > t2.filter;
01150 }
01151 };
01152
01153 static INITO*
01154 Create_Type_Filter_Map (void)
01155 {
01156 INITV_IDX i = INITV_next (INITV_next (INITO_val (PU_misc_info (Get_Current_PU()))));
01157 INITO* ino;
01158 INITO_IDX idx = TCON_uval (INITV_tc_val(i));
01159 if (idx)
01160 {
01161 ino = &Inito_Table[idx];
01162 ST* st = INITO_st(ino);
01163
01164 FmtAssert (!strcmp(ST_name (*st), "__TYPEINFO_TABLE__") &&
01165 (ST_sclass(st) == SCLASS_EH_REGION_SUPP),
01166 ("Unexpected ST in PU"));
01167 INITV_IDX blk = INITO_val(*ino);
01168
01169 do
01170 {
01171 INITV_IDX st_entry = INITV_blk(blk);
01172
01173 ST_IDX st_idx = 0;
01174 if (INITV_kind (st_entry) != INITVKIND_ZERO)
01175 st_idx = TCON_uval(INITV_tc_val (st_entry));
01176 int filter = TCON_ival (INITV_tc_val (INITV_next (st_entry)));
01177 type_filter_map [st_idx] = filter;
01178 } while (INITV_next(blk) && (blk=INITV_next(blk)));
01179 }
01180
01181 i = INITV_next (i);
01182 ino = 0;
01183 idx = TCON_uval (INITV_tc_val(i));
01184 if (idx)
01185 {
01186 ino = &Inito_Table[idx];
01187 ST* st = INITO_st(ino);
01188
01189 FmtAssert (!strcmp(ST_name (*st), "__EH_SPEC_TABLE__") &&
01190 (ST_sclass(st) == SCLASS_EH_REGION_SUPP),
01191 ("Unexpected ST in PU"));
01192 }
01193 return ino;
01194 }
01195
01196
01197
01198
01199 static int
01200 sizeof_signed_leb128 (int value)
01201 {
01202 char buff[ENCODE_SPACE_NEEDED];
01203 int size;
01204 int res = _dwarf_pro_encode_signed_leb128_nm (value, &size, buff, sizeof(buff));
01205 FmtAssert (res == DW_DLV_OK, ("Encoding for exception table failed"));
01206 return size;
01207 }
01208
01209
01210 static const char*
01211 Get_INITV_kind (INITVKIND kind)
01212 {
01213 #define CASE_KIND(n) case n:return #n
01214 switch (kind) {
01215 CASE_KIND(INITVKIND_UNK);
01216 CASE_KIND(INITVKIND_SYMOFF);
01217 CASE_KIND(INITVKIND_ZERO);
01218 CASE_KIND(INITVKIND_ONE);
01219 CASE_KIND(INITVKIND_VAL);
01220 CASE_KIND(INITVKIND_BLOCK);
01221 CASE_KIND(INITVKIND_PAD);
01222 CASE_KIND(INITVKIND_SYMDIFF);
01223 CASE_KIND(INITVKIND_SYMDIFF16);
01224 CASE_KIND(INITVKIND_LABEL);
01225 #ifdef TARG_IA64
01226 CASE_KIND(INITVKIND_SYMIPLT);
01227 #endif
01228 }
01229 return "unknown";
01230 #undef CASE_KIND
01231 }
01232
01233 static const char*
01234 Get_LABEL_Kind (LABEL_KIND kind)
01235 {
01236 #define CASE_KIND(n) case n: return #n
01237 switch (kind) {
01238 CASE_KIND(LKIND_DEFAULT);
01239 CASE_KIND(LKIND_ASSIGNED);
01240 CASE_KIND(LKIND_BEGIN_EH_RANGE);
01241 CASE_KIND(LKIND_END_EH_RANGE);
01242 CASE_KIND(LKIND_BEGIN_HANDLER);
01243 CASE_KIND(LKIND_END_HANDLER);
01244 }
01245 return "unknown";
01246 #undef CASE_KIND
01247 }
01248
01249 static void
01250 EH_Dump_INITV (INITV_IDX inv, FILE* fp, int step)
01251 {
01252 if (inv == 0)return;
01253
01254 for (int i=0; i<step; i++)
01255 fprintf(fp, "\t");
01256
01257 fprintf(fp, "%s (%d)", Get_INITV_kind(INITV_kind(inv)), inv);
01258
01259 if (INITVKIND_BLOCK == INITV_kind(inv)) {
01260 fprintf(fp, "\n");
01261 EH_Dump_INITV(INITV_blk(inv), fp, step + 1);
01262 }
01263 else if (INITVKIND_LABEL == INITV_kind(inv)) {
01264 LABEL& lab = Label_Table[INITV_lab(inv)];
01265 fprintf(fp, " %s: (%s) (%d)\n", Get_LABEL_Kind (lab.kind), LABEL_name (lab), INITV_lab(inv));
01266 }
01267 else if (INITVKIND_VAL == INITV_kind(inv)) {
01268 int sym = TCON_ival(INITV_tc_val(inv));
01269 fprintf(fp, " INITVKIND_VAL: value = %d (0x%08x)\n", sym, sym);
01270 }
01271 else if (INITVKIND_ZERO == INITV_kind(inv)) {
01272 fprintf(fp, " INITVKIND_VAL: value = 0\n");
01273 }
01274 else if (INITVKIND_ONE == INITV_kind(inv)) {
01275 fprintf(fp, " INITVKIND_VAL: value = 1\n");
01276 }
01277 else {
01278 fprintf(fp, "\n");
01279 }
01280 if (INITV_next(inv) != 0)
01281 EH_Dump_INITV(INITV_next(inv), fp, step);
01282 }
01283
01284 void
01285 EH_Dump_INITOs (WN *pu, FILE *fp)
01286 {
01287 INT i;
01288 INITO *ino;
01289 static int num = 0;
01290 FOREACH_INITO (CURRENT_SYMTAB, ino, i) {
01291 ST *st = INITO_st(ino);
01292 if (st->storage_class == SCLASS_EH_REGION ||
01293 st->storage_class == SCLASS_EH_REGION_SUPP)
01294 if (!ST_is_not_used(st)) {
01295 INITV_IDX inv = ino->val;
01296 fprintf(fp, "EH Symbol [%d]: \n", num++);
01297 fprintf(fp, "\tName: %s\n", ST_name(st));
01298 EH_Dump_INITV (inv, fp, 1);
01299 }
01300 }
01301 }
01302
01303 static void
01304 Print_EH_Range(EH_RANGE& range, FILE* fp, const int i)
01305 {
01306 fprintf (fp, "-----------------------------------------------------------------------\n");
01307 fprintf(fp, "EH_RANGE [%d]: (%p)\n", i, &range);
01308 fprintf(fp, "\t[0]. kind = %d\n", (int)range.kind);
01309 fprintf(fp, "\t[1]. ereg_supp = %d\n", (int)range.ereg_supp);
01310 fprintf(fp, "\t[2]. has_call = %d\n", (int)range.has_call);
01311 if (range.start_label && range.end_label) {
01312 fprintf(fp, "\t[3]. start_label = %d (%d)(%s)\n", (int)range.start_label,
01313 Label_Table[range.start_label].kind, LABEL_name(Label_Table[range.start_label]));
01314 fprintf(fp, "\t[4]. end_label = %d (%d)(%s)\n", (int)range.end_label,
01315 Label_Table[range.end_label].kind, LABEL_name(Label_Table[range.end_label]));
01316 }
01317 fprintf(fp, "\t[5]. parent = %p\n", range.parent);
01318
01319 if (range.ereg_supp == 0) return;
01320 INITV_IDX blk = INITO_val(range.ereg_supp);
01321 fprintf(fp, "\t[6]. ereg_supp.INITV.kind = %d, INITV_IDX: %d",INITV_kind(blk), blk);
01322 if (INITV_kind(blk) == INITVKIND_LABEL) {
01323 LABEL& lab = Label_Table[INITV_lab(blk)];
01324 fprintf(fp, ", lab:%d (%d)(%s)", INITV_lab(blk), lab.kind, LABEL_name(lab));
01325 }
01326 fprintf(fp, "\n");
01327
01328 if (INITV_kind(blk) != INITVKIND_BLOCK) return;
01329
01330 fprintf(fp, "\t[7]. The corresponding action info:\n");
01331 INITV_IDX first = INITV_blk(blk);
01332 for (INITV_IDX tmp = first; tmp; tmp = INITV_next(tmp)) {
01333 fprintf(fp, "\t\t.INITV.kind = %d", (int)INITV_kind(tmp));
01334 if (INITV_kind(tmp) == INITVKIND_LABEL) {
01335 LABEL& lab = Label_Table[INITV_lab(tmp)];
01336 fprintf(fp, ", lab: %d (%s)(%s)", INITV_lab(tmp), LABEL_name(lab), Get_LABEL_Kind (lab.kind));
01337 }
01338 if (INITV_kind(tmp) == INITVKIND_VAL) {
01339 int sym = TCON_ival(INITV_tc_val(tmp));
01340 fprintf(fp, ", value = 0x%08x", sym);
01341 }
01342 if (INITV_kind(tmp) == INITVKIND_ZERO) {
01343 fprintf (fp, ", value = 0");
01344 }
01345 fprintf(fp, "\n");
01346 }
01347 }
01348
01349 void
01350 EH_Print_Range_List (void)
01351 {
01352 INT32 i;
01353 for (i = 0; i < range_list.size(); i++) {
01354 EH_RANGE& range = range_list[i];
01355
01356
01357 if (Get_Trace (TP_EH, 0x0002)) {
01358 Print_EH_Range(range, TFile, i);
01359 }
01360 }
01361 fprintf (TFile, "-----------------------------------------------------------------------\n");
01362 }
01363
01364 void
01365 Print_PU_EH_Entry(PU& pu, ST* pu_st, FILE* fp)
01366 {
01367 INITO_IDX ino_idx = pu.misc;
01368
01369
01370
01371
01372
01373
01374
01375 fprintf (fp, "\n=======================================================================\n");
01376 fprintf (fp, "\t EH ENTRY INFO for PU: %s \t\n", ST_name(pu_st));
01377 fprintf (fp, "=======================================================================\n");
01378 if (ino_idx == INITO_IDX_ZERO) {
01379 fprintf(fp, "\tno eh entry\n");
01380 return;
01381 }
01382
01383 INITV_IDX exc_ptr_iv = INITO_val(ino_idx);
01384 INITV_IDX filter_iv = INITV_next(exc_ptr_iv);
01385 INITV_IDX tinfo = INITV_next(filter_iv);
01386 INITV_IDX eh_spec = INITV_next(tinfo);
01387
01388 fprintf (TFile, "\t[0].");
01389 Print_INITV_idx (exc_ptr_iv);
01390 fprintf (TFile, "\t[1].");
01391 Print_INITV_idx (filter_iv);
01392
01393
01394
01395
01396
01397 INITO_IDX id = TCON_uval(INITV_tc_val(tinfo));
01398 ST* st;
01399 INITV_IDX blk;
01400
01401 if (id != 0) {
01402 st = INITO_st(id);
01403 blk = INITO_val(id);
01404
01405 fprintf(fp, "\t[2]. tinfo list:");
01406 while (blk != INITV_IDX_ZERO) {
01407 INITV_IDX type_st_iv = INITV_blk(blk);
01408 int filter = TCON_ival(INITV_tc_val(INITV_next(type_st_iv)));
01409 ST_IDX type_st_idx = 0;
01410 if (INITVKIND_ZERO != INITV_kind(type_st_iv))
01411 type_st_idx = TCON_uval(INITV_tc_val(type_st_iv));
01412
01413 fprintf(fp, "ST_IDX = 0x%08x [%s (%d)], filter = %d\n", type_st_idx,
01414 type_st_idx ? ST_name(&St_Table[type_st_idx]) : "*ALL*",
01415 type_st_idx ? (int)(!ST_is_not_used(&St_Table[type_st_idx])) : 0,
01416 filter);
01417 blk = INITV_next(blk);
01418 }
01419 }
01420 else
01421 fprintf(fp, "\t[2]. tinfo list: <none>\n");
01422
01423
01424
01425
01426
01427 id = TCON_uval(INITV_tc_val(eh_spec));
01428 if (id != 0) {
01429 st = INITO_st(id);
01430 blk = INITO_val(id);
01431
01432 fprintf(fp, "\t[3]. eh_spec list:");
01433 FmtAssert (INITV_kind(blk) == INITVKIND_BLOCK, ("root initv for eh_spec must be block"));
01434 INITV_IDX type_st_iv = INITV_blk(blk);
01435 while (type_st_iv != INITV_IDX_ZERO) {
01436 ST_IDX type_st_idx = 0;
01437 if (INITVKIND_ZERO == INITV_kind(type_st_iv))
01438 break;
01439
01440 type_st_idx = TCON_uval(INITV_tc_val(type_st_iv));
01441 fprintf(fp, "0x%08x [%s]\n", type_st_idx,
01442 type_st_idx ? ST_name(&St_Table[type_st_idx]):"*END*");
01443 type_st_iv = INITV_next(type_st_iv);
01444 }
01445 }
01446 else
01447 fprintf(fp, "\t[3]. eh_spec list: <none>\n");
01448
01449 fprintf(fp, "\n");
01450 }
01451
01452
01453 static void
01454 INITV_Init_Integer_2(INITV_IDX inv, TYPE_ID mtype, INT64 val, UINT16 repeat)
01455 {
01456 if (val == 0)
01457 INITV_Set_ZERO (Initv_Table[inv], mtype, repeat);
01458 else {
01459 TCON tc = Host_To_Targ (mtype, val);
01460 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), repeat);
01461 }
01462 }
01463
01464 static void
01465 Check_Initv(INITV_IDX idx, FILE* fp)
01466 {
01467 if (idx == 0) return;
01468 fprintf(fp, "idx = %d, type = %d, val = %d\n", (int)idx, (int)INITV_kind(idx),
01469 (INITV_kind(idx) == INITVKIND_VAL ? TCON_ival(INITV_tc_val(idx)) : -1));
01470 FmtAssert(INITVKIND_UNK != INITV_kind(idx), ("INITV.kind = UNKNOWN\n"));
01471 if (INITVKIND_BLOCK == INITV_kind(idx))
01472 Check_Initv(INITV_blk(idx), fp);
01473 Check_Initv(INITV_next(idx), fp);
01474 }
01475
01476 static INITO* eh_pu_range_inito = NULL;
01477
01478 INITO*
01479 EH_Get_PU_Range_INITO(bool bSetNull)
01480 {
01481 INITO* ret = eh_pu_range_inito;
01482 if (bSetNull == true)
01483 eh_pu_range_inito = NULL;
01484 return ret;
01485 }
01486
01487
01488
01489
01490 #ifdef TARG_IA64
01491 bool pu_need_LSDA;
01492
01493
01494
01495
01496
01497
01498
01499 bool
01500 PU_Need_Not_Create_LSDA ()
01501 {
01502 bool flag = true;
01503 for (INT32 i = 0; i < range_list.size(); i++) {
01504 EH_RANGE& range = range_list[i];
01505 if (range.ereg_supp == 0) continue;
01506 ST* st = INITO_st(range.ereg_supp);
01507 if (ST_is_not_used(st)) continue;
01508
01509 INITV_IDX blk = INITO_val(range.ereg_supp);
01510 if (INITV_kind(blk) != INITVKIND_BLOCK)
01511 continue;
01512
01513 INITV_IDX first = INITV_blk(blk);
01514 if (INITV_kind(first) == INITVKIND_LABEL) {
01515 flag = false;
01516 return flag;
01517 }
01518 }
01519 if (flag)
01520 for (INT32 i = 0; i < range_list.size(); i++) {
01521 EH_RANGE& range = range_list[i];
01522 if (range.ereg_supp != 0) {
01523 ST* st = INITO_st(range.ereg_supp);
01524 Set_ST_is_not_used(st);
01525 }
01526 }
01527 return flag;
01528 }
01529
01530
01531
01532
01533 static void
01534 Create_INITO_For_Range_Table(ST * st, ST * pu)
01535 {
01536 INITV_IDX eh_spec_iv = Get_TF_Map_and_EH_Spec_List(Get_Current_PU(), tfmap);
01537 INITO_IDX inito = New_INITO(st);
01538 INITV_IDX inv_blk = New_INITV();
01539 INITV_IDX inv, prev_inv, cinv, inv_action, backup;
01540 int act_offset = 1;
01541
01542 eh_pu_range_inito = &Inito_Table[inito];
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 Set_INITO_val(inito, inv_blk);
01556 inv = New_INITV();
01557 INITV_Init_Block(inv_blk, inv);
01558
01559 #define WINUX_ALLOC_INV(inv) \
01560 prev_inv = inv; \
01561 inv = New_INITV(); \
01562 Set_INITV_next(prev_inv, inv);
01563
01564
01565 inv_action = cinv = New_INITV();
01566 INITV_Init_Integer_2(inv, MTYPE_U4, inv_action, 1);
01567
01568
01569 for (INT32 i = 0; i < range_list.size(); i++) {
01570 EH_RANGE& range = range_list[i];
01571 if (range.ereg_supp == 0) continue;
01572 ST* st = INITO_st(range.ereg_supp);
01573 if (ST_is_not_used(st)) continue;
01574
01575 Set_ST_is_not_used(st);
01576 INITV_IDX blk = INITO_val(range.ereg_supp);
01577 if (INITV_kind(blk) != INITVKIND_BLOCK) {
01578 Set_ST_is_not_used(st);
01579 continue;
01580 }
01581 FmtAssert(INITV_kind(blk) == INITVKIND_BLOCK,
01582 ("eh_range.ereg_supp.inito.initv.kind != block, %d\n", INITV_kind(blk)));
01583
01584 INITV_IDX first = INITV_blk(blk);
01585
01586 #ifdef OSP_OPT
01587 if ((INITV_kind(first) != INITVKIND_LABEL) &&
01588 PU_is_mainpu (Get_Current_PU ())) {
01589 continue;
01590 }
01591 #endif
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 WINUX_ALLOC_INV(inv)
01605 INITV_Init_Symdiff(inv, range.start_label, pu, !Use_Long_EH_Range_Offsets());
01606
01607
01608 WINUX_ALLOC_INV(inv)
01609 INITV_Init_Label(inv, range.start_label, 1);
01610 WINUX_ALLOC_INV(inv)
01611 INITV_Init_Label(inv, range.end_label, 1);
01612
01613
01614 WINUX_ALLOC_INV(inv)
01615 bool bHasLandingPad = true;
01616 if (INITV_kind(first) == INITVKIND_LABEL) {
01617 INITV_Init_Symdiff(inv, INITV_lab(first), pu, !Use_Long_EH_Range_Offsets());
01618 }
01619 else {
01620 INITV_Init_Integer_2(inv, MTYPE_U4, 0, 1);
01621 bHasLandingPad = false;
01622 }
01623
01624
01625 WINUX_ALLOC_INV(inv)
01626 INITV_Init_Integer_2(inv, MTYPE_U4, act_offset, 1);
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 int ar_count = 0;
01642 bool bNeedCleanup = false;
01643 for (INITV_IDX next = INITV_next(first); next; next = INITV_next(next)) {
01644
01645 int filter = 0;
01646 if (INITVKIND_ZERO != INITV_kind(next))
01647 filter = TCON_ival(INITV_tc_val(next));
01648
01649 if (filter > 0) {
01650 filter = Get_EH_Filter_By_Type(filter, tfmap);
01651 FmtAssert(bHasLandingPad, ("Landing pad must exist for handler."));
01652 }
01653 else if (filter < 0) {
01654 }
01655 else {
01656 if (INITV_next(next)) {
01657 INITV_IDX next_tmp = INITV_next(next);
01658 if (INITVKIND_VAL == INITV_kind(next_tmp))
01659 if (TCON_ival(INITV_tc_val(next_tmp)) < 0) {
01660 continue;
01661 }
01662 }
01663
01664 if (bHasLandingPad == false) continue;
01665
01666
01667
01668 filter = Get_EH_Filter_By_Type(filter, tfmap);
01669 if (filter == 0) {
01670 bNeedCleanup = true;
01671 continue;
01672 }
01673 }
01674
01675 ar_count++;
01676 WINUX_ALLOC_INV(cinv)
01677 INITV_Init_Integer_2(cinv, MTYPE_I4, filter, 1);
01678
01679 WINUX_ALLOC_INV(cinv)
01680 if (INITV_next(next) == 0) {
01681 INITV_Init_Integer_2(cinv, MTYPE_I4, 0, 1);
01682 }
01683 else {
01684 INITV_Init_Integer_2(cinv, MTYPE_I4, 1, 1);
01685 }
01686 act_offset += sizeof_signed_leb128(filter) + 1;
01687
01688 }
01689
01690 if (bNeedCleanup && ar_count) {
01691 FmtAssert(bHasLandingPad, ("Landing pad must exist for cleanup"));
01692 INITV_Init_Integer_2(cinv, MTYPE_I4, 1, 1);
01693
01694 WINUX_ALLOC_INV(cinv)
01695 INITV_Init_Integer_2(cinv, MTYPE_I4, 0, 1);
01696 WINUX_ALLOC_INV(cinv)
01697 INITV_Init_Integer_2(cinv, MTYPE_I4, 0, 1);
01698
01699 act_offset += 2;
01700 }
01701 if (ar_count == 0)
01702 INITV_Init_Integer_2(inv, MTYPE_U4, 0, 1);
01703 else
01704 INITV_Init_Integer_2(cinv, MTYPE_U4, 0, 1);
01705
01706 }
01707
01708 Set_INITV_next(inv, inv_action);
01709
01710 WINUX_ALLOC_INV(cinv)
01711 backup = INITV_next(inv_action);
01712 INITV_Init_Integer_2(inv_action, MTYPE_U4, cinv, 1);
01713 Set_INITV_next(inv_action, backup);
01714 inv_action = cinv;
01715
01716
01717 int maxft = Convert_TF_Map_To_FT_Map(tfmap, ftmap);
01718 for (int i=maxft; i >= 1; i--) {
01719 ST_IDX ix = Get_EH_ST_By_Filter(i, ftmap);
01720 WINUX_ALLOC_INV(cinv)
01721 INITV_Init_Integer_2(cinv, MTYPE_U4, ix, 1);
01722 }
01723
01724
01725
01726
01727
01728
01729
01730 WINUX_ALLOC_INV(cinv)
01731 backup = INITV_next(inv_action);
01732 INITV_Init_Integer_2(inv_action, MTYPE_U4, cinv, 1);
01733 Set_INITV_next(inv_action, backup);
01734 INITV_Init_Integer_2(cinv, MTYPE_U4, cinv, 1);
01735
01736
01737 int eh_filter = 0;
01738 for (INITV_IDX next = eh_spec_iv; next; next = INITV_next(next)) {
01739 WINUX_ALLOC_INV(cinv)
01740 eh_filter = 0;
01741 if (INITVKIND_ZERO != INITV_kind(next)) {
01742 eh_filter = Get_EH_Filter_By_Type(TCON_ival(INITV_tc_val(next)), tfmap);
01743 }
01744 INITV_Init_Integer_2(cinv, MTYPE_I4, eh_filter, 1);
01745 }
01746 if (eh_filter != 0) {
01747 WINUX_ALLOC_INV(cinv)
01748 INITV_Init_Integer_2(cinv, MTYPE_I1, 0, 1);
01749 }
01750 #undef WINUX_ALLOC_INV
01751 }
01752
01753 #else // TARG_IA64
01754
01755
01756
01757 #ifdef KEY
01758 static void
01759 Create_INITO_For_Range_Table(ST * st, ST * pu)
01760 {
01761 INITV_IDX blk=0, start, action_table_start, prev_action_start;
01762
01763
01764 int running_ofst=1;
01765 int bytes_for_filter;
01766
01767 INITO* eh_spec = Create_Type_Filter_Map ();
01768
01769 vector<INITV_IDX> action_chains;
01770
01771
01772 for (INT32 i=0; i<range_list.size(); ++i)
01773 {
01774
01775 INITV_IDX begin = New_INITV();
01776 INITV_Init_Symdiff (begin, range_list[i].start_label,
01777 pu, !Use_Long_EH_Range_Offsets());
01778
01779
01780
01781
01782 INITV_IDX high_pc = New_INITV();
01783 INITV_Init_Label (high_pc, range_list[i].end_label, 1);
01784 Set_INITV_next (begin, high_pc);
01785
01786 INITV_IDX low_pc = New_INITV();
01787 INITV_Init_Label (low_pc, range_list[i].start_label, 1);
01788 Set_INITV_next (high_pc, low_pc);
01789
01790
01791 INITO_IDX ereg = range_list[i].ereg_supp;
01792 INITV_IDX first_initv = INITV_blk (INITO_val (ereg));
01793 Set_ST_is_not_used (*(INITO_st (ereg)));
01794 #if 0
01795 if ((INITV_kind(first_initv) != INITVKIND_LABEL) &&
01796 PU_is_mainpu (Get_Current_PU ())) {
01797 continue;
01798 }
01799 #endif
01800
01801 LABEL_IDX pad_label=0;
01802 if (INITV_kind(first_initv) != INITVKIND_ZERO)
01803 pad_label = INITV_lab (first_initv);
01804
01805 INITV_IDX pad = New_INITV();
01806 if (pad_label)
01807 INITV_Init_Symdiff (pad, pad_label, pu, !Use_Long_EH_Range_Offsets());
01808 else
01809 INITV_Set_ZERO (Initv_Table[pad], MTYPE_U4, 1);
01810 Set_INITV_next (low_pc, pad);
01811
01812
01813
01814 FmtAssert (INITV_next (first_initv) != 0, ("No handler information available"));
01815 INITV_IDX action_ofst = 0;
01816 INITV_IDX first_action = New_INITV();
01817 for (INITV_IDX next_initv=INITV_next (first_initv);
01818 next_initv; next_initv=INITV_next (next_initv))
01819 {
01820 INITV_IDX action = New_INITV();
01821 int sym=0;
01822 if (INITV_kind(next_initv) != INITVKIND_ZERO)
01823 sym = TCON_uval(INITV_tc_val (next_initv));
01824
01825 bool catch_all = false;
01826 if (!sym)
01827 catch_all = (type_filter_map.find(sym) != type_filter_map.end());
01828
01829
01830
01831
01832
01833
01834
01835
01836 if (catch_all && INITV_next (next_initv))
01837 {
01838 int next_sym = 0;
01839 INITV_IDX tmp_idx = INITV_next (next_initv);
01840 if (INITV_kind (tmp_idx) != INITVKIND_ZERO)
01841 next_sym = TCON_ival (INITV_tc_val (tmp_idx));
01842 if (next_sym < 0)
01843 catch_all = false;
01844 }
01845
01846
01847
01848 if (catch_all && !pad_label) catch_all = false;
01849
01850
01851
01852 bool zero_action = false;
01853 if (sym < 0)
01854 {
01855 INITV_Set_VAL (Initv_Table[action],
01856 Enter_tcon (Host_To_Targ (MTYPE_I4,sym)), 1);
01857 bytes_for_filter = sizeof_signed_leb128 (sym);
01858 }
01859 else if (sym || catch_all)
01860 {
01861 INITV_Set_VAL (Initv_Table[action],
01862 Enter_tcon (Host_To_Targ (MTYPE_I4,type_filter_map[sym])), 1);
01863 bytes_for_filter = sizeof_signed_leb128 (type_filter_map[sym]);
01864 }
01865 else
01866 {
01867 INITV_Set_ZERO (Initv_Table[action], MTYPE_I4, 1);
01868 zero_action = true;
01869 bytes_for_filter = 1;
01870 }
01871
01872 if (!action_ofst)
01873 {
01874
01875 action_chains.push_back (action);
01876
01877
01878 if (zero_action && !INITV_next (next_initv))
01879 {
01880
01881
01882 INITV_Set_ZERO (Initv_Table[first_action], MTYPE_I4, 1);
01883 }
01884 else
01885 INITV_Set_VAL (Initv_Table[first_action],
01886 Enter_tcon (Host_To_Targ (MTYPE_I4, running_ofst)), 1);
01887
01888 Set_INITV_next (pad, first_action);
01889 }
01890
01891 if (action_ofst) Set_INITV_next (action_ofst, action);
01892
01893
01894
01895 action_ofst = New_INITV();
01896 if (INITV_next (next_initv))
01897 INITV_Set_ONE (Initv_Table[action_ofst], MTYPE_I4, 1);
01898 else
01899 INITV_Set_ZERO (Initv_Table[action_ofst], MTYPE_I4, 1);
01900 Set_INITV_next (action, action_ofst);
01901 running_ofst += (1 + bytes_for_filter);
01902 }
01903
01904 if (i == 0)
01905 {
01906 blk = start = New_INITV();
01907 INITV_Init_Block (blk, begin);
01908 }
01909 else
01910 {
01911
01912
01913 Set_INITV_next (prev_action_start, begin);
01914
01915
01916
01917
01918
01919
01920 }
01921 if (i == (range_list.size()-1))
01922 {
01923 INITO_IDX inito = New_INITO (ST_st_idx(st), start);
01924 }
01925 prev_action_start = first_action;
01926 }
01927
01928 INITV_IDX action_blk=0, prev_action_blk=0;
01929 if (action_chains.size())
01930 {
01931 action_blk = New_INITV();
01932 INITV_Init_Block (action_blk, action_chains[0], 1, INITVFLAGS_ACTION_REC);
01933 Set_INITV_next (blk, action_blk);
01934 prev_action_blk = action_blk;
01935 }
01936
01937 for (INT32 i=1; i<action_chains.size(); ++i)
01938 {
01939 action_blk = New_INITV();
01940 INITV_Init_Block (action_blk, action_chains[i], 1, INITVFLAGS_ACTION_REC);
01941 Set_INITV_next (prev_action_blk, action_blk);
01942 prev_action_blk = action_blk;
01943 }
01944
01945 vector<type_filter_entry> ti;
01946 for (map<ST_IDX, int, cmpst>::iterator i=type_filter_map.begin();
01947 i != type_filter_map.end(); ++i)
01948 {
01949 type_filter_entry f;
01950 f.st = (*i).first;
01951 f.filter = (*i).second;
01952 ti.push_back (f);
01953 }
01954 if (!ti.empty()) sort (ti.begin(), ti.end(), sort_on_filter());
01955
01956
01957 INITV_IDX prev=0;
01958 for (vector<type_filter_entry>::iterator i = ti.begin();
01959 i != ti.end(); ++i)
01960 {
01961 INITV_IDX type = New_INITV();
01962 if ((*i).st)
01963 INITV_Init_Symoff (type, &St_Table [(*i).st] , 0);
01964 else
01965 INITV_Set_ZERO (Initv_Table[type],
01966 (Is_Target_64bit() ? MTYPE_U8 : MTYPE_U4), 1);
01967 if (prev) Set_INITV_next (prev, type);
01968 else start = type;
01969 prev = type;
01970 }
01971 INITV_IDX type_blk=0;
01972 if (prev)
01973 {
01974 type_blk = New_INITV();
01975 INITV_Init_Block (type_blk, start, 1, INITVFLAGS_TYPEINFO);
01976 if (action_blk)
01977 Set_INITV_next (action_blk, type_blk);
01978 else if (blk)
01979 Set_INITV_next (blk, type_blk);
01980 }
01981 if (eh_spec)
01982 {
01983 prev=0;
01984 INITV_IDX first_eh_spec = INITV_blk (INITO_val (*eh_spec));
01985 FmtAssert (first_eh_spec, ("Empty EH specification"));
01986 for (; first_eh_spec; first_eh_spec = INITV_next (first_eh_spec))
01987 {
01988 ST_IDX sym = 0;
01989 if (INITV_kind (first_eh_spec) != INITVKIND_ZERO)
01990 sym = TCON_uval(INITV_tc_val (first_eh_spec));
01991 INITV_IDX spec = New_INITV();
01992 if (sym)
01993 INITV_Set_VAL (Initv_Table[spec],
01994 Enter_tcon (Host_To_Targ (MTYPE_I4,type_filter_map[sym])), 1);
01995 else INITV_Set_ZERO (Initv_Table[spec], MTYPE_I4, 1);
01996 if (prev) Set_INITV_next (prev, spec);
01997 else start = spec;
01998 prev = spec;
01999 }
02000 INITV_IDX spec_blk = New_INITV();
02001 INITV_Init_Block (spec_blk, start, 1, INITVFLAGS_EH_SPEC);
02002 if (type_blk)
02003 Set_INITV_next (type_blk, spec_blk);
02004 else if (action_blk)
02005 Set_INITV_next (action_blk, spec_blk);
02006 else if (blk)
02007 Set_INITV_next (blk, spec_blk);
02008 }
02009
02010 type_filter_map.clear();
02011 }
02012
02013 #else
02014
02015
02016
02017 static void
02018 Create_INITO_For_Range_Table(ST * st, ST * pu)
02019 {
02020 INITO_IDX inito = New_INITO(st);
02021 INITV_IDX inv_blk = New_INITV ();
02022 INITV_IDX inv;
02023 INITV_IDX prev_inv;
02024
02025
02026 prev_inv = Append_INITV (inv_blk, inito, INITV_IDX_ZERO);
02027 inv_blk = New_INITV ();
02028 INITV_Init_Block(prev_inv, inv_blk);
02029
02030 inv = New_INITV ();
02031 INITV_Init_Integer (inv, MTYPE_I4,
02032 (Use_Long_EH_Range_Offsets() ? LONG_OFFSETS
02033 : SHORT_OFFSETS) );
02034 INITV_Init_Block (inv_blk, inv);
02035 prev_inv = inv;
02036 inv = New_INITV ();
02037 INITV_Init_Integer (inv, MTYPE_I2, HEADER_VERSION);
02038 prev_inv = Append_INITV(inv, INITO_IDX_ZERO, prev_inv);
02039 inv = New_INITV ();
02040 INITV_Init_Integer (inv, MTYPE_I2, range_list.size());
02041 prev_inv = Append_INITV(inv, INITO_IDX_ZERO, prev_inv);
02042
02043 for (INT32 i = 0; i < range_list.size(); i++) {
02044
02045 inv_blk = Append_INITV (New_INITV (), INITO_IDX_ZERO, inv_blk);
02046
02047 inv = New_INITV();
02048 if (range_list[i].ereg_supp == 0)
02049 INITV_Init_Integer (inv, MTYPE_I4, 0);
02050 else
02051 INITV_Init_Symoff (inv, INITO_st(range_list[i].ereg_supp), 0);
02052 INITV_Init_Block (inv_blk, inv);
02053 prev_inv = inv;
02054 inv = New_INITV();
02055 INITV_Init_Integer (inv, MTYPE_I2, parent_offset(i));
02056 prev_inv = Append_INITV(inv, INITO_IDX_ZERO, prev_inv);
02057 inv = New_INITV();
02058 INITV_Init_Integer (inv, MTYPE_I2, range_list[i].kind);
02059 prev_inv = Append_INITV(inv, INITO_IDX_ZERO, prev_inv);
02060 inv = New_INITV();
02061 INITV_Init_Symdiff (inv, range_list[i].start_label,
02062 pu, !Use_Long_EH_Range_Offsets());
02063 prev_inv = Append_INITV(inv, INITO_IDX_ZERO, prev_inv);
02064 inv = New_INITV();
02065 INITV_Init_Symdiff (inv, range_list[i].end_label,
02066 pu, !Use_Long_EH_Range_Offsets());
02067 prev_inv = Append_INITV(inv, INITO_IDX_ZERO, prev_inv);
02068 }
02069 }
02070 #endif // KEY
02071 #endif // TARG_IA64
02072
02073
02074 void
02075 EH_Dump_LSDA (FILE *fp)
02076 {
02077 if (!EH_Get_PU_Range_INITO(false) || !EH_Get_PU_Range_ST())
02078 return;
02079 fprintf (TFile, "=======================================================================\n");
02080 fprintf (fp, "\t\tLSDA sturcture of PU:%s\n", ST_name (Get_Current_PU_ST()));
02081 fprintf (TFile, "=======================================================================\n");
02082
02083 ST* eh_range_table = EH_Get_PU_Range_ST();
02084 INITO *ino = EH_Get_PU_Range_INITO(false);
02085
02086 char* sym_name = ST_name(eh_range_table);
02087 FmtAssert(INITO_st(ino) == eh_range_table, ("Write_LSDA_INITO.st and inito are not paired.\n"));
02088 FmtAssert(sym_name != NULL &&
02089 strncmp(sym_name, ".range_table.", strlen(".range_table.")) == 0,
02090 ("Write_LSDA_INITO.ST name = %s\n", sym_name ? sym_name : "<null>"));
02091
02092 INITV_IDX inv_blk = INITO_val(*ino);
02093 FmtAssert(INITVKIND_BLOCK == INITV_kind(inv_blk), ("RangeTable.Initv1.kind != BLOCK\n"));
02094 INITV_IDX first = INITV_blk(inv_blk);
02095 INITV_IDX act_inv = (INITV_IDX)TCON_uval(INITV_tc_val(first));
02096 INITV_IDX type_inv = (INITV_IDX)TCON_uval(INITV_tc_val(act_inv));
02097 INITV_IDX eh_spec_inv = (INITV_IDX)TCON_uval(INITV_tc_val(type_inv));
02098
02099 INITV_IDX inv;
02100 inv = INITV_next(first);
02101
02102
02103 fprintf (fp, "\n--------------------------- CALL SITE TABLE ---------------------------\n");
02104 for(int i = 0;inv && inv != act_inv; inv = INITV_next(inv), i++) {
02105 INITV_IDX prev_inv;
02106 fprintf (fp, "Call Site Record [%d]:\n", i);
02107
02108
02109 FmtAssert (INITV_kind(inv) == INITVKIND_SYMDIFF || INITV_kind(inv) == INITVKIND_SYMDIFF16,
02110 ("@start != INITVKIND_SYMDIFF."));
02111 fprintf (fp, "\t[0]. cs_start:\t\t");
02112 Print_INITV_idx (inv);
02113
02114 inv = INITV_next(inv);
02115
02116 fprintf (fp, "\t[1]. start_label:\t");
02117 Print_INITV_idx (inv);
02118 inv = INITV_next(inv);
02119
02120 fprintf (fp, "\t[2]. end_label:\t\t");
02121 Print_INITV_idx (inv);
02122
02123 inv = INITV_next(inv);
02124
02125 if (INITVKIND_ZERO != INITV_kind(inv)) {
02126 FmtAssert(INITVKIND_SYMDIFF == INITV_kind(inv) ||
02127 INITVKIND_SYMDIFF16 == INITV_kind(inv), ("CS_lp.kind != INITVKIND_SYMDIFF."));
02128 fprintf (fp, "\t[3]. landing pad:\t");
02129 Print_INITV_idx (inv);
02130 }
02131 else {
02132 fprintf (fp, "\t[3]. NO landing pad:\t");
02133 Print_INITV_idx (inv);
02134 }
02135
02136 inv = INITV_next(inv);
02137
02138 fprintf (fp, "\t[4]. cs_action:\t\t");
02139 Print_INITV_idx (inv);
02140 }
02141
02142
02143 inv = INITV_next(act_inv);
02144 fprintf (fp, "\n---------------------------- ACTION TABLE -----------------------------\n");
02145 for(int i = 0; inv && inv != type_inv; inv = INITV_next(inv), i++) {
02146 fprintf (fp, "Action Record [%d]:\n", i);
02147
02148 fprintf (fp, "\t[0]. ar_filter:\t\t");
02149 Print_INITV_idx (inv);
02150
02151
02152 fprintf (fp, "\t[1]. ar_next:\t\t");
02153 Print_INITV_idx (inv);
02154 }
02155
02156
02157 inv = INITV_next(type_inv);
02158 fprintf (fp, "\n------------------------------ TYPE TABLE ------------------------------\n");
02159 for(int i = 0; inv && inv != eh_spec_inv; inv = INITV_next(inv)) {
02160 int eh_filter = 0;
02161 ST_IDX type_st_idx = 0;
02162 fprintf (fp, "Exceptions Object [%d]:\n", i);
02163 fprintf (fp, "\t[0]. ");
02164 Print_INITV_idx (inv);
02165 if (INITVKIND_ZERO != INITV_kind(inv))
02166 type_st_idx = TCON_uval(INITV_tc_val(inv));
02167 if (type_st_idx == 0)
02168 fprintf(fp, "\t[1]. type_st_idx == 0\n");
02169 else {
02170 fprintf (fp, "\t[1]. exceptions object: %s\n", ST_name (type_st_idx));
02171 eh_filter = Get_EH_Filter_By_Type (type_st_idx, tfmap);
02172 fprintf (fp, "\t[2]. eh_filter: %d\n", eh_filter);
02173 }
02174 }
02175
02176
02177 fprintf (fp, "\n------------------------ TYPE SPECIFICATION TABLE -----------------------\n");
02178 fprintf (fp, "Exception Objects Type in eh_spec:");
02179 inv = INITV_next(eh_spec_inv);
02180 for(int i = 0; inv; inv = INITV_next(inv), i++) {
02181 ST_IDX type_st_idx;
02182 fprintf (fp, "\t[%d]. ", i);
02183 Print_INITV_idx (inv);
02184 if (INITVKIND_ZERO != INITV_kind(inv)) {
02185 type_st_idx = Get_EH_ST_By_Filter (TCON_ival(INITV_tc_val(inv)), ftmap);
02186 fprintf (fp, "%s\n", ST_name (type_st_idx));
02187 }
02188 else
02189 fprintf (fp, "\n");
02190 }
02191 fprintf (fp, "\n");
02192 }
02193
02194
02195 struct SET_NOT_USED {
02196 SET_NOT_USED() {}
02197 void operator()(EH_RANGE& r) {
02198 Set_ST_is_not_used(INITO_st(r.ereg_supp));
02199 }
02200 };
02201
02202 void
02203 EH_Write_Range_Table(WN * wn)
02204 {
02205 if (range_list.size() == 0) {
02206 eh_pu_range_st = NULL;
02207 return;
02208 }
02209
02210 #ifdef KEY
02211
02212 if (!LANG_Enable_CXX_Openmp && PU_mp_lower_generated (Get_Current_PU ()))
02213 {
02214 EH_RANGE_LIST::iterator first(range_list.begin());
02215 EH_RANGE_LIST::iterator last(range_list.end());
02216 for_each (first, last, SET_NOT_USED());
02217 eh_pu_range_st = NULL;
02218 return;
02219 }
02220 #endif // KEY
02221
02222 fix_mask_ranges();
02223 reorder_range_list();
02224 #ifdef KEY
02225 flatten_regions();
02226 reorder_range_list();
02227 #endif
02228
02229 ST * st = ST_For_Range_Table(wn);
02230 eh_pu_range_st = st;
02231 Create_INITO_For_Range_Table(st, WN_st(wn));
02232 }
02233
02234 void print_label(LABEL_IDX label)
02235 {
02236 Label_Table[label].Print(stderr);
02237 }