#include "firm_types.h"
+/**
+ * This enum describes the different regions constructed by the structural analysis.
+ */
typedef enum ir_region_kind {
- ir_rk_Unknown, /**< Unknown region kind. */
- ir_rk_Block, /**< A Block simply wraps a basic block, needed for the construction. */
- ir_rk_Sequence, /**< A sequence of regions. */
- ir_rk_IfThen, /**< An if-then. */
- ir_rk_IfThenElse, /**< An if-then-else. */
- ir_rk_Case, /**< A Case like in Pascal. No fall through is allowed. */
- ir_rk_Switch, /**< A Switch like in C. Fall through is allowed. */
- ir_rk_Proper, /**< A proper region. */
- ir_rk_SelfLoop, /**< A self loop. */
- ir_rk_RepeatLoop, /**< A Repeat loop. */
- ir_rk_WhileLoop, /**< A While loop. */
- ir_rk_NaturalLoop, /**< A natural loop. */
- ir_rk_Improper, /**< An improper region. */
+ ir_rk_Unknown, /**< Unknown region kind. */
+ ir_rk_BasicBlock, /**< A Basic Block simply wraps a firm basic block, needed for the construction. */
+ /*
+ * part0->part1->...->partn->XXX
+ */
+ ir_rk_Sequence, /**< A sequence of regions. */
+ /*
+ * part0
+ * / |
+ * part1 |
+ * \ |
+ * XXX
+ */
+ ir_rk_IfThen, /**< An if-then. */
+ /*
+ * part0
+ * / \
+ * part1 part2
+ * \ /
+ * XXX
+ */
+ ir_rk_IfThenElse, /**< An if-then-else. */
+ /*
+ * part0
+ * / \
+ * part1 ... partn
+ * \ /
+ * XXX
+ */
+ ir_rk_Case, /**< A Case like in Pascal. No fall through is allowed. */
+ /*
+ * part0
+ * / | \
+ * part1->part2 partn
+ * \ /
+ * XXX
+ */
+ ir_rk_Switch, /**< A Switch like in C. At least one fall through exists. */
+ ir_rk_Proper, /**< A proper region. Any other DAG. */
+ ir_rk_TryCatch, /**< A TryCatch Exception handling. */
+ ir_rk_TryCatchFinally, /**< A TryCatchFinally Exception handling. */
+ /*
+ * +-+
+ * v |
+ * part0
+ */
+ ir_rk_SelfLoop, /**< A self loop. In Firm always a repeat or endless loop. */
+ /*
+ * part0
+ * | ^
+ * v |
+ * part1
+ * |
+ * v
+ * XXX
+ */
+ ir_rk_RepeatLoop, /**< A Repeat loop. */
+ /*
+ * part0 ---> XXX
+ * | ^
+ * v |
+ * part1
+ */
+ ir_rk_WhileLoop, /**< A While loop. */
+ /*
+ * Arbitrary loop with single head.
+ */
+ ir_rk_NaturalLoop, /**< A natural loop. */
+ ir_rk_Improper, /**< An improper region. May contain everything. */
} ir_region_kind;
+/** Returns non-zero if a region contains loops. */
+#define is_loop_region(type) ((type) >= ir_rk_SelfLoop)
+
+/**
+ * Returns the link of a region.
+ *
+ * @param reg the region
+ */
+void *get_region_link(const ir_region *reg);
+
+/**
+ * Sets the link of a region.
+ *
+ * @param reg the region
+ * @param data the data
+ */
+void set_region_link(ir_region *reg, void *data);
+
+/**
+ * Get the immediate region of a block.
+ *
+ * @param block a block node
+ */
+ir_region *get_block_region(const ir_node *block);
+
+/**
+ * Sets the immediate region of a block.
+ *
+ * @param block a block node
+ * @param reg the region
+ */
+void set_block_region(ir_node *block, ir_region *reg);
+
+/**
+ * Get the immediate region of a node.
+ *
+ * @param n a Firm IR node
+ */
+ir_region *get_irn_region(ir_node *n);
+
+/**
+ * Return non-if a given firm thing is a region.
+ *
+ * @param thing a Firm object address
+ */
+int is_region(const void *thing);
+
+/**
+ * Return the number of predecessors in a region.
+ *
+ * @param reg the region
+ */
+int get_region_n_preds(const ir_region *reg);
+
+/**
+ * Return the predecessor region at position pos.
+ *
+ * @param reg the region
+ */
+ir_region *get_region_pred(const ir_region *reg, int pos);
+
+/**
+ * Set the predecessor region at position pos.
+ *
+ * @param reg the region
+ * @param pos the position number
+ * @param n the new predecessor region
+ */
+void set_region_pred(ir_region *reg, int pos, ir_region *n);
+
+/**
+ * Return the number of successors in a region.
+ *
+ * @param reg the region
+ */
+int get_region_n_succs(const ir_region *reg);
+
+/**
+ * Return the successor region at position pos.
+ *
+ * @param reg the region
+ * @param pos the position number
+ */
+ir_region *get_region_succ(const ir_region *reg, int pos);
+
+/**
+ * Set the successor region at position pos.
+ *
+ * @param reg the region
+ * @param pos the position number
+ * @param n the new successor region
+ */
+void set_region_succ(ir_region *reg, int pos, ir_region *n);
+
+/**
+ * Construct the region tree of a graph by doing
+ * structural analysis.
+ *
+ * Uses link fields of nodes.
+ *
+ * @param irg the graph
+ *
+ * @return the region tree
+ */
+ir_reg_tree *construct_region_tree(ir_graph *irg);
+
+/**
+ * Walk over the region tree.
+ *
+ * @param tree the tree
+ * @param pre walker function, executed before the children of a tree node are visited
+ * @param post walker function, executed after the children of a tree node are visited
+ * @param env environment, passed to pre and post
+ */
+void region_tree_walk(ir_reg_tree *tree, irg_reg_walk_func *pre, irg_reg_walk_func *post, void *env);
+
#endif /* _FIRM_STRUCTURE_H */