21 natural_loops(goto_program);
41 for(
auto predecessor : it->incoming_edges)
44 predecessor->location_number > it->location_number &&
54 for(
const auto &loop : natural_loops.
loop_map)
56 std::size_t backedge_count = std::count_if(
57 loop.first->incoming_edges.begin(),
58 loop.first->incoming_edges.end(),
60 return loop.first->location_number < predecessor->location_number;
62 if(backedge_count > 1)
75 unordered_map<goto_programt::const_targett, std::size_t, const_target_hash>
84 std::vector<std::size_t> loop_size_by_id;
86 std::size_t loop_id = 0;
87 for(
const auto &header_and_loop : natural_loops.
loop_map)
89 const auto &loop = header_and_loop.second;
90 loop_size_by_id.push_back(loop.size());
92 for(
const auto &instruction : loop)
94 auto emplace_result = innermost_loop_ids.emplace(instruction, loop_id);
95 if(!emplace_result.second)
99 if(loop_size_by_id.at(emplace_result.first->second) > loop.size())
100 emplace_result.first->second = loop_id;
107 return innermost_loop_ids;
114 auto findit = innermost_loops.find(target);
115 if(findit == innermost_loops.end())
118 return (
long)findit->second;
127 postdominators(goto_program);
139 successors.size() == 1 &&
140 (*successors.begin())->incoming_edges.size() == 1)
143 const auto &instruction_postdoms = postdominators.
get_node(it).dominators;
151 std::size_t closest_exit_index = dominators.cfg.size();
152 for(
const auto &possible_exit : instruction_postdoms)
154 const auto possible_exit_index = dominators.get_node_index(possible_exit);
155 const auto &possible_exit_node = dominators.cfg[possible_exit_index];
156 const auto possible_exit_dominators =
157 possible_exit_node.dominators.size();
160 it != possible_exit && dominators.dominates(it, possible_exit_node) &&
167 closest_exit_index == dominators.cfg.size() ||
168 dominators.cfg[closest_exit_index].dominators.size() >
169 possible_exit_dominators)
171 closest_exit_index = possible_exit_index;
176 if(closest_exit_index < dominators.cfg.size())
178 auto emplace_result =
179 sese_regions.emplace(it, dominators.cfg[closest_exit_index].PC);
181 emplace_result.second,
"should only visit each region entry once");
188 auto rhs_trim_idx = input.size() - 1;
189 while(rhs_trim_idx > 0 && isspace(input[rhs_trim_idx]))
192 auto lhs_trim_idx = input.rfind(
'\n', rhs_trim_idx);
193 if(lhs_trim_idx == std::string::npos)
196 while(lhs_trim_idx < input.size() && isspace(input[lhs_trim_idx]))
199 return input.substr(lhs_trim_idx, (rhs_trim_idx - lhs_trim_idx) + 1);
203 unordered_map<goto_programt::const_targett, std::size_t, const_target_hash>
209 &program_relative_instruction_indices)
212 std::to_string(program_relative_instruction_indices.at(instruction)) +
221 &program_relative_instruction_indices)
223 std::ostringstream ostr;
224 instruction->output(ostr);
226 instruction, program_relative_instruction_indices) +
236 std::size_t next_index = 0;
241 program_relative_instruction_indices.emplace(it, next_index);
244 <<
" single-entry, single-exit regions:\n";
247 out <<
"Region starting at "
252 program_relative_instruction_indices)
258 program_relative_instruction_indices)