add dominance(partial)

This commit is contained in:
ridethepig 2023-05-17 21:38:28 +08:00
parent 34a5a8ff01
commit 7140d0bf2b
7 changed files with 189 additions and 28 deletions

View File

@ -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,
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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) {}

View File

@ -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
View 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
View 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;
}
}
}