add dominance(partial)
This commit is contained in:
parent
34a5a8ff01
commit
7140d0bf2b
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -1,6 +1,7 @@
|
||||
{
|
||||
"clangd.arguments": [
|
||||
"--compile-commands-dir=${workspaceFolder}/build"
|
||||
"--compile-commands-dir=${workspaceFolder}/build",
|
||||
"--header-insertion=never"
|
||||
],
|
||||
"cmake.configureOnOpen": true,
|
||||
"antlr4.rrd.saveDir": "${workspaceFolder}/build",
|
||||
@ -14,5 +15,7 @@
|
||||
"[python]": {
|
||||
"editor.defaultFormatter": "ms-python.autopep8"
|
||||
},
|
||||
"python.formatting.provider": "none"
|
||||
"python.formatting.provider": "none",
|
||||
"editor.indentSize": "tabSize",
|
||||
"editor.tabSize": 2,
|
||||
}
|
||||
@ -36,14 +36,13 @@ enum class InstTag {
|
||||
ExtractEle
|
||||
};
|
||||
|
||||
class Instruction : public Value {
|
||||
class Instruction : public User {
|
||||
public:
|
||||
int ir_seqno = -1;
|
||||
InstTag tag;
|
||||
std::shared_ptr<BasicBlock> parent_bb;
|
||||
std::vector<std::shared_ptr<Value>> operand_list;
|
||||
Instruction(InstTag inst_tag, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Value("", type), tag(inst_tag), parent_bb(parent_bb) {}
|
||||
BasicBlockPtr_t parent_bb;
|
||||
Instruction(InstTag inst_tag, TypePtr_t type, BasicBlockPtr_t parent_bb)
|
||||
: User("", type), tag(inst_tag), parent_bb(parent_bb) {}
|
||||
virtual std::string to_string() override {
|
||||
switch (tag) {
|
||||
case InstTag::Add: return "add";
|
||||
@ -91,8 +90,8 @@ public:
|
||||
InstStore(std::shared_ptr<Value> value, std::shared_ptr<Value> pointer, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Store, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
assert(value);
|
||||
operand_list.push_back(value);
|
||||
operand_list.push_back(pointer);
|
||||
Add_Operand(value);
|
||||
Add_Operand(pointer);
|
||||
}
|
||||
};
|
||||
|
||||
@ -100,7 +99,7 @@ class InstLoad : public Instruction {
|
||||
public:
|
||||
InstLoad(std::shared_ptr<Value> value, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Load, type, parent_bb) {
|
||||
operand_list.push_back(value);
|
||||
Add_Operand(value);
|
||||
}
|
||||
virtual std::string to_IR_string() override {
|
||||
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
||||
@ -118,8 +117,8 @@ public:
|
||||
std::shared_ptr<BasicBlock> parent_bb
|
||||
)
|
||||
: Instruction(inst_tag, val_type, parent_bb) {
|
||||
operand_list.push_back(op1);
|
||||
operand_list.push_back(op2);
|
||||
Add_Operand(op1);
|
||||
Add_Operand(op2);
|
||||
}
|
||||
virtual std::string to_IR_string() override {
|
||||
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
||||
@ -133,7 +132,7 @@ class InstZext : public Instruction {
|
||||
public:
|
||||
InstZext(std::shared_ptr<Value> op, std::shared_ptr<BasicBlock> parent_bb)
|
||||
: Instruction(InstTag::Zext, TypeHelper::TYPE_I32, parent_bb) {
|
||||
operand_list.push_back(op);
|
||||
Add_Operand(op);
|
||||
}
|
||||
virtual std::string to_IR_string() override {
|
||||
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
||||
@ -146,14 +145,14 @@ public:
|
||||
// conditional branch
|
||||
InstBranch(ValuePtr_t cond, BasicBlockPtr_t true_block, BasicBlockPtr_t false_block, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(cond);
|
||||
this->operand_list.push_back(true_block);
|
||||
this->operand_list.push_back(false_block);
|
||||
this->Add_Operand(cond);
|
||||
this->Add_Operand(true_block);
|
||||
this->Add_Operand(false_block);
|
||||
}
|
||||
// unconditional branch
|
||||
InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(target_block);
|
||||
this->Add_Operand(target_block);
|
||||
}
|
||||
};
|
||||
|
||||
@ -161,7 +160,7 @@ class InstReturn : public Instruction {
|
||||
public:
|
||||
InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {
|
||||
this->operand_list.push_back(ret_val);
|
||||
this->Add_Operand(ret_val);
|
||||
}
|
||||
InstReturn(BasicBlockPtr_t parent_bb) : Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {}
|
||||
};
|
||||
@ -171,8 +170,10 @@ class InstCall : public Instruction {
|
||||
public:
|
||||
InstCall(FunctionPtr_t func, const std::vector<ValuePtr_t> &args, BasicBlockPtr_t parent_bb)
|
||||
: Instruction(InstTag::Call, func->get_type()->return_type, parent_bb) {
|
||||
operand_list.push_back(func);
|
||||
operand_list.insert(operand_list.end(), args.begin(), args.end());
|
||||
Add_Operand(func);
|
||||
for (auto arg : args) {
|
||||
Add_Operand(arg);
|
||||
}
|
||||
}
|
||||
virtual std::string to_IR_string() override {
|
||||
if (Type::isType<VoidType>(type)) {
|
||||
@ -203,8 +204,10 @@ public:
|
||||
aim_to = nullptr;
|
||||
}
|
||||
element_type = extract_type(pointer, indices);
|
||||
operand_list.push_back(pointer);
|
||||
operand_list.insert(operand_list.end(), indices.begin(), indices.end());
|
||||
Add_Operand(pointer);
|
||||
for (auto index : indices) {
|
||||
Add_Operand(index);
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string to_IR_string() override {
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
#include <vector>
|
||||
namespace antlrSysY {
|
||||
|
||||
class Type;
|
||||
typedef std::shared_ptr<Type> TypePtr_t;
|
||||
|
||||
class Type {
|
||||
public:
|
||||
enum class TypeTag {
|
||||
@ -82,8 +85,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Type> TypePtr_t;
|
||||
|
||||
class TypeHelper {
|
||||
public:
|
||||
static bool isIntegerType(TypePtr_t type) {
|
||||
|
||||
@ -9,13 +9,29 @@
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
namespace antlrSysY {
|
||||
|
||||
class Value;
|
||||
class BasicBlock;
|
||||
class User;
|
||||
class Function;
|
||||
class Instruction;
|
||||
typedef std::shared_ptr<Value> ValuePtr_t;
|
||||
typedef std::shared_ptr<BasicBlock> BasicBlockPtr_t;
|
||||
typedef std::shared_ptr<Function> FunctionPtr_t;
|
||||
typedef std::shared_ptr<User> UserPtr_t;
|
||||
typedef std::shared_ptr<Instruction> InstructionPtr_t;
|
||||
typedef std::tuple<ValuePtr_t, UserPtr_t, int> UseEdge_t;
|
||||
// Define, User, operand-index
|
||||
|
||||
class Value {
|
||||
public:
|
||||
std::string name;
|
||||
TypePtr_t type;
|
||||
std::list<UseEdge_t> use_list;
|
||||
|
||||
Value(const std::string &name, TypePtr_t type) : name(name), type(type) {}
|
||||
virtual ~Value() = default;
|
||||
|
||||
@ -46,8 +62,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class User : public Value {
|
||||
public:
|
||||
std::vector<ValuePtr_t> operand_list;
|
||||
|
||||
User(const std::string &name, TypePtr_t type) : Value(name, type) {}
|
||||
void Add_Operand(ValuePtr_t op) {
|
||||
operand_list.push_back(op);
|
||||
use_list.push_back({op, std::make_shared<User>(this), operand_list.size()});
|
||||
}
|
||||
};
|
||||
|
||||
class BasicBlock;
|
||||
@ -96,15 +120,19 @@ public:
|
||||
BasicBlockListNode_t itr;
|
||||
std::list<std::shared_ptr<BasicBlock>> successors;
|
||||
std::list<std::shared_ptr<BasicBlock>> predecessors;
|
||||
|
||||
BasicBlockPtr_t idomer;
|
||||
std::list<BasicBlockPtr_t> idomee_list;
|
||||
std::list<BasicBlockPtr_t> domer_list;
|
||||
std::list<BasicBlockPtr_t> dom_frontier;
|
||||
int dom_level;
|
||||
int _dom_helper_index;
|
||||
|
||||
BasicBlock(const std::string &name, std::shared_ptr<Function> parent) : Value(name, TypeHelper::TYPE_LABEL) {
|
||||
this->parent = parent;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Value> ValuePtr_t;
|
||||
typedef std::shared_ptr<BasicBlock> BasicBlockPtr_t;
|
||||
typedef std::shared_ptr<Function> FunctionPtr_t;
|
||||
|
||||
class Constant : public Value {
|
||||
public:
|
||||
Constant(const std::string &name, TypePtr_t type) : Value(name, type) {}
|
||||
|
||||
@ -12,4 +12,10 @@ public:
|
||||
virtual void run(const Module &module) = 0;
|
||||
};
|
||||
|
||||
class PassMem2Reg : public Pass {
|
||||
public:
|
||||
PassMem2Reg() : Pass("mem2reg") {}
|
||||
virtual void run(const Module &module) override;
|
||||
};
|
||||
|
||||
} // namespace antlrSysY
|
||||
106
src/dominance_algo.cpp
Normal file
106
src/dominance_algo.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include "llir.h"
|
||||
#include "visitor.h"
|
||||
#include <bitset>
|
||||
|
||||
namespace antlrSysY {
|
||||
|
||||
static void _bitwise_and(std::vector<bool>& op1, const std::vector<bool>& op2) {
|
||||
for (int i = 0; i < op1.size(); ++ i) {
|
||||
op1[i] = op1[i] & op2[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void _bitwise_set(std::vector<bool>& op1, int l, int r,bool val) {
|
||||
for (int i = l; i < r; ++ i) {
|
||||
op1[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static void _gen_dom_level(BasicBlockPtr_t bb, int level) {
|
||||
bb->dom_level = level;
|
||||
for (auto succ : bb->idomee_list) {
|
||||
_gen_dom_level(succ, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void gen_dominance(FunctionPtr_t func) {
|
||||
// 编译器设计 2E 352 | Engineering A Compiler P479
|
||||
// Note: n \in Dom(n)
|
||||
// Basic iterative idea: Dom(n) = {n} union (intersect Dom(pred(n)))
|
||||
std::vector<std::vector<bool>> domers;
|
||||
std::vector<BasicBlockPtr_t> bb_list;
|
||||
const int N = func->bb_list.size();
|
||||
auto itr = func->bb_list.begin();
|
||||
for (auto basicblock : func->bb_list) {
|
||||
basicblock->idomee_list.clear();
|
||||
basicblock->domer_list.clear();
|
||||
domers.push_back({});
|
||||
domers.back().resize(N, true); // Dom(i) <- N
|
||||
basicblock->_dom_helper_index = bb_list.size();
|
||||
bb_list.push_back(basicblock);
|
||||
}
|
||||
_bitwise_set(domers[0], 1, N, false); // Dom(0) <- {0}
|
||||
|
||||
bool changed = true;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
int i = 0;
|
||||
for (int i = 1; i < N; ++ i) {
|
||||
auto cur_bb = bb_list[i];
|
||||
std::vector<bool> temp(true, N);
|
||||
// temp = {i} union (intersect Dom(j)), j in pred(i)
|
||||
for (auto pred : cur_bb->predecessors) {
|
||||
_bitwise_and(temp, domers[pred->_dom_helper_index]);
|
||||
}
|
||||
temp[i] = true;
|
||||
// if temp != Dom(i)
|
||||
if (!(temp == domers[i])) {
|
||||
domers[i] = temp; // Dom(i) <- temp
|
||||
changed = true; // changed <- true
|
||||
}
|
||||
}
|
||||
}
|
||||
// set each basicblock's domer
|
||||
for (int i = 0; i < N; ++ i) {
|
||||
for (int j = 0; j < N; ++ j) {
|
||||
if (domers[i][j]) {
|
||||
bb_list[i]->domer_list.push_back(bb_list[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// get domees and immediate domer
|
||||
for (int i = 0; i < N; ++ i) {
|
||||
for (auto domer1 : bb_list[i]->domer_list) {
|
||||
if (domer1 == bb_list[i])
|
||||
continue;
|
||||
bool flag = true;
|
||||
// if dom(i)[j] dom dom(i)[k], it cannot be the immediate domer of i
|
||||
for (auto domer2 : bb_list[i]->domer_list) {
|
||||
if (domer2 == bb_list[i] || domer2 == domer1)
|
||||
continue;
|
||||
if (std::find(domer2->domer_list.begin(), domer2->domer_list.end(), domer1) != domer2->domer_list.end()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
bb_list[i]->idomer = domer1;
|
||||
domer1->idomee_list.push_back(bb_list[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_gen_dom_level(bb_list[0], 0);
|
||||
}
|
||||
|
||||
void gen_dominance_frontier(FunctionPtr_t func) {
|
||||
// 编译器设计 2E 368
|
||||
// for all node in CFG: DF(n) <- Empty
|
||||
for (auto bb : func->bb_list) {
|
||||
bb->dom_frontier.clear();
|
||||
}
|
||||
// for all node in CFG:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
14
src/pass_mem2reg.cpp
Normal file
14
src/pass_mem2reg.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "passes.h"
|
||||
#include "llir.h"
|
||||
#include "common.h"
|
||||
|
||||
namespace antlrSysY {
|
||||
|
||||
void PassMem2Reg::run(const Module& module) {
|
||||
for (auto func : module.function_list) {
|
||||
if (func->is_libfunc()) continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user