Skip to content

Commit 46e0b9f

Browse files
author
Daniel Kroening
authored
Merge pull request #403 from smowton/find_scopes_for_anonymous_variables
Find scopes for anonymous variables
2 parents cd4fc7b + b3b2683 commit 46e0b9f

File tree

5 files changed

+129
-42
lines changed

5 files changed

+129
-42
lines changed
329 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
test.class
3+
--show-goto-functions
4+
dead anonlocal::1i
5+
dead anonlocal::2i
6+
dead anonlocal::3a
7+
dead new_tmp0
8+
^EXIT=0$
9+
^SIGNAL=0$
10+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
3+
public class test
4+
{
5+
public static void main(int unknown)
6+
{
7+
int i;
8+
int j;
9+
if(unknown==1)
10+
{
11+
// Check that anonymous locals
12+
// get assigned scopes:
13+
i = 0;
14+
i++;
15+
}
16+
else if(unknown==2)
17+
{
18+
j = 0;
19+
j++;
20+
}
21+
else
22+
{
23+
// Check that temporaries (here
24+
// a new_tmp variable) are treated
25+
// likewise
26+
test t = new test();
27+
}
28+
}
29+
}

src/java_bytecode/java_bytecode_convert_method.cpp

+89-41
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,43 @@ code_blockt &java_bytecode_convert_methodt::get_or_create_block_for_pcrange(
712712
to_code(this_block_children[child_offset])).code());
713713
}
714714

715+
static void gather_symbol_live_ranges(
716+
unsigned pc,
717+
const exprt &e,
718+
std::map<irep_idt, java_bytecode_convert_methodt::variablet> &result)
719+
{
720+
if(e.id()==ID_symbol)
721+
{
722+
const auto &symexpr=to_symbol_expr(e);
723+
auto findit=
724+
result.insert({
725+
symexpr.get_identifier(),
726+
java_bytecode_convert_methodt::variablet()});
727+
auto &var=findit.first->second;
728+
if(findit.second)
729+
{
730+
var.symbol_expr=symexpr;
731+
var.start_pc=pc;
732+
var.length=1;
733+
}
734+
else
735+
{
736+
if(pc<var.start_pc)
737+
{
738+
var.length+=(var.start_pc-pc);
739+
var.start_pc=pc;
740+
}
741+
else
742+
{
743+
var.length=std::max(var.length, (pc-var.start_pc)+1);
744+
}
745+
}
746+
}
747+
else
748+
forall_operands(it, e)
749+
gather_symbol_live_ranges(pc, *it, result);
750+
}
751+
715752
/*******************************************************************\
716753
717754
Function: java_bytecode_convert_methodt::convert_instructions
@@ -1959,10 +1996,9 @@ codet java_bytecode_convert_methodt::convert_instructions(
19591996
// review successor computation of athrow!
19601997
code_blockt code;
19611998

1962-
// locals
1999+
// Add anonymous locals to the symtab:
19632000
for(const auto &var : used_local_names)
19642001
{
1965-
code.add(code_declt(var));
19662002
symbolt new_symbol;
19672003
new_symbol.name=var.get_identifier();
19682004
new_symbol.type=var.type();
@@ -1975,11 +2011,6 @@ codet java_bytecode_convert_methodt::convert_instructions(
19752011
new_symbol.is_lvalue=true;
19762012
symbol_table.add(new_symbol);
19772013
}
1978-
// temporaries
1979-
for(const auto &var : tmp_vars)
1980-
{
1981-
code.add(code_declt(var));
1982-
}
19832014

19842015
// Try to recover block structure as indicated in the local variable table:
19852016

@@ -2025,44 +2056,61 @@ codet java_bytecode_convert_methodt::convert_instructions(
20252056
start_new_block=address_pair.second.successors.size()>1;
20262057
}
20272058

2059+
// Find out where temporaries are used:
2060+
std::map<irep_idt, variablet> temporary_variable_live_ranges;
2061+
for(const auto &aentry : address_map)
2062+
gather_symbol_live_ranges(
2063+
aentry.first,
2064+
aentry.second.code,
2065+
temporary_variable_live_ranges);
2066+
2067+
std::vector<const variablet*> vars_to_process;
20282068
for(const auto &vlist : variables)
2029-
{
20302069
for(const auto &v : vlist)
2031-
{
2032-
if(v.is_parameter)
2033-
continue;
2034-
// Merge lexical scopes as far as possible to allow us to
2035-
// declare these variable scopes faithfully.
2036-
// Don't insert yet, as for the time being the blocks' only
2037-
// operands must be other blocks.
2038-
// The declarations will be inserted in the next pass instead.
2039-
get_or_create_block_for_pcrange(
2040-
root,
2041-
root_block,
2042-
v.start_pc,
2043-
v.start_pc+v.length,
2044-
std::numeric_limits<unsigned>::max(),
2045-
address_map);
2046-
}
2070+
vars_to_process.push_back(&v);
2071+
2072+
for(const auto &v : tmp_vars)
2073+
vars_to_process.push_back(
2074+
&temporary_variable_live_ranges.at(v.get_identifier()));
2075+
2076+
for(const auto &v : used_local_names)
2077+
vars_to_process.push_back(
2078+
&temporary_variable_live_ranges.at(v.get_identifier()));
2079+
2080+
for(const auto vp : vars_to_process)
2081+
{
2082+
const auto &v=*vp;
2083+
if(v.is_parameter)
2084+
continue;
2085+
// Merge lexical scopes as far as possible to allow us to
2086+
// declare these variable scopes faithfully.
2087+
// Don't insert yet, as for the time being the blocks' only
2088+
// operands must be other blocks.
2089+
// The declarations will be inserted in the next pass instead.
2090+
get_or_create_block_for_pcrange(
2091+
root,
2092+
root_block,
2093+
v.start_pc,
2094+
v.start_pc+v.length,
2095+
std::numeric_limits<unsigned>::max(),
2096+
address_map);
20472097
}
2048-
for(const auto &vlist : variables)
2098+
for(const auto vp : vars_to_process)
20492099
{
2050-
for(const auto &v : vlist)
2051-
{
2052-
if(v.is_parameter)
2053-
continue;
2054-
// Skip anonymous variables:
2055-
if(v.symbol_expr.get_identifier()==irep_idt())
2056-
continue;
2057-
auto &block=get_block_for_pcrange(
2058-
root,
2059-
root_block,
2060-
v.start_pc,
2061-
v.start_pc+v.length,
2062-
std::numeric_limits<unsigned>::max());
2063-
code_declt d(v.symbol_expr);
2064-
block.operands().insert(block.operands().begin(), d);
2065-
}
2100+
const auto &v=*vp;
2101+
if(v.is_parameter)
2102+
continue;
2103+
// Skip anonymous variables:
2104+
if(v.symbol_expr.get_identifier()==irep_idt())
2105+
continue;
2106+
auto &block=get_block_for_pcrange(
2107+
root,
2108+
root_block,
2109+
v.start_pc,
2110+
v.start_pc+v.length,
2111+
std::numeric_limits<unsigned>::max());
2112+
code_declt d(v.symbol_expr);
2113+
block.operands().insert(block.operands().begin(), d);
20662114
}
20672115

20682116
for(auto &block : root_block.operands())

src/java_bytecode/java_bytecode_convert_method_class.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class java_bytecode_convert_methodt:public messaget
7373
typedef std::vector<local_variable_with_holest>
7474
local_variable_table_with_holest;
7575

76-
protected:
7776
class variablet
7877
{
7978
public:
@@ -85,6 +84,7 @@ class java_bytecode_convert_methodt:public messaget
8584
variablet() : symbol_expr(), start_pc(0), length(0), is_parameter(false) {}
8685
};
8786

87+
protected:
8888
typedef std::vector<variablet> variablest;
8989
expanding_vector<variablest> variables;
9090
std::set<symbol_exprt> used_local_names;

0 commit comments

Comments
 (0)