/* Memory Phis in endless loops must be kept alive.
As we can't distinguish these easily we keep all of them alive. */
- if ((res->op == op_Phi) && (mode == mode_M))
+ if (is_Phi(res) && mode == mode_M)
add_End_keepalive(get_irg_end(irg), res);
return res;
} /* new_bd_Phi */
NEW_BD_BINOP(Shl)
NEW_BD_BINOP(Shr)
NEW_BD_BINOP(Shrs)
-NEW_BD_BINOP(Rot)
+NEW_BD_BINOP(Rotl)
NEW_BD_UNOP(Abs)
NEW_BD_BINOP(Carry)
NEW_BD_BINOP(Borrow)
ir_graph *irg = current_ir_graph;
ir_node *res = new_ir_node(db, irg, block, op_SymConst, mode, 0, NULL);
- res->attr.symc.num = symkind;
- res->attr.symc.sym = value;
- res->attr.symc.tp = tp;
+ res->attr.symc.kind = symkind;
+ res->attr.symc.sym = value;
+ res->attr.symc.tp = tp;
res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
return res;
} /* new_bd_Mux */
-static ir_node *
-new_bd_Psi(dbg_info *db, ir_node *block,
- int arity, ir_node *cond[], ir_node *vals[], ir_mode *mode) {
- ir_node **in;
- ir_node *res;
- ir_graph *irg = current_ir_graph;
- int i;
-
- NEW_ARR_A(ir_node *, in, 2 * arity + 1);
-
- for (i = 0; i < arity; ++i) {
- in[2 * i] = cond[i];
- in[2 * i + 1] = vals[i];
- }
- in[2 * i] = vals[i];
-
- res = new_ir_node(db, irg, block, op_Psi, mode, 2 * arity + 1, in);
- assert(res);
-
- res = optimize_node(res);
- IRN_VRFY_IRG(res, irg);
- return res;
-} /* new_bd_Psi */
-
static ir_node *
new_bd_CopyB(dbg_info *db, ir_node *block,
ir_node *store, ir_node *dst, ir_node *src, ir_type *data_type) {
res->attr.assem.pin_state = op_pin_state_pinned;
res->attr.assem.inputs = NEW_ARR_D(ir_asm_constraint, irg->obst, arity);
res->attr.assem.outputs = NEW_ARR_D(ir_asm_constraint, irg->obst, n_outs);
- res->attr.assem.clobber = NEW_ARR_D(ident *, irg->obst, n_clobber);
+ res->attr.assem.clobber = NEW_ARR_D(ident *, irg->obst, n_clobber);
res->attr.assem.asm_text = asm_text;
- memcpy(res->attr.assem.inputs, inputs, sizeof(inputs[0]) * arity);
- memcpy(res->attr.assem.outputs, outputs, sizeof(outputs[0]) * n_outs);
- memcpy(res->attr.assem.clobber, clobber, sizeof(clobber[0]) * n_clobber);
+ memcpy(res->attr.assem.inputs, inputs, sizeof(inputs[0]) * arity);
+ memcpy(res->attr.assem.outputs, outputs, sizeof(outputs[0]) * n_outs);
+ memcpy(res->attr.assem.clobber, clobber, sizeof(clobber[0]) * n_clobber);
res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
NEW_RD_BINOP(Shl)
NEW_RD_BINOP(Shr)
NEW_RD_BINOP(Shrs)
-NEW_RD_BINOP(Rot)
+NEW_RD_BINOP(Rotl)
NEW_RD_UNOP(Abs)
NEW_RD_BINOP(Carry)
NEW_RD_BINOP(Borrow)
return res;
} /* new_rd_Mux */
-ir_node *
-new_rd_Psi(dbg_info *db, ir_graph *irg, ir_node *block,
- int arity, ir_node *cond[], ir_node *vals[], ir_mode *mode) {
- ir_node *res;
- ir_graph *rem = current_ir_graph;
-
- current_ir_graph = irg;
- res = new_bd_Psi(db, block, arity, cond, vals, mode);
- current_ir_graph = rem;
-
- return res;
-} /* new_rd_Psi */
-
ir_node *new_rd_CopyB(dbg_info *db, ir_graph *irg, ir_node *block,
ir_node *store, ir_node *dst, ir_node *src, ir_type *data_type) {
ir_node *res;
ir_node *op, ir_node *k, ir_mode *mode) {
return new_rd_Shrs(NULL, irg, block, op, k, mode);
}
-ir_node *new_r_Rot(ir_graph *irg, ir_node *block,
+ir_node *new_r_Rotl(ir_graph *irg, ir_node *block,
ir_node *op, ir_node *k, ir_mode *mode) {
- return new_rd_Rot(NULL, irg, block, op, k, mode);
+ return new_rd_Rotl(NULL, irg, block, op, k, mode);
}
ir_node *new_r_Carry(ir_graph *irg, ir_node *block,
ir_node *op, ir_node *k, ir_mode *mode) {
ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode) {
return new_rd_Mux(NULL, irg, block, sel, ir_false, ir_true, mode);
}
-ir_node *new_r_Psi(ir_graph *irg, ir_node *block,
- int arity, ir_node *conds[], ir_node *vals[], ir_mode *mode) {
- return new_rd_Psi(NULL, irg, block, arity, conds, vals, mode);
-}
ir_node *new_r_CopyB(ir_graph *irg, ir_node *block,
ir_node *store, ir_node *dst, ir_node *src, ir_type *data_type) {
return new_rd_CopyB(NULL, irg, block, store, dst, src, data_type);
} /* new_rd_Phi0 */
+/**
+ * Internal constructor of a Phi node by a phi_merge operation.
+ *
+ * @param irg the graph on which the Phi will be constructed
+ * @param block the block in which the Phi will be constructed
+ * @param mode the mod eof the Phi node
+ * @param in the input array of the phi node
+ * @param ins number of elements in the input array
+ * @param phi0 in non-NULL: the Phi0 node in the same block that represents
+ * the value for which the new Phi is constructed
+ */
static INLINE ir_node *
new_rd_Phi_in(ir_graph *irg, ir_node *block, ir_mode *mode,
ir_node **in, int ins, ir_node *phi0) {
/* Allocate a new node on the obstack. The allocation copies the in
array. */
- res = new_ir_node (NULL, irg, block, op_Phi, mode, ins, in);
+ res = new_ir_node(NULL, irg, block, op_Phi, mode, ins, in);
res->attr.phi.u.backedge = new_backedge_arr(irg->obst, ins);
/* This loop checks whether the Phi has more than one predecessor.
Phi node merges the same definition on several paths and therefore
is not needed. Don't consider Bad nodes! */
known = res;
- for (i=0; i < ins; ++i)
- {
+ for (i = ins - 1; i >= 0; --i) {
assert(in[i]);
in[i] = skip_Id(in[i]); /* increases the number of freed Phis. */
/* Optimize self referencing Phis: We can't detect them yet properly, as
they still refer to the Phi0 they will replace. So replace right now. */
- if (phi0 && in[i] == phi0) in[i] = res;
+ if (phi0 && in[i] == phi0)
+ in[i] = res;
- if (in[i]==res || in[i]==known || is_Bad(in[i])) continue;
+ if (in[i] == res || in[i] == known || is_Bad(in[i]))
+ continue;
- if (known==res)
+ if (known == res)
known = in[i];
else
break;
}
- /* i==ins: there is at most one predecessor, we don't need a phi node. */
- if (i == ins) {
+ /* i < 0: there is at most one predecessor, we don't need a phi node. */
+ if (i < 0) {
if (res != known) {
edges_node_deleted(res, current_ir_graph);
- obstack_free (current_ir_graph->obst, res);
+ obstack_free(current_ir_graph->obst, res);
if (is_Phi(known)) {
/* If pred is a phi node we want to optimize it: If loops are matured in a bad
order, an enclosing Phi know may get superfluous. */
res = optimize_in_place_2(known);
if (res != known)
exchange(known, res);
-
}
else
res = known;
res = new_Bad();
}
} else {
- res = optimize_node (res); /* This is necessary to add the node to the hash table for cse. */
+ res = optimize_node(res); /* This is necessary to add the node to the hash table for cse. */
IRN_VRFY_IRG(res, irg);
/* Memory Phis in endless loops must be kept alive.
As we can't distinguish these easily we keep all of them alive. */
- if ((res->op == op_Phi) && (mode == mode_M))
+ if (is_Phi(res) && mode == mode_M)
add_End_keepalive(get_irg_end(irg), res);
}
static void
set_frag_value(ir_node **frag_arr, int pos, ir_node *val) {
-#if 0
- if (!frag_arr[pos]) frag_arr[pos] = val;
- if (frag_arr[current_ir_graph->n_loc - 1]) {
- ir_node **arr = get_frag_arr(frag_arr[current_ir_graph->n_loc - 1]);
- assert(arr != frag_arr && "Endless recursion detected");
- set_frag_value(arr, pos, val);
- }
-#else
+#ifdef DEBUG_libfirm
int i;
- for (i = 0; i < 1000; ++i) {
- if (!frag_arr[pos]) {
+ for (i = 1024; i >= 0; --i)
+#else
+ for (;;)
+#endif
+ {
+ if (frag_arr[pos] == NULL)
frag_arr[pos] = val;
- }
- if (frag_arr[current_ir_graph->n_loc - 1]) {
+ if (frag_arr[current_ir_graph->n_loc - 1] != NULL) {
ir_node **arr = get_frag_arr(frag_arr[current_ir_graph->n_loc - 1]);
+ assert(arr != frag_arr && "Endless recursion detected");
frag_arr = arr;
- }
- else
+ } else
return;
}
- assert(0 && "potential endless recursion");
-#endif
+ assert(!"potential endless recursion in set_frag_value");
} /* set_frag_value */
static ir_node *
ir_node *res;
ir_node **frag_arr;
- assert(is_fragile_op(cfOp) && (get_irn_op(cfOp) != op_Bad));
+ assert(is_fragile_op(cfOp) && !is_Bad(cfOp));
frag_arr = get_frag_arr(cfOp);
res = frag_arr[pos];
- if (!res) {
- if (block->attr.block.graph_arr[pos]) {
- /* There was a set_value() after the cfOp and no get_value before that
+ if (res == NULL) {
+ if (block->attr.block.graph_arr[pos] != NULL) {
+ /* 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.is_matured) {
int ins = get_irn_arity(block);
res->attr.phi.next = block->attr.block.phis;
block->attr.block.phis = res;
}
- assert(res);
- /* @@@ tested by Flo: set_frag_value(frag_arr, pos, res);
- but this should be better: (remove comment if this works) */
+ assert(res != NULL);
/* It's a Phi, we can write this into all graph_arrs with NULL */
set_frag_value(block->attr.block.graph_arr, pos, res);
} else {
#endif /* PRECISE_EXC_CONTEXT */
/**
- * check whether a control flow cf_pred is a exception flow.
+ * Check whether a control flownode cf_pred represents an exception flow.
*
* @param cf_pred the control flow node
* @param prev_cf_op if cf_pred is a Proj, the predecessor node, else equal to cf_pred
in graph_arr to break recursions.
Else we may not set graph_arr as there a later value is remembered. */
phi0 = NULL;
- if (!block->attr.block.graph_arr[pos]) {
- if (block == get_irg_start_block(current_ir_graph)) {
+ if (block->attr.block.graph_arr[pos] == NULL) {
+ ir_graph *irg = current_ir_graph;
+
+ if (block == get_irg_start_block(irg)) {
/* Collapsing to Bad tarvals is no good idea.
So we call a user-supplied routine here that deals with this case as
appropriate for the given language. Sorrily the only help we can give
However, this SHOULD NOT HAPPEN, as bad control flow nodes are intercepted
before recurring.
*/
- if (default_initialize_local_variable) {
+ if (default_initialize_local_variable != NULL) {
ir_node *rem = get_cur_block();
set_cur_block(block);
- block->attr.block.graph_arr[pos] = default_initialize_local_variable(current_ir_graph, mode, pos - 1);
+ block->attr.block.graph_arr[pos] = default_initialize_local_variable(irg, mode, pos - 1);
set_cur_block(rem);
}
else
- block->attr.block.graph_arr[pos] = new_Const(mode, tarval_bad);
+ block->attr.block.graph_arr[pos] = new_Unknown(mode);
/* We don't need to care about exception ops in the start block.
There are none by definition. */
return block->attr.block.graph_arr[pos];
} else {
- phi0 = new_rd_Phi0(current_ir_graph, block, mode);
+ phi0 = new_rd_Phi0(irg, block, mode);
block->attr.block.graph_arr[pos] = phi0;
#if PRECISE_EXC_CONTEXT
if (get_opt_precise_exc_context()) {
/* We want to pass the Phi0 node to the constructor: this finds additional
optimization possibilities.
The Phi0 node either is allocated in this function, or it comes from
- a former call to get_r_value_internal. In this case we may not yet
- exchange phi0, as this is done in mature_immBlock. */
- if (!phi0) {
+ a former call to get_r_value_internal(). In this case we may not yet
+ exchange phi0, as this is done in mature_immBlock(). */
+ if (phi0 == NULL) {
phi0_all = block->attr.block.graph_arr[pos];
- if (!((get_irn_op(phi0_all) == op_Phi) &&
+ if (!(is_Phi(phi0_all) &&
(get_irn_arity(phi0_all) == 0) &&
(get_nodes_block(phi0_all) == block)))
phi0_all = NULL;
/* In case we allocated a Phi0 node at the beginning of this procedure,
we need to exchange this Phi0 with the real Phi. */
- if (phi0) {
+ if (phi0 != NULL) {
exchange(phi0, res);
block->attr.block.graph_arr[pos] = res;
/* Don't set_frag_value as it does not overwrite. Doesn't matter, is
1. The block is not mature and we visit it the first time. We can not
create a proper Phi node, therefore a Phi0, i.e., a Phi without
- predecessors is returned. This node is added to the linked list (field
- "link") of the containing block to be completed when this block is
+ predecessors is returned. This node is added to the linked list (block
+ attribute "phis") of the containing block to be completed when this block is
matured. (Completion will add a new Phi and turn the Phi0 into an Id
node.)
res = block->attr.block.graph_arr[pos];
/* case 2 -- If the value is actually computed, return it. */
- if (res) { return res; };
+ if (res != NULL)
+ return res;
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);
ir_node **nin;
- NEW_ARR_A (ir_node *, nin, ins);
+ NEW_ARR_A(ir_node *, nin, ins);
/* Phi merge collects the predecessors and then creates a node. */
- res = phi_merge (block, pos, mode, nin, ins);
+ res = phi_merge(block, pos, mode, nin, ins);
} else { /* case 1 */
/* The block is not mature, we don't know how many in's are needed. A Phi
block->attr.block.phis = res;
}
- /* If we get here, the frontend missed a use-before-definition error */
- if (!res) {
- /* 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,
- get_mode_null(mode));
- }
+ assert(is_ir_node(res) && "phi_merge() failed to construct a definition");
/* The local valid value is available now. */
block->attr.block.graph_arr[pos] = res;
assert(is_Block(block));
if (!get_Block_matured(block)) {
- ins = ARR_LEN(block->in)-1;
+ ir_graph *irg = current_ir_graph;
+
+ ins = ARR_LEN(block->in) - 1;
/* Fix block parameters */
- block->attr.block.backedge = new_backedge_arr(current_ir_graph->obst, ins);
+ block->attr.block.backedge = new_backedge_arr(irg->obst, ins);
/* An array for building the Phi nodes. */
NEW_ARR_A(ir_node *, nin, ins);
/* Traverse a chain of Phi nodes attached to this block and mature
these, too. **/
for (n = block->attr.block.phis; n; n = next) {
- inc_irg_visited(current_ir_graph);
+ inc_irg_visited(irg);
next = n->attr.phi.next;
exchange(n, phi_merge(block, n->attr.phi.u.pos, n->mode, nin, ins));
}
block->attr.block.is_matured = 1;
- /* Now, as the block is a finished firm node, we can optimize it.
+ /* Now, as the block is a finished Firm node, we can optimize it.
Since other nodes have been allocated since the block was created
we can not free the node on the obstack. Therefore we have to call
- optimize_in_place.
+ optimize_in_place().
Unfortunately the optimization does not change a lot, as all allocated
nodes refer to the unoptimized node.
- We can call _2, as global cse has no effect on blocks. */
+ We can call optimize_in_place_2(), as global cse has no effect on blocks. */
block = optimize_in_place_2(block);
- IRN_VRFY_IRG(block, current_ir_graph);
+ IRN_VRFY_IRG(block, irg);
}
} /* mature_immBlock */
NEW_D_BINOP(Mulh)
/**
- * Allocate the frag array.
+ * Allocate a frag array for a node if the current graph state is phase_building.
+ *
+ * @param irn the node for which the frag array should be allocated
+ * @param op the opcode of the (original) node, if does not match opcode of irn,
+ * nothing is done
+ * @param frag_store the address of the frag store in irn attributes, if this
+ * address contains a value != NULL, does nothing
*/
-static void allocate_frag_arr(ir_node *res, ir_op *op, ir_node ***frag_store) {
+void firm_alloc_frag_arr(ir_node *irn, ir_op *op, ir_node ***frag_store) {
if (get_opt_precise_exc_context()) {
if ((current_ir_graph->phase_state == phase_building) &&
- (get_irn_op(res) == op) && /* Could be optimized away. */
+ (get_irn_op(irn) == op) && /* Could be optimized away. */
!*frag_store) /* Could be a cse where the arr is already set. */ {
- *frag_store = new_frag_arr(res);
+ *frag_store = new_frag_arr(irn);
}
}
-} /* allocate_frag_arr */
+} /* firm_alloc_frag_arr */
ir_node *
new_d_Quot(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) {
ir_node *res;
res = new_bd_Quot(db, current_ir_graph->current_block, memop, op1, op2, mode, state);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Quot, &res->attr.except.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Quot, &res->attr.except.frag_arr);
#endif
return res;
ir_node *res;
res = new_bd_DivMod(db, current_ir_graph->current_block, memop, op1, op2, mode, state);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_DivMod, &res->attr.except.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_DivMod, &res->attr.except.frag_arr);
#endif
return res;
ir_node *res;
res = new_bd_Div(db, current_ir_graph->current_block, memop, op1, op2, mode, state);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Div, &res->attr.except.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
#endif
return res;
ir_node *res;
res = new_bd_DivRL(db, current_ir_graph->current_block, memop, op1, op2, mode, state);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Div, &res->attr.except.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
#endif
return res;
ir_node *res;
res = new_bd_Mod(db, current_ir_graph->current_block, memop, op1, op2, mode, state);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Mod, &res->attr.except.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Mod, &res->attr.except.frag_arr);
#endif
return res;
NEW_D_BINOP(Shl)
NEW_D_BINOP(Shr)
NEW_D_BINOP(Shrs)
-NEW_D_BINOP(Rot)
+NEW_D_BINOP(Rotl)
NEW_D_UNOP(Abs)
NEW_D_BINOP(Carry)
NEW_D_BINOP(Borrow)
res = new_bd_Call(db, current_ir_graph->current_block,
store, callee, arity, in, tp);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
#endif
return res;
res = new_bd_Load(db, current_ir_graph->current_block,
store, addr, mode);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
#endif
return res;
res = new_bd_Store(db, current_ir_graph->current_block,
store, addr, val);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
#endif
return res;
res = new_bd_Alloc(db, current_ir_graph->current_block,
store, size, alloc_type, where);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Alloc, &res->attr.alloc.exc.frag_arr); /* Could be optimized away. */
+ firm_alloc_frag_arr(res, op_Alloc, &res->attr.alloc.exc.frag_arr);
#endif
return res;
sel, ir_false, ir_true, mode);
} /* new_d_Mux */
-ir_node *
-new_d_Psi(dbg_info *db,int arity, ir_node *conds[], ir_node *vals[], ir_mode *mode) {
- return new_bd_Psi(db, current_ir_graph->current_block,
- arity, conds, vals, mode);
-} /* new_d_Psi */
-
ir_node *new_d_CopyB(dbg_info *db,ir_node *store,
ir_node *dst, ir_node *src, ir_type *data_type) {
ir_node *res;
res = new_bd_CopyB(db, current_ir_graph->current_block,
store, dst, src, data_type);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
+ firm_alloc_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
#endif
return res;
} /* new_d_CopyB */
res = new_bd_Bound(db, current_ir_graph->current_block,
store, idx, lower, upper);
#if PRECISE_EXC_CONTEXT
- allocate_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
+ firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
#endif
return res;
} /* new_d_Bound */
/* call once for each run of the library */
void
-init_cons(uninitialized_local_variable_func_t *func) {
+firm_init_cons(uninitialized_local_variable_func_t *func) {
default_initialize_local_variable = func;
-} /* init_cons */
+} /* firm_init_cons */
void
irp_finalize_cons(void) {
ir_node *new_Shrs(ir_node *op, ir_node *k, ir_mode *mode) {
return new_d_Shrs(NULL, op, k, mode);
}
-ir_node *new_Rot(ir_node *op, ir_node *k, ir_mode *mode) {
- return new_d_Rot(NULL, op, k, mode);
+ir_node *new_Rotl(ir_node *op, ir_node *k, ir_mode *mode) {
+ return new_d_Rotl(NULL, op, k, mode);
}
ir_node *new_Carry(ir_node *op1, ir_node *op2, ir_mode *mode) {
return new_d_Carry(NULL, op1, op2, mode);
ir_node *new_Mux(ir_node *sel, ir_node *ir_false, ir_node *ir_true, ir_mode *mode) {
return new_d_Mux(NULL, sel, ir_false, ir_true, mode);
}
-ir_node *new_Psi(int arity, ir_node *conds[], ir_node *vals[], ir_mode *mode) {
- return new_d_Psi(NULL, arity, conds, vals, mode);
-}
ir_node *new_CopyB(ir_node *store, ir_node *dst, ir_node *src, ir_type *data_type) {
return new_d_CopyB(NULL, store, dst, src, data_type);
}