NAME ^

compilers/imcc/optimizer.c

DESCRIPTION ^

Optimization occurs in three stages: 1) pre_optimizer -- runs before control flow graph (CFG) is built 2) optimizer -- runs after CFG is built, but before register allocation 3) post_optimizer -- runs after register allocation

pre_optimizer -------------

During pre-optimization we perform optimizations which don't require full knowledge of the control flow graph and the life ranges of each variable. This phase is handled by two functions: pre_optimize() and cfg_optimize().

pre_optimize() runs before the construction of the CFG begins. It calls strength_reduce() to perform simple strength reduction, and if_branch() to rewrite certain if/branch/label constructs (for details, see if_branch() below).

[pre_optimize() may also be called later, during the main optimization phase, but this is not guaranteed.]

cfg_optimize() runs during the construction of the CFG. It calls branch_branch() to perform jump optimization (i.e. branches to branch statements or jumps to jumps are converted into single branches/jumps to the final destination), unused_label() to remove unused labels and dead_code_remove() to remove unreachable code (e.g. basic blocks which are never entered or instructions after and unconditional branch which are never branched to).

cfg_optimize may be called multiple times during the construction of the CFG depending on whether or not it finds anything to optimize.

RT#46277: subst_constants ... rewrite e.g. add_i_ic_ic -- where does this happen?

optimizer ---------

runs with CFG and life info

used_once ... deletes assignments, when LHS is unused loop_optimization ... pulls invariants out of loops RT#46279 e.g. constant_propagation

post_optimizer: currently pcc_optimize in pcc.c ---------------

runs after register alloocation

e.g. eliminate new Px .PerlUndef because Px where different before

Functions ^

int pre_optimize(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

Handles optimizations occuring before the construction of the CFG.

PARROT_WARN_UNUSED_RESULT int cfg_optimize(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

Handles optimizations occuring during the construction of the CFG. Returns TRUE if any optimization was performed. Otherwise, returns FALSE.

int optimize(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

RT#48260: Not yet documented!!!

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL const char *get_neg_op(ARGIN(const char *op), NOTNULL(int *n))

Get negated form of operator. If no negated form is known, return NULL.

static int if_branch(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

Convert if/branch/label constructs of the form:

  if cond L1
  branch L2
  L1
to the simpler negated form:

  unless cond L2
static int strength_reduce(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

strength_reduce ... rewrites e.g add Ix, Ix, y => add Ix, y

These are run after constant simplification, so it is guaranteed that one operand is non constant if opsize == 4

static int constant_propagation(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

Does conservative constant propagation. This code will not propagate constants past labels or saves, even though sometimes it may be safe.

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL Instruction *IMCC_subst_constants_umix(PARROT_INTERP, NOTNULL(IMC_Unit *unit), ARGIN(const char *name), NOTNULL(SymReg **r), int n)

rewrite e.g. add_n_ic => add_n_nc

PARROT_WARN_UNUSED_RESULT static int eval_ins(PARROT_INTERP, ARGIN(const char *op), size_t ops, NOTNULL(SymReg **r))

Run one parrot instruction, registers are filled with the according constants. Thus the result is always ok as the function core evaluates the constants.

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL Instruction *IMCC_subst_constants(PARROT_INTERP, NOTNULL(IMC_Unit *unit), ARGIN(const char *name), NOTNULL(SymReg **r), int n, NOTNULL(int *ok))

rewrite e.g. add_n_nc_nc => set_n_nc abs_i_ic => set_i_ic eq_ic_ic_ic => branch_ic / delete if_ic_ic => branch_ic / delete

static int branch_branch(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

if I0 goto L1 => if IO goto L2 ... L1: branch L2

Returns TRUE if any optimizations were performed. Otherwise, returns FALSE.

PARROT_WARN_UNUSED_RESULT static int branch_reorg(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

branch L2 => ... L1: branch L4 ... L1: branch L3 ... L2: branch L3 ... L5: branch L4 L5:

Returns TRUE if any optimizations were performed. Otherwise, returns FALSE.

PARROT_WARN_UNUSED_RESULT static int branch_cond_loop_swap(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *branch), NOTNULL(Instruction *start), NOTNULL(Instruction *cond))

RT#48260: Not yet documented!!!

static int branch_cond_loop(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

start: => start: if cond goto end if cond goto end ... branch start start_post1: end: ... unless cond goto start_post562 end:

The basic premise is "branch (A) to conditional (B), where B goes to just after A."

Returns TRUE if any optimizations were performed. Otherwise, returns FALSE.

PARROT_WARN_UNUSED_RESULT static int unused_label(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

Removes unused labels. A label is unused if ... [RT#46287: finish this].

Returns TRUE if any optimizations were performed. Otherwise, returns FALSE.

static int dead_code_remove(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

RT#48260: Not yet documented!!!

static int used_once(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

RT#48260: Not yet documented!!!

static int _is_ins_save(NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *check_ins), NOTNULL(SymReg *r), int what)

RT#48260: Not yet documented!!!

PARROT_WARN_UNUSED_RESULT static int is_ins_save(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *ins), NOTNULL(SymReg *r), int what)

RT#48260: Not yet documented!!!

int max_loop_depth(NOTNULL(IMC_Unit *unit))

RT#48260: Not yet documented!!!

int is_invariant(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *ins))

RT#48260: Not yet documented!!!

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL Basic_block *find_outer(NOTNULL(IMC_Unit *unit), NOTNULL(Basic_block *blk))

RT#48260: Not yet documented!!!

int move_ins_out(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction **ins), NOTNULL(Basic_block *bb))

move the instruction ins before loop in bb

int loop_one(PARROT_INTERP, NOTNULL(IMC_Unit *unit), int bnr)

RT#48260: Not yet documented!!!

int loop_optimization(PARROT_INTERP, NOTNULL(IMC_Unit *unit))

RT#48260: Not yet documented!!!


parrot