49 std::shared_ptr<InstructionSequence>
get_start_block(
const std::shared_ptr<ControlFlowGraph> &cfg)
const {
50 return cfg->get_entry_block();
60 return cfg->get_outgoing_edges(bb);
68 std::shared_ptr<InstructionSequence>
get_block(
const Edge *edge)
const {
81 std::shared_ptr<InstructionSequence>
get_start_block(
const std::shared_ptr<ControlFlowGraph> &cfg)
const {
82 return cfg->get_exit_block();
92 return cfg->get_incoming_edges(bb);
176 template<
typename DataflowType>
179 DataflowType &m_dataflow;
184 : m_dataflow(dataflow) {
187 std::string get_instruction_annotation(std::shared_ptr<InstructionSequence> bb,
Instruction *ins)
const {
189 typename DataflowType::FactType fact = m_dataflow.get_fact_before_instruction(bb, ins);
190 std::string s = DataflowType::fact_to_string(fact);
202 typename DataflowType::FactType fact = m_dataflow.get_fact_at_beginning_of_block(bb);
203 return DataflowType::fact_to_string(fact);
213 typename DataflowType::FactType fact = m_dataflow.get_fact_at_end_of_block(bb);
214 return DataflowType::fact_to_string(fact);
232 template<
typename Analysis>
250 std::shared_ptr<ControlFlowGraph> m_cfg;
253 std::vector<FactType> m_endfacts, m_beginfacts;
256 std::vector<unsigned> m_iter_order;
261 Dataflow(
const std::shared_ptr<ControlFlowGraph> &cfg);
302 std::vector<typename Analysis::FactType> &get_logical_begin_facts() {
303 return Analysis::DIRECTION == DataflowDirection::FORWARD
308 std::vector<typename Analysis::FactType> &get_logical_end_facts() {
309 return Analysis::DIRECTION == DataflowDirection::FORWARD
314 const std::vector<typename Analysis::FactType> &get_logical_begin_facts()
const {
315 return Analysis::DIRECTION == DataflowDirection::FORWARD
320 const std::vector<typename Analysis::FactType> &get_logical_end_facts()
const {
321 return Analysis::DIRECTION == DataflowDirection::FORWARD
327 FactType get_instruction_fact(std::shared_ptr<InstructionSequence> bb,
Instruction *ins,
bool after_in_logical_order)
const;
330 void compute_iter_order();
334 void postorder_on_cfg(std::bitset<MAX_BLOCKS> &visited, std::shared_ptr<InstructionSequence> bb);
337 template<
typename Analysis>
340 for (
unsigned i = 0; i < cfg->get_num_blocks(); ++i) {
341 m_beginfacts.push_back(m_analysis.get_top_fact());
342 m_endfacts.push_back(m_analysis.get_top_fact());
346 template<
typename Analysis>
350 template<
typename Analysis>
352 compute_iter_order();
354 std::vector<FactType> &logical_begin_facts = get_logical_begin_facts(),
355 &logical_end_facts = get_logical_end_facts();
357 const auto &to_logical_predecessors = m_analysis.LOGICAL_BACKWARD;
361 unsigned num_iters = 0;
367 for (
auto i = m_iter_order.begin(); i != m_iter_order.end(); i++) {
369 std::shared_ptr<InstructionSequence> bb = m_cfg->get_block(
id);
373 FactType fact = m_analysis.get_top_fact();
375 for (
auto j = logical_predecessor_edges.cbegin(); j != logical_predecessor_edges.cend(); j++) {
377 std::shared_ptr<InstructionSequence> logical_predecessor = to_logical_predecessors.get_block(e);
378 fact = m_analysis.combine_facts(fact, logical_end_facts[logical_predecessor->get_block_id()]);
383 logical_begin_facts[id] = fact;
386 for (
auto j = m_analysis.begin(bb); j != m_analysis.end(bb); ++j) {
390 m_analysis.model_instruction(ins, fact);
395 if (fact != logical_end_facts[
id]) {
397 logical_end_facts[id] = fact;
409 template<
typename Analysis>
411 return m_endfacts.at(bb->get_block_id());
414 template<
typename Analysis>
416 return m_beginfacts.at(bb->get_block_id());
419 template<
typename Analysis>
423 bool after_in_logical_order = (Analysis::DIRECTION == DataflowDirection::FORWARD);
424 return get_instruction_fact(bb, ins, after_in_logical_order);
427 template<
typename Analysis>
431 bool after_in_logical_order = (Analysis::DIRECTION == DataflowDirection::BACKWARD);
432 return get_instruction_fact(bb, ins, after_in_logical_order);
435 template<
typename Analysis>
438 return analysis.fact_to_string(fact);
444 template<
typename Analysis>
447 bool after_in_logical_order)
const {
448 const std::vector<FactType> &logical_begin_facts = get_logical_begin_facts();
450 FactType fact = logical_begin_facts[bb->get_block_id()];
452 for (
auto i = m_analysis.begin(bb); i != m_analysis.end(bb); ++i) {
454 bool at_instruction = (bb_ins == ins);
456 if (at_instruction && !after_in_logical_order)
break;
458 m_analysis.model_instruction(bb_ins, fact);
460 if (at_instruction) {
461 assert(after_in_logical_order);
469 template<
typename Analysis>
471 std::bitset<MAX_BLOCKS> visited;
473 const auto &to_logical_successors = m_analysis.LOGICAL_FORWARD;
475 std::shared_ptr<InstructionSequence> logical_entry_block = to_logical_successors.get_start_block(m_cfg);
477 postorder_on_cfg(visited, logical_entry_block);
479 std::reverse(m_iter_order.begin(), m_iter_order.end());
482 template<
typename Analysis>
484 const auto &to_logical_successors = m_analysis.LOGICAL_FORWARD;
487 if (visited.test(bb->get_block_id())) {
492 visited.set(bb->get_block_id());
496 for (
auto i = logical_successor_edges.begin(); i != logical_successor_edges.end(); i++) {
498 std::shared_ptr<InstructionSequence> next_bb = to_logical_successors.get_block(e);
499 postorder_on_cfg(visited, next_bb);
503 m_iter_order.push_back(bb->get_block_id());
ControlFlowGraph and associated types.
Base class for backward analyses.
Definition: dataflow.h:139
InstructionIterator begin(std::shared_ptr< InstructionSequence > bb) const
Get a begin iterator over the instructions in a basic block in "analysis" order.
Definition: dataflow.h:152
static const DataflowDirection DIRECTION
Analysis direction is backward.
Definition: dataflow.h:142
BackwardNavigation LOGICAL_FORWARD
Logical forward navigation through the ControlFlowGraph in analysis order.
Definition: dataflow.h:164
ForwardNavigation LOGICAL_BACKWARD
Logical backward navigation through the ControlFlowGraph in analysis order.
Definition: dataflow.h:168
InstructionIterator end(std::shared_ptr< InstructionSequence > bb) const
Get an end iterator over the instructions in a basic block in "analysis" order.
Definition: dataflow.h:158
InstructionSequence::const_reverse_iterator InstructionIterator
Iterator type for iterating over instructions in a basic block in "analysis" order.
Definition: dataflow.h:146
Backward navigation in the control-flow graph (from successors back to predecessors).
Definition: dataflow.h:75
std::shared_ptr< InstructionSequence > get_start_block(const std::shared_ptr< ControlFlowGraph > &cfg) const
Get the "start" block in the ControlFlowGraph, which for a backward analysis is the exit block.
Definition: dataflow.h:81
const ControlFlowGraph::EdgeList & get_edges(const std::shared_ptr< ControlFlowGraph > &cfg, std::shared_ptr< InstructionSequence > bb) const
Get the control edges for a given block which lead to the "logical successors" of the block.
Definition: dataflow.h:91
std::shared_ptr< InstructionSequence > get_block(const Edge *edge) const
Get the basic block that is a "logical" successor from an Edge returned from the get_edges member fun...
Definition: dataflow.h:100
std::vector< Edge * > EdgeList
Data type for a vector of edges.
Definition: cfg.h:92
Annotator to return a stringified dataflow fact for a specific instruction in a basic block.
Definition: dataflow.h:177
virtual std::string get_block_end_annotation(std::shared_ptr< InstructionSequence > bb) const
Get an end annotation for a basic block.
Definition: dataflow.h:212
virtual std::string get_block_begin_annotation(std::shared_ptr< InstructionSequence > bb) const
Get a begin annotation for a basic block.
Definition: dataflow.h:201
DataflowAnnotator(DataflowType &dataflow)
Constructor.
Definition: dataflow.h:183
An instance of Dataflow performs a dataflow analysis on the basic blocks of a control flow graph and ...
Definition: dataflow.h:233
static const unsigned MAX_BLOCKS
We assume there won't be more than this many basic blocks.
Definition: dataflow.h:240
FactType get_fact_before_instruction(std::shared_ptr< InstructionSequence > bb, Instruction *ins) const
Get dataflow fact at the location immediately before the specified instruction (in program order).
Definition: dataflow.h:428
FactType get_fact_after_instruction(std::shared_ptr< InstructionSequence > bb, Instruction *ins) const
Get dataflow fact at the location immediately after the specified instruction (in program order).
Definition: dataflow.h:420
void execute()
Execute the analysis.
Definition: dataflow.h:351
const FactType & get_fact_at_beginning_of_block(std::shared_ptr< InstructionSequence > bb) const
Get dataflow fact at beginning of specific block.
Definition: dataflow.h:415
static std::string fact_to_string(const FactType &fact)
Convert dataflow fact to a string.
Definition: dataflow.h:436
Dataflow(const std::shared_ptr< ControlFlowGraph > &cfg)
Constructor.
Definition: dataflow.h:338
const FactType & get_fact_at_end_of_block(std::shared_ptr< InstructionSequence > bb) const
Get dataflow fact at end of specified block.
Definition: dataflow.h:410
Analysis::FactType FactType
Data type representing a dataflow fact.
Definition: dataflow.h:237
Control-flow graph edge data type.
Definition: cfg.h:56
std::shared_ptr< InstructionSequence > get_source() const
Get the source basic block.
Definition: cfg.h:75
std::shared_ptr< InstructionSequence > get_target() const
Get the target basic block.
Definition: cfg.h:79
Base class for forward analyses.
Definition: dataflow.h:106
ForwardNavigation LOGICAL_FORWARD
Logical forward navigation through the ControlFlowGraph in analysis order.
Definition: dataflow.h:131
InstructionIterator end(std::shared_ptr< InstructionSequence > bb) const
Get an end iterator over the instructions in a basic block in "analysis" order.
Definition: dataflow.h:125
InstructionIterator begin(std::shared_ptr< InstructionSequence > bb) const
Get a begin iterator over the instructions in a basic block in "analysis" order.
Definition: dataflow.h:119
InstructionSequence::const_iterator InstructionIterator
Iterator type for iterating over instructions in a basic block in "analysis" order.
Definition: dataflow.h:113
static const DataflowDirection DIRECTION
Analysis direction is forward.
Definition: dataflow.h:109
BackwardNavigation LOGICAL_BACKWARD
Logical backward navigation through the ControlFlowGraph in analysis order.
Definition: dataflow.h:135
Forward navigation in the control-flow graph (from predecessors towards successors).
Definition: dataflow.h:43
std::shared_ptr< InstructionSequence > get_block(const Edge *edge) const
Get the basic block that is a "logical" successor from an Edge returned from the get_edges member fun...
Definition: dataflow.h:68
std::shared_ptr< InstructionSequence > get_start_block(const std::shared_ptr< ControlFlowGraph > &cfg) const
Get the "start" block in the ControlFlowGraph, which for a forward analysis is the entry block.
Definition: dataflow.h:49
const ControlFlowGraph::EdgeList & get_edges(const std::shared_ptr< ControlFlowGraph > &cfg, std::shared_ptr< InstructionSequence > bb) const
Get the control edges for a given block which lead to the "logical successors" of the block.
Definition: dataflow.h:59
Definition: instruction_seq_iter.h:37
Instruction object type.
Definition: instruction.h:31
DataflowDirection
Dataflow analysis direction.
Definition: dataflow.h:36