/**
* Constructs a Block with a fixed number of predecessors.
- * Does not set current_block. Can not be used with automatic
+ * Does not set current_block. Cannot be used with automatic
* Phi node construction.
*/
static ir_node *
-new_bd_Block(dbg_info *db, int arity, ir_node **in) {
+new_bd_Block(dbg_info *db, int arity, ir_node **in) {
ir_node *res;
ir_graph *irg = current_ir_graph;
- res = new_ir_node (db, irg, NULL, op_Block, mode_BB, arity, in);
- set_Block_matured(res, 1);
- set_Block_block_visited(res, 0);
+ res = new_ir_node(db, irg, NULL, op_Block, mode_BB, arity, in);
- res->attr.block.dead = 0;
+ /* macroblock header */
+ res->in[0] = res;
+
+ res->attr.block.is_dead = 0;
+ res->attr.block.is_mb_head = 1;
res->attr.block.irg = irg;
res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
res->attr.block.in_cg = NULL;
res->attr.block.cg_backedge = NULL;
res->attr.block.extblk = NULL;
+ res->attr.block.mb_depth = 0;
- IRN_VRFY_IRG(res, irg);
+ set_Block_matured(res, 1);
+ set_Block_block_visited(res, 0);
+
+ IRN_VRFY_IRG(res, irg);
return res;
- } /* new_bd_Block */
+} /* new_bd_Block */
static ir_node *
new_bd_Start(dbg_info *db, ir_node *block) {
break;
}
- if (!has_unknown) res = optimize_node (res);
+ if (!has_unknown) res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
/* Memory Phis in endless loops must be kept alive.
return res;
} /* new_bd_Pin */
+static ir_node *
+new_bd_ASM(dbg_info *db, ir_node *block, ir_node *store, int arity, ir_node *inputs[], ident *asm_text) {
+ ir_node *res, **in;
+ ir_graph *irg = current_ir_graph;
+ int i;
+
+ NEW_ARR_A(ir_node *, in, arity + 1);
+
+ in[0] = store;
+ for (i = 0; i < arity; ++i)
+ in[i + 1] = inputs[i];
+
+ res = new_ir_node(db, irg, block, op_ASM, mode_T, arity + 1, in);
+ res->attr.assem.asm_text = asm_text;
+
+ res = optimize_node(res);
+ IRN_VRFY_IRG(res, irg);
+ return res;
+} /* new_bd_ASM */
+
/* --------------------------------------------- */
/* private interfaces, for professional use only */
/* --------------------------------------------- */
Does not set current_block. Can not be used with automatic
Phi node construction. */
ir_node *
-new_rd_Block(dbg_info *db, ir_graph *irg, int arity, ir_node **in) {
+new_rd_Block(dbg_info *db, ir_graph *irg, int arity, ir_node **in) {
ir_graph *rem = current_ir_graph;
ir_node *res;
return res;
} /* new_rd_Pin */
+ir_node *new_rd_ASM(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+ int arity, ir_node *inputs[], ident *asm_text) {
+ ir_node *res;
+ ir_graph *rem = current_ir_graph;
+
+ current_ir_graph = irg;
+ res = new_bd_ASM(db, block, store, arity, inputs, asm_text);
+ current_ir_graph = rem;
+
+ return res;
+} /* new_rd_ASM */
+
+
ir_node *new_r_Block(ir_graph *irg, int arity, ir_node **in) {
return new_rd_Block(NULL, irg, arity, in);
}
ir_node *new_r_Pin(ir_graph *irg, ir_node *block, ir_node *node) {
return new_rd_Pin(NULL, irg, block, node);
}
+ir_node *new_r_ASM(ir_graph *irg, ir_node *block, ir_node *store,
+ int arity, ir_node *inputs[], ident *asm_text) {
+ return new_rd_ASM(NULL, irg, block, store, arity, inputs, asm_text);
+}
/** ********************/
/** public interfaces */
/* case 2 -- If the value is actually computed, return it. */
if (res) return res;
- if (block->attr.block.matured) { /* case 3 */
+ if (block->attr.block.is_matured) { /* case 3 */
/* The Phi has the same amount of ins as the corresponding block. */
int ins = get_irn_arity(block);
/* Error Message */
printf("Error: no value set. Use of undefined variable. Initializing to zero.\n");
assert(mode->code >= irm_F && mode->code <= irm_P);
- res = new_rd_Const(NULL, current_ir_graph, block, mode,
- tarval_mode_null[mode->code]);
+ res = new_rd_Const(NULL, current_ir_graph, block, mode, tarval_mode_null[mode->code]);
}
/* The local valid value is available now. */
if (block->attr.block.graph_arr[pos]) {
/* There was a set_value() after the cfOp and no get_value before that
set_value(). We must build a Phi node now. */
- if (block->attr.block.matured) {
+ if (block->attr.block.is_matured) {
int ins = get_irn_arity(block);
ir_node **nin;
- NEW_ARR_A (ir_node *, nin, ins);
+ NEW_ARR_A(ir_node *, nin, ins);
res = phi_merge(block, pos, mode, nin, ins);
} else {
- res = new_rd_Phi0 (current_ir_graph, block, mode);
- res->attr.phi0_pos = pos;
+ res = new_rd_Phi0(current_ir_graph, block, mode);
+ res->attr.phi0.pos = pos;
res->link = block->link;
block->link = res;
}
/* case 2 -- If the value is actually computed, return it. */
if (res) { return res; };
- if (block->attr.block.matured) { /* case 3 */
+ if (block->attr.block.is_matured) { /* case 3 */
/* The Phi has the same amount of ins as the corresponding block. */
int ins = get_irn_arity(block);
The Phi0 has to remember the pos of it's internal value. If the real
Phi is computed, pos is used to update the array with the local
values. */
- res = new_rd_Phi0 (current_ir_graph, block, mode);
- res->attr.phi0_pos = pos;
+ res = new_rd_Phi0(current_ir_graph, block, mode);
+ res->attr.phi0.pos = pos;
res->link = block->link;
block->link = res;
}
assert (!get_Block_matured(block) && "Block already matured"); */
if (!get_Block_matured(block)) {
- ins = ARR_LEN (block->in)-1;
+ ins = ARR_LEN(block->in)-1;
/* Fix block parameters */
block->attr.block.backedge = new_backedge_arr(current_ir_graph->obst, ins);
/* An array for building the Phi nodes. */
- NEW_ARR_A (ir_node *, nin, ins);
+ NEW_ARR_A(ir_node *, nin, ins);
/* Traverse a chain of Phi nodes attached to this block and mature
these, too. **/
for (n = block->link; n; n = next) {
inc_irg_visited(current_ir_graph);
next = n->link;
- exchange(n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
+ exchange(n, phi_merge(block, n->attr.phi0.pos, n->mode, nin, ins));
}
- block->attr.block.matured = 1;
+ block->attr.block.is_matured = 1;
/* Now, as the block is a finished firm node, we can optimize it.
Since other nodes have been allocated since the block was created
return new_bd_Pin(db, current_ir_graph->current_block, node);
} /* new_d_Pin */
+ir_node *
+new_d_ASM(dbg_info *db, ir_node *store, int arity, ir_node *inputs[], ident *asm_text) {
+ return new_bd_ASM(db, current_ir_graph->current_block, store, arity, inputs, asm_text);
+} /* new_d_ASM */
+
/* ********************************************************************* */
/* Comfortable interface with automatic Phi node construction. */
/* (Uses also constructors of ?? interface, except new_Block. */
/* Block construction */
/* immature Block without predecessors */
-ir_node *new_d_immBlock(dbg_info *db) {
+ir_node *
+new_d_immBlock(dbg_info *db) {
ir_node *res;
assert(get_irg_phase_state(current_ir_graph) == phase_building);
/* creates a new dynamic in-array as length of in is -1 */
- res = new_ir_node (db, current_ir_graph, NULL, op_Block, mode_BB, -1, NULL);
+ res = new_ir_node(db, current_ir_graph, NULL, op_Block, mode_BB, -1, NULL);
current_ir_graph->current_block = res;
- res->attr.block.matured = 0;
- res->attr.block.dead = 0;
+
+ /* macroblock head */
+ res->in[0] = res;
+
+ res->attr.block.is_matured = 0;
+ res->attr.block.is_dead = 0;
+ res->attr.block.is_mb_head = 1;
res->attr.block.irg = current_ir_graph;
res->attr.block.backedge = NULL;
res->attr.block.in_cg = NULL;
res->attr.block.cg_backedge = NULL;
res->attr.block.extblk = NULL;
res->attr.block.region = NULL;
+ res->attr.block.mb_depth = 0;
+
set_Block_block_visited(res, 0);
/* Create and initialize array for Phi-node construction. */
return new_d_immBlock(NULL);
} /* new_immBlock */
+/* immature PartBlock with its predecessors */
+ir_node *
+new_d_immPartBlock(dbg_info *db, ir_node *pred_jmp) {
+ ir_node *res = new_d_immBlock(db);
+ ir_node *blk = get_nodes_block(pred_jmp);
+
+ res->in[0] = blk->in[0];
+ res->attr.block.is_mb_head = 0;
+ res->attr.block.mb_depth = blk->attr.block.mb_depth + 1;
+
+ add_immBlock_pred(res, pred_jmp);
+
+ return res;
+} /* new_d_immPartBlock */
+
+ir_node *
+new_immPartBlock(ir_node *pred_jmp) {
+ return new_d_immPartBlock(NULL, pred_jmp);
+} /* new_immPartBlock */
+
/* add an edge to a jmp/control flow node */
void
add_immBlock_pred(ir_node *block, ir_node *jmp) {
- if (block->attr.block.matured) {
- assert(0 && "Error: Block already matured!\n");
- } else {
- int n = ARR_LEN(block->in) - 1;
- assert(jmp != NULL);
- ARR_APP1(ir_node *, block->in, jmp);
- /* Call the hook */
- hook_set_irn_n(block, n, jmp, NULL);
- }
+ int n = ARR_LEN(block->in) - 1;
+
+ assert(!block->attr.block.is_matured && "Error: Block already matured!\n");
+ assert(block->attr.block.is_mb_head && "Error: Cannot add a predecessor to a PartBlock");
+ assert(jmp != NULL);
+
+ ARR_APP1(ir_node *, block->in, jmp);
+ /* Call the hook */
+ hook_set_irn_n(block, n, jmp, NULL);
} /* add_immBlock_pred */
/* changing the current block */
ir_node *new_Pin(ir_node *node) {
return new_d_Pin(NULL, node);
}
+ir_node *new_ASM(ir_node *store, int arity, ir_node *inputs[], ident *asm_text) {
+ return new_d_ASM(NULL, store, arity, inputs, asm_text);
+}