@@ -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
717754Function: 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 ())
0 commit comments