ignore OP_LOAD_* ops when calculating potential unary constant folds

ran clang-format
This commit is contained in:
Anthony Pesch 2016-12-18 16:06:52 -08:00
parent d8a4a623f4
commit 4444a431b5
3 changed files with 42 additions and 38 deletions

View File

@ -2,80 +2,86 @@
#include "jit/ir/ir.h"
#include "jit/pass_stats.h"
DEFINE_STAT(constant_propagations_removed, "constant propagations removed");
DEFINE_STAT(constants_folded, "constant operations folded");
DEFINE_STAT(could_optimize_binary_op, "constant binary operations possible");
DEFINE_STAT(could_optimize_unary_op, "constant unary operations possible");
void cprop_run(struct ir *ir) {
list_for_each_entry(instr, &ir->instrs, struct ir_instr, it) {
/* Simplify binary ops with constant arguments */
if(instr->arg[0] && ir_is_constant(instr->arg[0]) &&
instr->arg[1] && ir_is_constant(instr->arg[1]) &&
instr->result)
{
/* fold constant binary ops */
if (instr->arg[0] && ir_is_constant(instr->arg[0]) && instr->arg[1] &&
ir_is_constant(instr->arg[1]) && instr->result) {
uint64_t lhs = ir_zext_constant(instr->arg[0]);
uint64_t rhs = ir_zext_constant(instr->arg[1]);
struct ir_value *result;
switch(instr->op)
{
struct ir_value *folded = NULL;
switch (instr->op) {
case OP_ADD:
result = ir_alloc_int(ir, lhs + rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs + rhs, instr->result->type);
break;
case OP_AND:
result = ir_alloc_int(ir, lhs & rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs & rhs, instr->result->type);
break;
case OP_DIV:
result = ir_alloc_int(ir, lhs / rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs / rhs, instr->result->type);
break;
case OP_LSHR:
result = ir_alloc_int(ir, lhs >> rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs >> rhs, instr->result->type);
break;
case OP_OR:
result = ir_alloc_int(ir, lhs | rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs | rhs, instr->result->type);
break;
case OP_SHL:
result = ir_alloc_int(ir, lhs << rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs << rhs, instr->result->type);
break;
case OP_SUB:
result = ir_alloc_int(ir, lhs - rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs - rhs, instr->result->type);
break;
case OP_UMUL:
result = ir_alloc_int(ir, lhs * rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs * rhs, instr->result->type);
break;
case OP_XOR:
result = ir_alloc_int(ir, lhs ^ rhs, instr->result->type);
folded = ir_alloc_int(ir, lhs ^ rhs, instr->result->type);
break;
default:
STAT_could_optimize_binary_op++;
continue;
}
ir_replace_uses(instr->result, result);
STAT_constant_propagations_removed++;
if (folded) {
ir_replace_uses(instr->result, folded);
STAT_constants_folded++;
}
}
/* Simplify constant unary ops */
else if(instr->arg[0] && !instr->arg[1] && ir_is_constant(instr->arg[0]) &&
instr->result) {
/* fold constant unary ops */
else if (instr->arg[0] && !instr->arg[1] && ir_is_constant(instr->arg[0]) &&
instr->result) {
uint64_t arg = ir_zext_constant(instr->arg[0]);
struct ir_value *result;
switch(instr->op)
{
struct ir_value *folded = NULL;
switch (instr->op) {
case OP_NEG:
result = ir_alloc_int(ir, 0 - arg, instr->result->type);
folded = ir_alloc_int(ir, 0 - arg, instr->result->type);
break;
case OP_NOT:
result = ir_alloc_int(ir, ~arg, instr->result->type);
folded = ir_alloc_int(ir, ~arg, instr->result->type);
break;
/* filter the load instructions out of the "could optimize" stats */
case OP_LOAD:
case OP_LOAD_FAST:
case OP_LOAD_SLOW:
case OP_LOAD_CONTEXT:
case OP_LOAD_LOCAL:
break;
default:
STAT_could_optimize_unary_op++;
continue;
}
ir_replace_uses(instr->result, result);
STAT_constant_propagations_removed++;
if (folded) {
ir_replace_uses(instr->result, folded);
STAT_constants_folded++;
}
}
}
}

View File

@ -3,8 +3,6 @@
struct ir;
void cprop_run(struct ir *ir);
#endif

View File

@ -78,7 +78,7 @@ static void process_file(struct jit *jit, const char *filename,
while (name) {
if (!strcmp(name, "lse")) {
lse_run(&ir);
} else if (!strcmp(name, "cprop")){
} else if (!strcmp(name, "cprop")) {
cprop_run(&ir);
} else if (!strcmp(name, "cve")) {
cve_run(&ir);