write DCE

This commit is contained in:
2024-10-24 06:44:04 +00:00
parent 8e4e133fa0
commit 86a835c6ef
6 changed files with 135 additions and 2 deletions

View File

@ -64,7 +64,11 @@ class GlobalVarDefItem : public LLVMIRItemBase {
} }
} }
}; };
class ActionItem : public LLVMIRItemBase {}; class ActionItem : public LLVMIRItemBase {
public:
bool marked_as_useless;
ActionItem() : marked_as_useless(false) {}
};
class JMPActionItem : public ActionItem { class JMPActionItem : public ActionItem {
public: public:
std::shared_ptr<class PhiItem> corresponding_phi; std::shared_ptr<class PhiItem> corresponding_phi;

4
include/opt/dce.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#include "IR/IR_basic.h"
std::shared_ptr<ModuleItem> DCE(std::shared_ptr<ModuleItem> src);

View File

@ -3,3 +3,4 @@
#include "global_var_cache.h" #include "global_var_cache.h"
#include "mem2reg.h" #include "mem2reg.h"
#include "regalloc.h" #include "regalloc.h"
#include "dce.h"

View File

@ -49,6 +49,7 @@ int main(int argc, char **argv) {
auto IR_with_out_allocas = Mem2Reg(IR); auto IR_with_out_allocas = Mem2Reg(IR);
// IR_with_out_allocas->RecursivePrint(std::cerr); // IR_with_out_allocas->RecursivePrint(std::cerr);
IR_with_out_allocas = GloabalVarCache(IR_with_out_allocas); IR_with_out_allocas = GloabalVarCache(IR_with_out_allocas);
IR_with_out_allocas = DCE(IR_with_out_allocas);
// IR_with_out_allocas->RecursivePrint(std::cerr); // IR_with_out_allocas->RecursivePrint(std::cerr);
auto IR_with_out_phis = PhiEliminate(IR_with_out_allocas); auto IR_with_out_phis = PhiEliminate(IR_with_out_allocas);
// IR_with_out_phis->RecursivePrint(std::cerr); // IR_with_out_phis->RecursivePrint(std::cerr);

63
src/opt/dce.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "dce.h"
#include "IR/IR_basic.h"
#include "cfg.h"
#include "liveanalysis.h"
void ConductDCEForFunction(std::shared_ptr<FunctionDefItem> func);
void ConductDCEForFunction(std::shared_ptr<FunctionDefItem> func) {
CFGType cfg;
cfg = BuildCFGForFunction(func);
LiveAnalysis(cfg);
std::unordered_set<std::string> all_vars;
std::unordered_map<std::string, std::unordered_set<ActionItem *>> use_map, def_map;
std::unordered_map<ActionItem *, std::vector<size_t>> actions_use_vars;
for (size_t i = 0; i < cfg.id_to_var.size(); i++) {
all_vars.insert(cfg.id_to_var[i]);
}
for (auto node : cfg.nodes) {
for (const auto &[action, use_vars] : node->action_use_vars) {
for (auto var_id : use_vars) {
use_map[cfg.id_to_var[var_id]].insert(action);
}
actions_use_vars[action] = use_vars;
}
for (const auto &[action, def_vars] : node->action_def_vars) {
for (auto var_id : def_vars) {
def_map[cfg.id_to_var[var_id]].insert(action);
}
}
}
while (all_vars.size() > 0) {
auto v = *(all_vars.begin());
all_vars.erase(v);
if (use_map[v].size() == 0) {
if (def_map[v].size() != 1) throw std::runtime_error("def_map[v].size()!=1");
auto def_inst = *(def_map[v].begin());
if (!dynamic_cast<CallItem *>(def_inst)) {
// no side effect
def_inst->marked_as_useless = true;
const auto &use_vars = actions_use_vars[def_inst];
for (auto var_id : use_vars) {
use_map[cfg.id_to_var[var_id]].erase(def_inst);
all_vars.insert(cfg.id_to_var[var_id]);
}
}
}
}
for (auto node : cfg.nodes) {
auto block = node->corresponding_block;
auto tmp = block->actions;
block->actions.clear();
for (auto act : tmp) {
if (!act->marked_as_useless) {
block->actions.push_back(act);
}
}
}
}
std::shared_ptr<ModuleItem> DCE(std::shared_ptr<ModuleItem> src) {
for (auto func : src->function_defs) {
ConductDCEForFunction(func);
}
return src;
}

View File

@ -22,6 +22,9 @@ void VarCollect(CFGType &cfg, std::vector<std::string> &id_to_var, std::unordere
}; };
for (auto node : cfg.nodes) { for (auto node : cfg.nodes) {
auto block = node->corresponding_block; auto block = node->corresponding_block;
for (auto [_, phi_act] : block->phi_map) {
TryAddVar(phi_act->result_full);
}
for (auto act : block->actions) { for (auto act : block->actions) {
if (auto bin_act = std::dynamic_pointer_cast<BinaryOperationAction>(act)) { if (auto bin_act = std::dynamic_pointer_cast<BinaryOperationAction>(act)) {
TryAddVar(bin_act->result_full); TryAddVar(bin_act->result_full);
@ -46,6 +49,8 @@ void VarCollect(CFGType &cfg, std::vector<std::string> &id_to_var, std::unordere
TryAddVar(load_spilled_args_act->var_full); TryAddVar(load_spilled_args_act->var_full);
} else if (auto alloca_act = std::dynamic_pointer_cast<AllocaAction>(act)) { } else if (auto alloca_act = std::dynamic_pointer_cast<AllocaAction>(act)) {
TryAddVar(alloca_act->name_full); TryAddVar(alloca_act->name_full);
} else if (auto phi_act = std::dynamic_pointer_cast<PhiItem>(act)) {
TryAddVar(phi_act->result_full);
} }
} }
} }
@ -63,6 +68,47 @@ void UseDefCollect(CFGType &cfg, [[maybe_unused]] std::vector<std::string> &id_t
std::vector<size_t> cur_node_use; std::vector<size_t> cur_node_use;
std::vector<size_t> cur_node_def; std::vector<size_t> cur_node_def;
bool use_def_init = false; bool use_def_init = false;
for (auto [_, phi_act] : block->phi_map) {
std::vector<size_t> &cur_act_use = node->action_use_vars[phi_act.get()];
std::vector<size_t> &cur_act_def = node->action_def_vars[phi_act.get()];
if (var_to_id.find(phi_act->result_full) != var_to_id.end()) {
cur_act_def.push_back(var_to_id[phi_act->result_full]);
}
std::unordered_set<size_t> cur_act_use_tmp;
for (auto &[value, _] : phi_act->values) {
if (var_to_id.find(value) != var_to_id.end()) {
// cur_act_use.push_back(var_to_id[value]);
cur_act_use_tmp.insert(var_to_id[value]);
}
}
for (size_t i : cur_act_use_tmp) {
cur_act_use.push_back(i);
}
std::sort(cur_act_use.begin(), cur_act_use.end());
std::sort(cur_act_def.begin(), cur_act_def.end());
for (size_t i = 1; i < cur_act_use.size(); i++) {
if (cur_act_use[i] == cur_act_use[i - 1]) {
throw std::runtime_error("use variable appears twice in one action");
}
}
for (size_t i = 1; i < cur_act_def.size(); i++) {
if (cur_act_def[i] == cur_act_def[i - 1]) {
throw std::runtime_error("def variable appears twice in one action");
}
}
if (!use_def_init) {
use_def_init = true;
cur_node_use = cur_act_use;
cur_node_def = cur_act_def;
} else {
const auto &use_p = cur_node_use;
const auto &def_p = cur_node_def;
const auto &use_n = cur_act_use;
const auto &def_n = cur_act_def;
cur_node_use = GetCollectionsUnion(use_p, GetCollectionsDifference(use_n, def_p));
cur_node_def = GetCollectionsUnion(def_p, def_n);
}
}
for (auto act : block->actions) { for (auto act : block->actions) {
std::vector<size_t> &cur_act_use = node->action_use_vars[act.get()]; std::vector<size_t> &cur_act_use = node->action_use_vars[act.get()];
std::vector<size_t> &cur_act_def = node->action_def_vars[act.get()]; std::vector<size_t> &cur_act_def = node->action_def_vars[act.get()];
@ -182,6 +228,20 @@ void UseDefCollect(CFGType &cfg, [[maybe_unused]] std::vector<std::string> &id_t
} }
} else if (auto alloca_act = std::dynamic_pointer_cast<AllocaAction>(act)) { } else if (auto alloca_act = std::dynamic_pointer_cast<AllocaAction>(act)) {
cur_act_def.push_back(var_to_id[alloca_act->name_full]); cur_act_def.push_back(var_to_id[alloca_act->name_full]);
} else if (auto phi_act = std::dynamic_pointer_cast<PhiItem>(act)) {
if (var_to_id.find(phi_act->result_full) != var_to_id.end()) {
cur_act_def.push_back(var_to_id[phi_act->result_full]);
}
std::unordered_set<size_t> cur_act_use_tmp;
for (auto &[value, _] : phi_act->values) {
if (var_to_id.find(value) != var_to_id.end()) {
// cur_act_use.push_back(var_to_id[value]);
cur_act_use_tmp.insert(var_to_id[value]);
}
}
for (size_t i : cur_act_use_tmp) {
cur_act_use.push_back(i);
}
} }
std::sort(cur_act_use.begin(), cur_act_use.end()); std::sort(cur_act_use.begin(), cur_act_use.end());
std::sort(cur_act_def.begin(), cur_act_def.end()); std::sort(cur_act_def.begin(), cur_act_def.end());