2012-10-30 08:41:40 +00:00
|
|
|
/*
|
|
|
|
flow.h
|
|
|
|
|
|
|
|
Flow graph analysis.
|
|
|
|
|
|
|
|
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
|
|
|
|
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
|
|
Date: 2012/10/30
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
#ifndef flow_h
|
|
|
|
#define flow_h
|
|
|
|
|
|
|
|
/** \defgroup qfcc_flow Flow graph analysis
|
|
|
|
\ingroup qfcc
|
|
|
|
*/
|
|
|
|
//@{
|
|
|
|
|
|
|
|
struct function_s;
|
2012-10-30 10:25:35 +00:00
|
|
|
struct sblock_s;
|
|
|
|
struct statement_s;
|
2012-11-05 10:00:57 +00:00
|
|
|
struct operand_s;
|
|
|
|
|
|
|
|
typedef struct flowvar_s {
|
|
|
|
struct flowvar_s *next; ///< for ALLOC
|
|
|
|
struct set_s *use; ///< set of statements that use this var
|
|
|
|
struct set_s *define; ///< set of statements that define this var
|
2012-11-06 09:26:08 +00:00
|
|
|
struct operand_s *op; ///< an operand using this var
|
2012-11-05 10:00:57 +00:00
|
|
|
int number; ///< number of variable in func's ref list
|
|
|
|
} flowvar_t;
|
2012-10-30 08:41:40 +00:00
|
|
|
|
2012-10-30 13:05:46 +00:00
|
|
|
typedef struct flowloop_s {
|
|
|
|
struct flowloop_s *next;
|
2012-11-01 03:11:17 +00:00
|
|
|
unsigned head;
|
2012-10-30 13:05:46 +00:00
|
|
|
struct set_s *nodes;
|
|
|
|
} flowloop_t;
|
|
|
|
|
2012-11-01 03:11:17 +00:00
|
|
|
typedef struct flowedge_s {
|
2012-11-02 08:30:29 +00:00
|
|
|
unsigned tail;
|
|
|
|
unsigned head;
|
2012-11-01 03:11:17 +00:00
|
|
|
} flowedge_t;
|
|
|
|
|
2012-11-01 04:23:16 +00:00
|
|
|
/** Represent a node in a flow graph.
|
|
|
|
*/
|
2012-11-01 03:11:17 +00:00
|
|
|
typedef struct flownode_s {
|
2012-11-06 06:28:37 +00:00
|
|
|
struct flownode_s *next; ///< for ALLOC
|
|
|
|
unsigned id; ///< index of this node in the flow graph
|
|
|
|
unsigned dfn; ///< depth-first ordering of this node
|
|
|
|
struct set_s *predecessors; ///< predecessors of this node
|
|
|
|
struct set_s *successors; ///< successors of this node
|
|
|
|
struct set_s *edges; ///< edges leaving this node to successor nodes
|
|
|
|
struct set_s *dom; ///< dominating nodes
|
2012-11-06 06:30:07 +00:00
|
|
|
struct {
|
|
|
|
struct set_s *use;
|
|
|
|
struct set_s *def;
|
|
|
|
struct set_s *in;
|
|
|
|
struct set_s *out;
|
|
|
|
} live_vars;
|
|
|
|
struct sblock_s *sblock; ///< original statement block
|
2012-11-07 02:28:33 +00:00
|
|
|
struct dagnode_s *dag; ///< dag for this node
|
2012-11-01 03:11:17 +00:00
|
|
|
} flownode_t;
|
|
|
|
|
2012-11-02 08:30:29 +00:00
|
|
|
typedef struct flowgraph_s {
|
2012-11-06 06:28:37 +00:00
|
|
|
struct flowgraph_s *next; ///< for ALLOC
|
2012-11-06 09:26:08 +00:00
|
|
|
struct function_s *func; ///< function to which this graph is attached
|
2012-11-06 06:28:37 +00:00
|
|
|
flownode_t **nodes; ///< array of nodes in the graph
|
2012-11-02 08:30:29 +00:00
|
|
|
int num_nodes;
|
2012-11-06 06:28:37 +00:00
|
|
|
flowedge_t *edges; ///< array of all edges in the graph
|
2012-11-02 08:30:29 +00:00
|
|
|
int num_edges;
|
2012-11-06 06:28:37 +00:00
|
|
|
struct set_s *dfst; ///< edges in the depth-first search tree
|
|
|
|
unsigned *dfo; ///< depth-first order of nodes
|
|
|
|
flowloop_t *loops; ///< linked list of natural loops
|
2012-11-02 08:30:29 +00:00
|
|
|
} flowgraph_t;
|
|
|
|
|
2012-11-05 10:00:57 +00:00
|
|
|
flowvar_t *flow_get_var (struct operand_s *op);
|
2012-10-30 10:25:35 +00:00
|
|
|
int flow_is_cond (struct statement_s *s);
|
|
|
|
int flow_is_goto (struct statement_s *s);
|
2012-11-03 09:59:15 +00:00
|
|
|
int flow_is_jumpb (struct statement_s *s);
|
2012-10-30 10:25:35 +00:00
|
|
|
int flow_is_return (struct statement_s *s);
|
|
|
|
struct sblock_s *flow_get_target (struct statement_s *s);
|
2012-11-03 09:59:15 +00:00
|
|
|
struct sblock_s **flow_get_targetlist (struct statement_s *s);
|
2012-11-16 10:33:37 +00:00
|
|
|
void flow_analyze_statement (struct statement_s *s, struct set_s *use,
|
|
|
|
struct set_s *def, struct set_s *kill,
|
|
|
|
struct operand_s *operands[4]);
|
2012-10-30 08:41:40 +00:00
|
|
|
void flow_build_vars (struct function_s *func);
|
2012-11-02 08:30:29 +00:00
|
|
|
flowgraph_t *flow_build_graph (struct sblock_s *func);
|
|
|
|
void flow_del_graph (flowgraph_t *graph);
|
2012-11-06 09:26:08 +00:00
|
|
|
void flow_data_flow (flowgraph_t *graph);
|
2012-11-07 05:11:26 +00:00
|
|
|
struct sblock_s *flow_generate (flowgraph_t *graph);
|
2012-11-02 08:30:29 +00:00
|
|
|
|
|
|
|
void print_flowgraph (flowgraph_t *graph, const char *filename);
|
2012-10-30 08:41:40 +00:00
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
#endif//flow_h
|