Exemple #1
0
//Control flow struct optimizations.
//Transform follow struct to do-while loop
//
//    LABEL:
//    IR-List
//    IF DET
//       GOTO LABEL
//       ...(DEAD CODE)
//    ELSE
//       FALSE-PART
//    ENDIF
//
//is replace by
//
//    DO {
//        IR-List
//    } WHILE DET
//    FALSE-PART
bool IR_CFS_OPT::transformToDoWhile(IR ** head, IR * ir)
{
    ASSERT(head != NULL && *head != NULL, ("invalid parameter"));
    if (!ir->is_lab()) { return false; }

    for (IR * t = ir; t != NULL; t = t->get_next()) {
        if (!t->is_if()) { continue; }

        if (IF_truebody(t) != NULL &&
            IF_truebody(t)->is_goto() &&
            isSameLabel(LAB_lab(ir), GOTO_lab(IF_truebody(t)))) {

            //Start transform.
            IR * dowhile = m_ru->allocIR(IR_DO_WHILE);
            LOOP_det(dowhile) = m_ru->dupIRTree(LOOP_det(t));

            IR * if_stmt = t;
            t = ir->get_next();
            while (t != NULL && t != if_stmt) {
                IR * c = t;
                t = t->get_next();
                xcom::remove(head, c);
                xcom::add_next(&LOOP_body(dowhile), c);
            }

            ASSERT(t == if_stmt, ("illegal IR layout"));

            xcom::remove(head, if_stmt);
            if (IF_falsebody(if_stmt)) {
                xcom::add_next(&dowhile, IF_falsebody(if_stmt));
                IF_falsebody(if_stmt) = NULL;
            }
            xcom::insertafter(&ir, dowhile);
            m_ru->freeIRTree(if_stmt); //free IF
            xcom::remove(head, ir);
            m_ru->freeIRTree(ir); //free LABEL
            return true;
        }
    }

    return false;
}
Exemple #2
0
bool IR_CFS_OPT::CfsOpt(
        IN OUT IR ** ir_list,
        SimpCtx const& sc)
{
    bool change = false;

    for (IR * ir = *ir_list; ir != NULL;) {
        if (transformToDoWhile(ir_list, ir)) {
            change = true;
            ir = *ir_list;
            continue;
        }

        if (ir->is_if() && transformIf1(ir_list, ir)) {
            change = true;
            ir = *ir_list;
            continue;
        }

        if (ir->is_if() && transformIf2(ir_list, ir)) {
            change = true;
            ir = *ir_list;
            continue;
        }

        if (ir->is_if() && transformIf3(ir_list, ir)) {
            change = true;
            ir = *ir_list;
            continue;
        }

        switch (ir->get_code()) {
        case IR_IF:
            if (hoistIf(ir_list, ir)) {
                change = true;
                ir = *ir_list;
                continue;
            }
            if (CfsOpt(&IF_truebody(ir), sc)) {
                change = true;
                ir = *ir_list;
                continue;
            }
            if (CfsOpt(&IF_falsebody(ir), sc)) {
                change = true;
                ir = *ir_list;
                continue;
            }
            break;
        case IR_DO_WHILE:
        case IR_WHILE_DO:
        case IR_DO_LOOP:
            if (hoistLoop(ir_list, ir)) {
                change = true;
                ir = *ir_list;
                continue;
            }
            if (CfsOpt(&LOOP_body(ir), sc)) {
                change = true;
                ir = *ir_list;
                continue;
            }
            break;
        case IR_SWITCH:
            if (CfsOpt(&SWITCH_body(ir), sc)) {
                change = true;
                ir = *ir_list;
                continue;
            }
            break;
        default:;
        } //end switch

         ir = ir->get_next();
    }
    return change;
}