Commit e84ed4e2 authored by Michael Beck's avatar Michael Beck
Browse files

Add an Unreachable node.

Unreachable nodes mark unreachable control flow (after noreturn calls). They
"eat" the memory, saving the two keeps used before.

Works mostly yet (scheduler issues warning about not scheduled Unreachable's)

[r27894]
parent 282b4f95
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
* Copyright (C) 1995-2010 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
......@@ -254,6 +254,7 @@
* ir_node *new_IJmp (ir_node *tgt);
* ir_node *new_Cond (ir_node *c);
* ir_node *new_Return (ir_node *store, int arity, ir_node **in);
* ir_node *new_Unreachable (ir_node *store);
* ir_node *new_Const (tarval *con);
* ir_node *new_SymConst (ir_mode *mode, symconst_symbol value, symconst_kind kind);
* ir_node *new_simpleSel (ir_node *store, ir_node *objptr, ir_entity *ent);
......@@ -381,7 +382,7 @@
*
* Mature_immBlock also fixes the number of inputs to the Phi nodes. Mature_immBlock
* should be called as early as possible, as afterwards the generation of Phi
* nodes is more efficient.
* nodes is more efficient.
*
* Inputs:
* There is an input for each control flow predecessor of the block.
......@@ -416,7 +417,7 @@
* -----------------------
*
* In each block there must be exactly one of the control flow
* operations Start, End, Jmp, Cond, Return or Raise. The output of a
* operations Start, End, Jmp, Cond, Return, Raise, or Unreachable. The output of a
* control flow operation points to the block to be executed next.
*
* ir_node *new_Start (void)
......@@ -426,7 +427,7 @@
* node in each procedure which is automatically created by new_ir_graph.
*
* Inputs:
* No inputs except the block it belogns to.
* No inputs except the block it belongs to.
* Output:
* A tuple of 4 (5, 6) distinct values. These are labeled by the following
* projection numbers (pn_Start):
......@@ -486,13 +487,13 @@
* A value of mode I_u. (i)
* Output:
* A tuple of n control flows. If the Cond's input is i, control
* flow will procede along output i. If the input is >= n control
* flow will proceed along output i. If the input is >= n control
* flow proceeds along output n.
*
* ir_node *new_Return (ir_node *store, int arity, ir_node **in)
* -------------------------------------------------------------
*
* The return node has as inputs the results of the procedure. It
* The Return node has as inputs the results of the procedure. It
* passes the control flow to the end_block.
*
* Inputs:
......@@ -501,7 +502,16 @@
* Output
* Control flow to the end block.
*
* ---------
* ir_node *new_Unreachable (ir_node *store)
* -----------------------------------------
*
* The Unreachable node represents an unreachable control flow, typically
* after a noreturn call. It passes the control flow to the end_block.
*
* Inputs:
* The memory state.
* Output
* Control flow to the end block.
*
* ir_node *new_Const (tarval *con)
* -----------------------------------------------
......@@ -1216,6 +1226,16 @@ FIRM_API ir_node *new_rd_Cond(dbg_info *db, ir_node *block, ir_node *c);
FIRM_API ir_node *new_rd_Return(dbg_info *db, ir_node *block,
ir_node *store, int arity, ir_node *in[]);
/** Constructor for an Unreachable node.
*
* Holds the memory. Only node that can end unreachable control flow.
*
* @param *db A pointer for debug information.
* @param *block The IR block the node belongs to.
* @param *store The state of memory.
*/
FIRM_API ir_node *new_rd_Unreachable(dbg_info *db, ir_node *block, ir_node *store);
/** Constructor for a Const_type node.
*
* Adds the node to the start block.
......@@ -2046,11 +2066,20 @@ FIRM_API ir_node *new_r_Cond(ir_node *block, ir_node *c);
* @param *block The IR block the node belongs to.
* @param *store The state of memory.
* @param arity Number of array indices.
* @param *in[] Array with index inputs to the node. The constructor copies this array.
* @param *in[] Array with index inputs to the node. The constructor copies this array.
*/
FIRM_API ir_node *new_r_Return(ir_node *block, ir_node *store,
int arity, ir_node *in[]);
/** Constructor for an Unreachable node.
*
* Holds the memory. Only node that can end unreachable control flow.
*
* @param *block The IR block the node belongs to.
* @param *store The state of memory.
*/
FIRM_API ir_node *new_r_Unreachable(ir_node *block, ir_node *store);
/** Constructor for a Const node.
*
* Adds the node to the start block.
......@@ -2792,6 +2821,17 @@ FIRM_API ir_node *new_d_Cond(dbg_info *db, ir_node *c);
FIRM_API ir_node *new_d_Return(dbg_info *db, ir_node *store,
int arity, ir_node *in[]);
/** Constructor for an Unreachable node.
*
* Adds the node to the block in current_ir_block.
*
* Holds the memory. Only node that can end unreachable control flow.
*
* @param *db A pointer for debug information.
* @param *store The state of memory.
*/
FIRM_API ir_node *new_d_Unreachable(dbg_info *db, ir_node *store);
/** Constructor for a Const_type node.
*
* Adds the node to the start block.
......@@ -3556,6 +3596,15 @@ FIRM_API ir_node *new_Cond(ir_node *c);
*/
FIRM_API ir_node *new_Return(ir_node *store, int arity, ir_node *in[]);
/** Constructor for an Unreachable node.
*
* Holds the memory. Only node that can end unreachable control flow.
* Adds the node to the block in current_ir_block.
*
* @param *store The state of memory.
*/
FIRM_API ir_node *new_Unreachable(ir_node *store);
/** Constructor for a Const node.
*
* Constructor for a Const node. The constant represents a target
......
......@@ -310,6 +310,8 @@ FIRM_API int is_Sync(const ir_node *node);
FIRM_API int is_Tuple(const ir_node *node);
/** Return true of the node is a Unknown node. */
FIRM_API int is_Unknown(const ir_node *node);
/** Return true of the node is a Unreachable node. */
FIRM_API int is_Unreachable(const ir_node *node);
FIRM_API ir_asm_constraint* get_ASM_input_constraints(const ir_node *node);
......@@ -586,6 +588,9 @@ void set_Sub_right(ir_node *node, ir_node *right);
FIRM_API ir_node *get_Unreachable_mem(const ir_node *node);
void set_Unreachable_mem(ir_node *node, ir_node *mem);
/** @} */
#endif
......@@ -62,8 +62,9 @@ typedef enum ir_opcode {
iro_Sync,
iro_Tuple,
iro_Unknown,
iro_Unreachable,
iro_First = iro_ASM,
iro_Last = iro_Unknown,
iro_Last = iro_Unreachable,
beo_First,
/* backend specific nodes */
......@@ -145,6 +146,7 @@ FIRM_API ir_op *op_SymConst;
FIRM_API ir_op *op_Sync;
FIRM_API ir_op *op_Tuple;
FIRM_API ir_op *op_Unknown;
FIRM_API ir_op *op_Unreachable;
FIRM_API ir_op *get_op_ASM(void);
......@@ -204,5 +206,6 @@ FIRM_API ir_op *get_op_SymConst(void);
FIRM_API ir_op *get_op_Sync(void);
FIRM_API ir_op *get_op_Tuple(void);
FIRM_API ir_op *get_op_Unknown(void);
FIRM_API ir_op *get_op_Unreachable(void);
#endif
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
* Copyright (C) 1995-2010 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
......@@ -121,6 +121,7 @@ void be_start_transform_setup(void)
be_set_transform_function(op_Pin, be_duplicate_node);
be_set_transform_function(op_Start, be_duplicate_node);
be_set_transform_function(op_Sync, be_duplicate_node);
be_set_transform_function(op_Unreachable, be_duplicate_node);
}
ir_node *be_duplicate_node(ir_node *node)
......
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
* Copyright (C) 1995-2010 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
......@@ -304,6 +304,7 @@ static int should_be_scheduled(ir_node *node)
case iro_Start:
case iro_Jmp:
case beo_Return:
case iro_Unreachable:
return 1;
default:
break;
......
......@@ -760,6 +760,7 @@ static void dump_node_mode(FILE *F, ir_node *n)
case iro_Sel:
case iro_End:
case iro_Return:
case iro_Unreachable:
case iro_Free:
case iro_Sync:
case iro_Jmp:
......
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
* Copyright (C) 1995-2010 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
......@@ -893,9 +893,10 @@ static int verify_node_Block(ir_node *n, ir_graph *irg)
break; /* We can not test properly. How many tuples are there? */
ASSERT_AND_RET(
(
is_Return(pred) ||
is_Bad(pred) ||
is_Raise(pred) ||
is_Return(pred) ||
is_Unreachable(pred) ||
is_Bad(pred) ||
is_Raise(pred) ||
is_fragile_op(pred)
),
"End Block node", 0);
......
......@@ -2185,6 +2185,8 @@ static void do_dfs(ir_graph *irg, loop_env *env)
pred = skip_Proj(pred);
if (is_Return(pred))
dfs(get_Return_mem(pred), env);
else if (is_Unreachable(pred))
dfs(get_Unreachable_mem(pred), env);
else if (is_Raise(pred))
dfs(get_Raise_mem(pred), env);
else if (is_fragile_op(pred))
......
......@@ -633,6 +633,12 @@ class Return(Op):
flags = [ "cfopcode" ]
pinned = "yes"
class Unreachable(Op):
ins = [ "mem" ]
mode = "mode_X"
flags = [ "cfopcode" ]
pinned = "yes"
class Rotl(Binop):
flags = []
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment