parrotcode: compilers/imcc/optimizer.c | |
Contents | Compilers |
compilers/imcc/optimizer.c
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
int pre_optimize(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
int cfg_optimize(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
int optimize(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
const char *get_neg_op(NOTNULL(const char *op), NOTNULL(int *n))
static int if_branch(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
if cond L1
branch L2
L1
unless cond L2
static int strength_reduce(PARROT_INTERP, IMC_Unit *unit)
static int constant_propagation(PARROT_INTERP, IMC_Unit *unit)
Instruction *IMCC_subst_constants_umix(PARROT_INTERP, IMC_Unit *unit, NOTNULL(const char *name), SymReg **r, int n)
static int eval_ins(PARROT_INTERP, char *op, size_t ops, SymReg **r)
PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL Instruction *IMCC_subst_constants(PARROT_INTERP, IMC_Unit *unit, NOTNULL(const char *name), SymReg **r, int n, NOTNULL(int *ok))
static int branch_branch(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
static int branch_reorg(PARROT_INTERP, IMC_Unit *unit)
static int branch_cond_loop_swap(PARROT_INTERP, IMC_Unit *unit, Instruction *branch, Instruction *start, Instruction *cond)
static int branch_cond_loop(PARROT_INTERP, IMC_Unit *unit)
static int unused_label(PARROT_INTERP, IMC_Unit *unit)
static int dead_code_remove(PARROT_INTERP, IMC_Unit *unit)
static int used_once(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
static int _is_ins_save(NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *check_ins), NOTNULL(SymReg *r), int what)
PARROT_WARN_UNUSED_RESULT static int is_ins_save(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *ins), NOTNULL(SymReg *r), int what)
int max_loop_depth(NOTNULL(IMC_Unit *unit))
int is_invariant(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction *ins))
Basic_block *find_outer(NOTNULL(IMC_Unit *unit), NOTNULL(Basic_block *blk))
int move_ins_out(PARROT_INTERP, NOTNULL(IMC_Unit *unit), NOTNULL(Instruction **ins), NOTNULL(Basic_block *bb))
int loop_one(PARROT_INTERP, NOTNULL(IMC_Unit *unit), int bnr)
int loop_optimization(PARROT_INTERP, NOTNULL(IMC_Unit *unit))
|