// returns an array of call-free inner-loops
LoopList* LoopFinder::compute_loops(bool call_free_only) {
  // visited has flags set for each block that has been visited
  boolArray visited (max_blocks(), false);
  if (ok()) compute_dominators(&visited);

  if (ir()->method()->has_exception_handlers()) set_not_ok();

  LoopList* all_loops = NULL;
  if (ok()) all_loops = find_backedges(&visited);
  if (ok())             gather_loop_blocks(all_loops);
  if (ok())    _loops = find_loops(all_loops, call_free_only);
  if (ok())             compute_loop_exits_and_entries(_loops);

  if (ok() && OptimizeSinglePrecision) {
    compute_single_precision_flag(_loops);
  }
  // asserts are using the precision computed before
  if (ok())             insert_blocks(_loops);
  if (ok() && PrintLoops && Verbose) {
    all_loops->print("+All Loops:");
    _loops->print("+Inner Loops:");
    ir()->print(false);
  }
  return _loops;
}
Exemple #2
0
void
loop_process()
{
    find_loops();
    map_bbi_loop();
    //dump_loops();
    loop_relations();
    //dump_loop_comm_ances();
}
Exemple #3
0
/* imc_reg_alloc is the main loop of the allocation algorithm. It operates
 * on a single compilation unit at a time.
 */
void
imc_reg_alloc(struct Parrot_Interp *interpreter, IMC_Unit * unit)
{
    int to_spill;
    int todo, first;

    if (!unit)
        return;
    if (!optimizer_level && pasm_file)
        return;

    init_tables(interpreter);
    allocated = 0;

#if IMC_TRACE
    fprintf(stderr, "reg_alloc.c: imc_reg_alloc\n");
    if (unit->instructions->r[1] && unit->instructions->r[1]->pcc_sub) {
        fprintf(stderr, "img_reg_alloc: pcc_sub (nargs = %d)\n",
            unit->instructions->r[1]->pcc_sub->nargs);
    }
#endif

    debug(interpreter, DEBUG_IMC, "\n------------------------\n");
    debug(interpreter, DEBUG_IMC, "processing sub %s\n", function);
    debug(interpreter, DEBUG_IMC, "------------------------\n\n");
    if (IMCC_INFO(interpreter)->verbose ||
            (IMCC_INFO(interpreter)->debug & DEBUG_IMC))
        imc_stat_init(unit);

    /* consecutive labels, if_branch, unused_labels ... */
    pre_optimize(interpreter, unit);
    if (optimizer_level == OPT_PRE && pasm_file)
        return;

    nodeStack = imcstack_new();
    unit->n_spilled = 0;

    todo = first = 1;
    while (todo) {
        find_basic_blocks(interpreter, unit, first);
        build_cfg(interpreter, unit);

        if (first && (IMCC_INFO(interpreter)->debug & DEBUG_CFG))
            dump_cfg(unit);
        first = 0;
        todo = cfg_optimize(interpreter, unit);
    }

    todo = first = 1;
    while (todo) {
        if (!first) {
            find_basic_blocks(interpreter, unit, 0);
            build_cfg(interpreter, unit);
        }
        first = 0;

        compute_dominators(interpreter, unit);
        find_loops(interpreter, unit);

        build_reglist(interpreter, unit);
        life_analysis(interpreter, unit);
        /* optimize, as long as there is something to do */
        if (dont_optimize)
            todo = 0;
        else {
            todo = optimize(interpreter, unit);
            if (todo)
                pre_optimize(interpreter, unit);
        }
    }
    todo = 1;
#if !DOIT_AGAIN_SAM
    build_interference_graph(interpreter, unit);
#endif
    while (todo) {
#if DOIT_AGAIN_SAM
        build_interference_graph(interpreter, unit);
#endif
        if (optimizer_level & OPT_SUB)
            allocate_wanted_regs(unit);
        compute_spilling_costs(interpreter, unit);
#ifdef DO_SIMPLIFY
        /* simplify until no changes can be made */
        while (simplify(unit)) {}
#endif
        order_spilling(unit);          /* put the remaining items on stack */

        to_spill = try_allocate(interpreter, unit);
        allocated = 1;

        if ( to_spill >= 0 ) {
            allocated = 0;
            spill(interpreter, unit, to_spill);
            /*
             * build the new cfg/reglist on the fly in spill() and
             * do life analysis there for only the involved regs
             */
#if DOIT_AGAIN_SAM
            find_basic_blocks(interpreter, unit, 0);
            build_cfg(interpreter, unit);
            build_reglist(interpreter, unit);
            life_analysis(interpreter);
#endif
        }
        else {
            /* the process is finished */
            todo = 0;
        }
    }
    if (optimizer_level & OPT_SUB)
        sub_optimize(interpreter, unit);
    if (IMCC_INFO(interpreter)->debug & DEBUG_IMC)
        dump_instructions(unit);
    if (IMCC_INFO(interpreter)->verbose  ||
            (IMCC_INFO(interpreter)->debug & DEBUG_IMC))
        print_stat(interpreter, unit);
    imcstack_free(nodeStack);
}