placeholder sext/zext/trunc elimination pass

This commit is contained in:
Anthony Pesch 2016-04-11 00:24:26 -07:00
parent 9a8b5ff755
commit d49d107b78
4 changed files with 102 additions and 1 deletions

View File

@ -170,6 +170,7 @@ set(REDREAM_SOURCES
src/jit/ir/ir_reader.cc
src/jit/ir/ir_writer.cc
#src/jit/ir/passes/constant_propagation_pass.cc
src/jit/ir/passes/conversion_elimination_pass.cc
src/jit/ir/passes/dead_code_elimination_pass.cc
src/jit/ir/passes/load_store_elimination_pass.cc
src/jit/ir/passes/pass_runner.cc

View File

@ -0,0 +1,74 @@
#include "jit/ir/passes/conversion_elimination_pass.h"
using namespace re::jit::backend;
using namespace re::jit::ir;
using namespace re::jit::ir::passes;
DEFINE_STAT(num_sext_removed, "Number of sext eliminated");
DEFINE_STAT(num_zext_removed, "Number of zext eliminated");
DEFINE_STAT(num_trunc_removed, "Number of trunc eliminated");
void ConversionEliminationPass::Run(IRBuilder &builder) {
auto it = builder.instrs().begin();
auto end = builder.instrs().end();
while (it != end) {
Instr *instr = *(it++);
// eliminate unnecessary sext / zext operations
if (instr->op() == OP_LOAD_HOST || instr->op() == OP_LOAD_GUEST ||
instr->op() == OP_LOAD_CONTEXT) {
ValueType memory_type = VALUE_V;
bool same_type = true;
bool all_sext = true;
bool all_zext = true;
for (auto use : instr->uses()) {
Instr *use_instr = use->instr();
if (use_instr->op() == OP_SEXT || use_instr->op() == OP_ZEXT) {
if (memory_type == VALUE_V) {
memory_type = use_instr->type();
}
if (memory_type != use_instr->type()) {
same_type = false;
}
}
if (use_instr->op() != OP_SEXT) {
all_sext = false;
}
if (use_instr->op() != OP_ZEXT) {
all_zext = false;
}
}
if (same_type && all_sext) {
// TODO implement
num_sext_removed++;
} else if (same_type && all_zext) {
// TODO implement
num_zext_removed++;
}
} else if (instr->op() == OP_STORE_HOST || instr->op() == OP_STORE_GUEST ||
instr->op() == OP_STORE_CONTEXT) {
Value *store_value = instr->arg1();
if (!store_value->constant()) {
Instr *def = store_value->def();
if (def->op() == OP_TRUNC) {
// TODO implement
// note, don't actually remove the truncation as other values may
// reference it. let DCE clean it up
num_trunc_removed++;
}
}
}
}
}

View File

@ -0,0 +1,23 @@
#ifndef CONVERSION_ELIMINATION_PASS_H
#define CONVERSION_ELIMINATION_PASS_H
#include "jit/backend/backend.h"
#include "jit/ir/passes/pass_runner.h"
namespace re {
namespace jit {
namespace ir {
namespace passes {
class ConversionEliminationPass : public Pass {
public:
const char *name() { return "cve"; }
void Run(IRBuilder &builder);
};
}
}
}
}
#endif

View File

@ -7,6 +7,7 @@
#include "jit/frontend/sh4/sh4_frontend.h"
#include "jit/ir/ir_builder.h"
#include "jit/ir/ir_reader.h"
#include "jit/ir/passes/conversion_elimination_pass.h"
#include "jit/ir/passes/dead_code_elimination_pass.h"
#include "jit/ir/passes/load_store_elimination_pass.h"
#include "sys/filesystem.h"
@ -16,7 +17,7 @@ using namespace re::jit::ir;
using namespace re::jit::ir::passes;
using namespace re::sys;
DEFINE_string(pass, "lse,dce", "Comma-separated list of passes to run");
DEFINE_string(pass, "lse,cve,dce", "Comma-separated list of passes to run");
DEFINE_bool(print_after_all, true, "Print IR after each pass");
DEFINE_bool(stats, true, "Display pass stats");
@ -62,6 +63,8 @@ static void process_file(const char *filename, bool disable_ir_dump) {
if (name == "lse") {
pass = std::unique_ptr<Pass>(new LoadStoreEliminationPass());
} else if (name == "cve") {
pass = std::unique_ptr<Pass>(new ConversionEliminationPass());
} else if (name == "dce") {
pass = std::unique_ptr<Pass>(new DeadCodeEliminationPass());
} else {