20
20
template <class T >
21
21
struct procedure_local_cfg_baset <
22
22
T,
23
- const java_bytecode_convert_methodt::address_mapt ,
23
+ java_bytecode_convert_methodt::method_with_amapt ,
24
24
unsigned > :
25
25
public graph<cfg_base_nodet<T, unsigned > >
26
26
{
27
- typedef java_bytecode_convert_methodt::address_mapt address_mapt ;
27
+ typedef java_bytecode_convert_methodt::method_with_amapt method_with_amapt ;
28
28
typedef std::map<unsigned , unsigned > entry_mapt;
29
29
entry_mapt entry_map;
30
30
31
31
procedure_local_cfg_baset () {}
32
32
33
- void operator ()(const address_mapt& amap )
33
+ void operator ()(const method_with_amapt &args )
34
34
{
35
- for (const auto & inst : amap)
35
+ const auto &method=args.first ;
36
+ const auto &amap=args.second ;
37
+ for (const auto &inst : amap)
36
38
{
37
39
// Map instruction PCs onto node indices:
38
40
entry_map[inst.first ]=this ->add_node ();
39
41
// Map back:
40
42
(*this )[entry_map[inst.first ]].PC =inst.first ;
41
43
}
42
- for (const auto & inst : amap)
44
+ // Add edges declared in the address map:
45
+ for (const auto &inst : amap)
43
46
{
44
47
for (auto succ : inst.second .successors )
45
48
this ->add_edge (entry_map.at (inst.first ), entry_map.at (succ));
46
49
}
50
+ // Next, add edges declared in the exception table, which
51
+ // don't figure in the address map successors/predecessors as yet:
52
+ for (const auto &table_entry : method.exception_table )
53
+ {
54
+ auto findit=amap.find (table_entry.start_pc );
55
+ assert (findit!=amap.end () &&
56
+ " Exception table entry doesn't point to an instruction?" );
57
+ for (; findit->first <table_entry.end_pc ; ++findit)
58
+ {
59
+ // For now just assume any non-branch
60
+ // instruction could potentially throw.
61
+ auto succit=findit;
62
+ ++succit;
63
+ if (succit==amap.end ())
64
+ continue ;
65
+ const auto &thisinst=findit->second ;
66
+ if (thisinst.successors .size ()==1 &&
67
+ thisinst.successors .back ()==succit->first )
68
+ {
69
+ this ->add_edge (
70
+ entry_map.at (findit->first ),
71
+ entry_map.at (table_entry.handler_pc ));
72
+ }
73
+ }
74
+ }
47
75
}
48
76
49
- unsigned get_first_node (const address_mapt& amap ) const
77
+ unsigned get_first_node (const method_with_amapt &args ) const
50
78
{
51
- return amap .begin ()->first ;
79
+ return args. second .begin ()->first ;
52
80
}
53
- unsigned get_last_node (const address_mapt& amap ) const
81
+ unsigned get_last_node (const method_with_amapt &args ) const
54
82
{
55
- return (--amap .end ())->first ;
83
+ return (--args. second .end ())->first ;
56
84
}
57
- unsigned nodes_empty (const address_mapt& amap ) const
85
+ unsigned nodes_empty (const method_with_amapt &args ) const
58
86
{
59
- return amap .empty ();
87
+ return args. second .empty ();
60
88
}
61
89
};
62
90
@@ -75,8 +103,8 @@ typedef java_bytecode_convert_methodt::java_cfg_dominatorst
75
103
// Comparators for local variables:
76
104
77
105
static bool lt_index (
78
- const local_variable_with_holest& a,
79
- const local_variable_with_holest& b)
106
+ const local_variable_with_holest & a,
107
+ const local_variable_with_holest & b)
80
108
{
81
109
return a.var .index <b.var .index ;
82
110
}
@@ -96,9 +124,9 @@ typedef std::map<
96
124
97
125
struct is_predecessor_oft
98
126
{
99
- const predecessor_mapt& order;
127
+ const predecessor_mapt & order;
100
128
101
- explicit is_predecessor_oft (const predecessor_mapt& _order) : order(_order) {}
129
+ explicit is_predecessor_oft (const predecessor_mapt & _order) : order(_order) {}
102
130
103
131
bool operator ()(
104
132
local_variable_with_holest* a,
@@ -129,7 +157,7 @@ Function: gather_transitive_predecessors
129
157
130
158
static void gather_transitive_predecessors (
131
159
local_variable_with_holest* start,
132
- const predecessor_mapt& predecessor_map,
160
+ const predecessor_mapt & predecessor_map,
133
161
std::set<local_variable_with_holest*>& result)
134
162
{
135
163
if (!result.insert (start).second )
@@ -156,7 +184,7 @@ Function: is_store_to_slot
156
184
\*******************************************************************/
157
185
158
186
static bool is_store_to_slot (
159
- const java_bytecode_convert_methodt::instructiont& inst,
187
+ const java_bytecode_convert_methodt::instructiont & inst,
160
188
unsigned slotidx)
161
189
{
162
190
const std::string prevstatement=id2string (inst.statement );
@@ -167,7 +195,7 @@ static bool is_store_to_slot(
167
195
if (inst.args .size ()==1 )
168
196
{
169
197
// Store with an argument:
170
- const auto & arg=inst.args [0 ];
198
+ const auto & arg=inst.args [0 ];
171
199
storeslot=id2string (to_constant_expr (arg).get_value ());
172
200
}
173
201
else
@@ -195,7 +223,7 @@ Function: maybe_add_hole
195
223
\*******************************************************************/
196
224
197
225
static void maybe_add_hole (
198
- local_variable_with_holest& var,
226
+ local_variable_with_holest & var,
199
227
unsigned from,
200
228
unsigned to)
201
229
{
@@ -271,9 +299,9 @@ static void populate_predecessor_map(
271
299
local_variable_table_with_holest::iterator firstvar,
272
300
local_variable_table_with_holest::iterator varlimit,
273
301
const std::vector<local_variable_with_holest*>& live_variable_at_address,
274
- const address_mapt& amap,
275
- predecessor_mapt& predecessor_map,
276
- message_handlert& msg_handler)
302
+ const address_mapt & amap,
303
+ predecessor_mapt & predecessor_map,
304
+ message_handlert & msg_handler)
277
305
{
278
306
messaget msg (msg_handler);
279
307
for (auto it=firstvar, itend=varlimit; it!=itend; ++it)
@@ -385,7 +413,7 @@ Function: get_common_dominator
385
413
386
414
static unsigned get_common_dominator (
387
415
const std::set<local_variable_with_holest*>& merge_vars,
388
- const java_cfg_dominatorst& dominator_analysis)
416
+ const java_cfg_dominatorst & dominator_analysis)
389
417
{
390
418
assert (!merge_vars.empty ());
391
419
@@ -399,9 +427,9 @@ static unsigned get_common_dominator(
399
427
std::vector<unsigned > candidate_dominators;
400
428
for (auto v : merge_vars)
401
429
{
402
- const auto & dominator_nodeidx=
430
+ const auto & dominator_nodeidx=
403
431
dominator_analysis.cfg .entry_map .at (v->var .start_pc );
404
- const auto & this_var_doms=
432
+ const auto & this_var_doms=
405
433
dominator_analysis.cfg [dominator_nodeidx].dominators ;
406
434
for (const auto this_var_dom : this_var_doms)
407
435
if (this_var_dom<=first_pc)
@@ -451,7 +479,7 @@ Function: populate_live_range_holes
451
479
\*******************************************************************/
452
480
453
481
static void populate_live_range_holes (
454
- local_variable_with_holest& merge_into,
482
+ local_variable_with_holest & merge_into,
455
483
const std::set<local_variable_with_holest*>& merge_vars,
456
484
unsigned expanded_live_range_start)
457
485
{
@@ -489,10 +517,10 @@ Function: merge_variable_table_entries
489
517
\*******************************************************************/
490
518
491
519
static void merge_variable_table_entries (
492
- local_variable_with_holest& merge_into,
520
+ local_variable_with_holest & merge_into,
493
521
const std::set<local_variable_with_holest*>& merge_vars,
494
- const java_cfg_dominatorst& dominator_analysis,
495
- std::ostream& debug_out)
522
+ const java_cfg_dominatorst & dominator_analysis,
523
+ std::ostream & debug_out)
496
524
{
497
525
// Because we need a lexically-scoped declaration,
498
526
// we must have the merged variable
@@ -527,7 +555,7 @@ static void merge_variable_table_entries(
527
555
#endif
528
556
529
557
// Nuke the now-subsumed var-table entries:
530
- for (auto & v : merge_vars)
558
+ for (auto & v : merge_vars)
531
559
if (v!=&merge_into)
532
560
v->var .length =0 ;
533
561
}
@@ -557,8 +585,8 @@ Function: find_initialisers_for_slot
557
585
void java_bytecode_convert_methodt::find_initialisers_for_slot (
558
586
local_variable_table_with_holest::iterator firstvar,
559
587
local_variable_table_with_holest::iterator varlimit,
560
- const address_mapt& amap,
561
- const java_cfg_dominatorst& dominator_analysis)
588
+ const address_mapt & amap,
589
+ const java_cfg_dominatorst & dominator_analysis)
562
590
{
563
591
// Build a simple map from instruction PC to the variable
564
592
// live in this slot at that PC, and a map from each variable
@@ -582,7 +610,7 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot(
582
610
// Now merge vartable entries according to the predecessor_map:
583
611
584
612
// Take the transitive closure of the predecessor map:
585
- for (auto & kv : predecessor_map)
613
+ for (auto & kv : predecessor_map)
586
614
{
587
615
std::set<local_variable_with_holest*> closed_preds;
588
616
gather_transitive_predecessors (kv.first , predecessor_map, closed_preds);
@@ -609,7 +637,7 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot(
609
637
if (findit==predecessor_map.end ())
610
638
continue ;
611
639
612
- const auto & merge_vars=findit->second ;
640
+ const auto & merge_vars=findit->second ;
613
641
assert (merge_vars.size ()>=2 );
614
642
615
643
merge_variable_table_entries (
@@ -638,8 +666,8 @@ Function: walk_to_next_index
638
666
\*******************************************************************/
639
667
640
668
static void walk_to_next_index (
641
- local_variable_table_with_holest::iterator& it1,
642
- local_variable_table_with_holest::iterator& it2,
669
+ local_variable_table_with_holest::iterator & it1,
670
+ local_variable_table_with_holest::iterator & it2,
643
671
local_variable_table_with_holest::iterator itend)
644
672
{
645
673
if (it2==itend)
@@ -671,9 +699,9 @@ Function: find_initialisers
671
699
\*******************************************************************/
672
700
673
701
void java_bytecode_convert_methodt::find_initialisers (
674
- local_variable_table_with_holest& vars,
675
- const address_mapt& amap,
676
- const java_cfg_dominatorst& dominator_analysis)
702
+ local_variable_table_with_holest & vars,
703
+ const address_mapt & amap,
704
+ const java_cfg_dominatorst & dominator_analysis)
677
705
{
678
706
// Sort table entries by local slot index:
679
707
std::sort (vars.begin (), vars.end (), lt_index);
@@ -739,17 +767,18 @@ Function: setup_local_variables
739
767
\*******************************************************************/
740
768
741
769
void java_bytecode_convert_methodt::setup_local_variables (
742
- const methodt& m,
743
- const address_mapt& amap)
770
+ const methodt & m,
771
+ const address_mapt & amap)
744
772
{
745
773
// Compute CFG dominator tree
746
774
java_cfg_dominatorst dominator_analysis;
747
- dominator_analysis (amap);
775
+ method_with_amapt dominator_args (m, amap);
776
+ dominator_analysis (dominator_args);
748
777
749
778
// Find out which local variable table entries should be merged:
750
779
// Wrap each entry so we have somewhere to record live ranges with holes:
751
780
std::vector<local_variable_with_holest> vars_with_holes;
752
- for (const auto & v : m.local_variable_table )
781
+ for (const auto & v : m.local_variable_table )
753
782
vars_with_holes.push_back ({v, {}});
754
783
755
784
// Merge variable records:
0 commit comments