}
}
+#include "irdump.h"
+
void inline_method(ir_node *call, ir_graph *called_graph) {
ir_node *pre_call;
ir_node *post_call, *post_bl;
free(res_pred);
free(cf_pred);
-/* --
- If the exception control flow from the Call directly branched to the
- end block we now have the following control flow predecessor pattern:
- ProjX -> Tuple -> Jmp.
- We must remove the Jmp along with it's empty block and add Jmp's
- predecessors as predecessors of this end block. -- */
- /* find the problematic predecessor of the end block. */
- end_bl = get_irg_end_block(current_ir_graph);
- for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
- cf_op = get_Block_cfgpred(end_bl, i);
- if (get_irn_op(cf_op) == op_Proj) {
- cf_op = get_Proj_pred(cf_op);
- if (get_irn_op(cf_op) == op_Tuple) {
- cf_op = get_Tuple_pred(cf_op, 1);
- assert(get_irn_op(cf_op) == op_Jmp);
- break;
+ if (n_exc > 0) {
+ /* -- If the exception control flow from the inlined Call directly
+ branched to the end block we now have the following control
+ flow predecessor pattern: ProjX -> Tuple -> Jmp. We must
+ remove the Jmp along with it's empty block and add Jmp's
+ predecessors as predecessors of this end block. No problem if
+ there is no exception, because then branches Bad to End which
+ is fine. -- */
+ /* find the problematic predecessor of the end block. */
+ end_bl = get_irg_end_block(current_ir_graph);
+ for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
+ cf_op = get_Block_cfgpred(end_bl, i);
+ if (get_irn_op(cf_op) == op_Proj) {
+ cf_op = get_Proj_pred(cf_op);
+ if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
+ // There are unoptimized tuples from inlineing before when no exc
+ assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
+ cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
+ assert(get_irn_op(cf_op) == op_Jmp);
+ break;
+ }
}
}
- }
- /* repair */
- if (i < get_Block_n_cfgpreds(end_bl)) {
- bl = get_nodes_Block(cf_op);
- arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
- cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
- for (j = 0; j < i; j++)
- cf_pred[j] = get_Block_cfgpred(end_bl, j);
- for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
- cf_pred[j] = get_Block_cfgpred(bl, j-i);
- for (j = j; j < arity; j++)
- cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
- set_irn_in(end_bl, arity, cf_pred);
- free(cf_pred);
+ /* repair */
+ if (i < get_Block_n_cfgpreds(end_bl)) {
+ bl = get_nodes_Block(cf_op);
+ arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
+ cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
+ for (j = 0; j < i; j++)
+ cf_pred[j] = get_Block_cfgpred(end_bl, j);
+ for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
+ cf_pred[j] = get_Block_cfgpred(bl, j-i);
+ for (j = j; j < arity; j++)
+ cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
+ set_irn_in(end_bl, arity, cf_pred);
+ free(cf_pred);
+ }
}
/* -- Turn cse back on. -- */
/* will be executed only if needed. */
/********************************************************************/
+#include "irdump.h"
+
static pdeq *worklist; /* worklist of ir_node*s */
/* Find the earliest correct block for N. --- Place N into the
if ((get_irn_op(n) == op_Const) ||
(get_irn_op(n) == op_SymConst) ||
- (is_Bad(n))) {
+ (is_Bad(n)) ||
+ (get_irn_op(n) == op_Unknown)) {
/* These nodes will not be placed by the loop below. */
b = get_irg_start_block(current_ir_graph);
depth = 1;
while (irn_not_visited(b) && (!is_Bad(new)) && (new != b)) {
/* We would have to run gigo if new is bad, so we
promote it directly below. */
- assert(((b == new) || get_opt_control_flow_straightening() || get_opt_control_flow_weak_simplification()) &&
+ assert(((b == new) ||
+ get_opt_control_flow_straightening() ||
+ get_opt_control_flow_weak_simplification()) &&
("strange flag setting"));
exchange (b, new);
b = new;
(get_irn_arity(n) > 1)) {
arity = get_irn_arity(n);
+ if (n == get_irg_end_block(current_ir_graph))
+ return; // No use to add a block here.
+
for (i=0; i<arity; i++) {
pre = get_irn_n(n, i);
/* Predecessor has multiple sucessors. Insert new flow edge */
- if ((NULL != pre) && (op_Proj == get_irn_op(pre))) {
+ if ((NULL != pre) &&
+ (op_Proj == get_irn_op(pre)) &&
+ op_Raise != get_irn_op(skip_Proj(pre))) {
/* set predecessor array for new block */
in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);