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": [
|
"clangd.arguments": [
|
||||||
"--compile-commands-dir=${workspaceFolder}/build"
|
"--compile-commands-dir=${workspaceFolder}/build",
|
||||||
|
"--header-insertion=never"
|
||||||
],
|
],
|
||||||
"cmake.configureOnOpen": true,
|
"cmake.configureOnOpen": true,
|
||||||
"antlr4.rrd.saveDir": "${workspaceFolder}/build",
|
"antlr4.rrd.saveDir": "${workspaceFolder}/build",
|
||||||
@ -14,5 +15,7 @@
|
|||||||
"[python]": {
|
"[python]": {
|
||||||
"editor.defaultFormatter": "ms-python.autopep8"
|
"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
|
ExtractEle
|
||||||
};
|
};
|
||||||
|
|
||||||
class Instruction : public Value {
|
class Instruction : public User {
|
||||||
public:
|
public:
|
||||||
int ir_seqno = -1;
|
int ir_seqno = -1;
|
||||||
InstTag tag;
|
InstTag tag;
|
||||||
std::shared_ptr<BasicBlock> parent_bb;
|
BasicBlockPtr_t parent_bb;
|
||||||
std::vector<std::shared_ptr<Value>> operand_list;
|
Instruction(InstTag inst_tag, TypePtr_t type, BasicBlockPtr_t parent_bb)
|
||||||
Instruction(InstTag inst_tag, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
: User("", type), tag(inst_tag), parent_bb(parent_bb) {}
|
||||||
: Value("", type), tag(inst_tag), parent_bb(parent_bb) {}
|
|
||||||
virtual std::string to_string() override {
|
virtual std::string to_string() override {
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case InstTag::Add: return "add";
|
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)
|
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) {
|
: Instruction(InstTag::Store, TypeHelper::TYPE_VOID, parent_bb) {
|
||||||
assert(value);
|
assert(value);
|
||||||
operand_list.push_back(value);
|
Add_Operand(value);
|
||||||
operand_list.push_back(pointer);
|
Add_Operand(pointer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ class InstLoad : public Instruction {
|
|||||||
public:
|
public:
|
||||||
InstLoad(std::shared_ptr<Value> value, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
InstLoad(std::shared_ptr<Value> value, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb)
|
||||||
: Instruction(InstTag::Load, type, parent_bb) {
|
: Instruction(InstTag::Load, type, parent_bb) {
|
||||||
operand_list.push_back(value);
|
Add_Operand(value);
|
||||||
}
|
}
|
||||||
virtual std::string to_IR_string() override {
|
virtual std::string to_IR_string() override {
|
||||||
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
||||||
@ -118,8 +117,8 @@ public:
|
|||||||
std::shared_ptr<BasicBlock> parent_bb
|
std::shared_ptr<BasicBlock> parent_bb
|
||||||
)
|
)
|
||||||
: Instruction(inst_tag, val_type, parent_bb) {
|
: Instruction(inst_tag, val_type, parent_bb) {
|
||||||
operand_list.push_back(op1);
|
Add_Operand(op1);
|
||||||
operand_list.push_back(op2);
|
Add_Operand(op2);
|
||||||
}
|
}
|
||||||
virtual std::string to_IR_string() override {
|
virtual std::string to_IR_string() override {
|
||||||
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
||||||
@ -133,7 +132,7 @@ class InstZext : public Instruction {
|
|||||||
public:
|
public:
|
||||||
InstZext(std::shared_ptr<Value> op, std::shared_ptr<BasicBlock> parent_bb)
|
InstZext(std::shared_ptr<Value> op, std::shared_ptr<BasicBlock> parent_bb)
|
||||||
: Instruction(InstTag::Zext, TypeHelper::TYPE_I32, 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 {
|
virtual std::string to_IR_string() override {
|
||||||
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
std::string str = type->to_IR_string() + " %" + std::to_string(ir_seqno);
|
||||||
@ -146,14 +145,14 @@ public:
|
|||||||
// conditional branch
|
// conditional branch
|
||||||
InstBranch(ValuePtr_t cond, BasicBlockPtr_t true_block, BasicBlockPtr_t false_block, BasicBlockPtr_t parent_bb)
|
InstBranch(ValuePtr_t cond, BasicBlockPtr_t true_block, BasicBlockPtr_t false_block, BasicBlockPtr_t parent_bb)
|
||||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, parent_bb) {
|
||||||
this->operand_list.push_back(cond);
|
this->Add_Operand(cond);
|
||||||
this->operand_list.push_back(true_block);
|
this->Add_Operand(true_block);
|
||||||
this->operand_list.push_back(false_block);
|
this->Add_Operand(false_block);
|
||||||
}
|
}
|
||||||
// unconditional branch
|
// unconditional branch
|
||||||
InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb)
|
InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb)
|
||||||
: Instruction(InstTag::Br, TypeHelper::TYPE_VOID, 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:
|
public:
|
||||||
InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb)
|
InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb)
|
||||||
: Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, 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) {}
|
InstReturn(BasicBlockPtr_t parent_bb) : Instruction(InstTag::Ret, TypeHelper::TYPE_VOID, parent_bb) {}
|
||||||
};
|
};
|
||||||
@ -171,8 +170,10 @@ class InstCall : public Instruction {
|
|||||||
public:
|
public:
|
||||||
InstCall(FunctionPtr_t func, const std::vector<ValuePtr_t> &args, BasicBlockPtr_t parent_bb)
|
InstCall(FunctionPtr_t func, const std::vector<ValuePtr_t> &args, BasicBlockPtr_t parent_bb)
|
||||||
: Instruction(InstTag::Call, func->get_type()->return_type, parent_bb) {
|
: Instruction(InstTag::Call, func->get_type()->return_type, parent_bb) {
|
||||||
operand_list.push_back(func);
|
Add_Operand(func);
|
||||||
operand_list.insert(operand_list.end(), args.begin(), args.end());
|
for (auto arg : args) {
|
||||||
|
Add_Operand(arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
virtual std::string to_IR_string() override {
|
virtual std::string to_IR_string() override {
|
||||||
if (Type::isType<VoidType>(type)) {
|
if (Type::isType<VoidType>(type)) {
|
||||||
@ -203,8 +204,10 @@ public:
|
|||||||
aim_to = nullptr;
|
aim_to = nullptr;
|
||||||
}
|
}
|
||||||
element_type = extract_type(pointer, indices);
|
element_type = extract_type(pointer, indices);
|
||||||
operand_list.push_back(pointer);
|
Add_Operand(pointer);
|
||||||
operand_list.insert(operand_list.end(), indices.begin(), indices.end());
|
for (auto index : indices) {
|
||||||
|
Add_Operand(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string to_IR_string() override {
|
virtual std::string to_IR_string() override {
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
namespace antlrSysY {
|
namespace antlrSysY {
|
||||||
|
|
||||||
|
class Type;
|
||||||
|
typedef std::shared_ptr<Type> TypePtr_t;
|
||||||
|
|
||||||
class Type {
|
class Type {
|
||||||
public:
|
public:
|
||||||
enum class TypeTag {
|
enum class TypeTag {
|
||||||
@ -82,8 +85,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Type> TypePtr_t;
|
|
||||||
|
|
||||||
class TypeHelper {
|
class TypeHelper {
|
||||||
public:
|
public:
|
||||||
static bool isIntegerType(TypePtr_t type) {
|
static bool isIntegerType(TypePtr_t type) {
|
||||||
|
|||||||
@ -9,13 +9,29 @@
|
|||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace antlrSysY {
|
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 {
|
class Value {
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string name;
|
||||||
TypePtr_t type;
|
TypePtr_t type;
|
||||||
|
std::list<UseEdge_t> use_list;
|
||||||
|
|
||||||
Value(const std::string &name, TypePtr_t type) : name(name), type(type) {}
|
Value(const std::string &name, TypePtr_t type) : name(name), type(type) {}
|
||||||
virtual ~Value() = default;
|
virtual ~Value() = default;
|
||||||
|
|
||||||
@ -46,8 +62,16 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class User : public Value {
|
class User : public Value {
|
||||||
public:
|
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;
|
class BasicBlock;
|
||||||
@ -96,15 +120,19 @@ public:
|
|||||||
BasicBlockListNode_t itr;
|
BasicBlockListNode_t itr;
|
||||||
std::list<std::shared_ptr<BasicBlock>> successors;
|
std::list<std::shared_ptr<BasicBlock>> successors;
|
||||||
std::list<std::shared_ptr<BasicBlock>> predecessors;
|
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) {
|
BasicBlock(const std::string &name, std::shared_ptr<Function> parent) : Value(name, TypeHelper::TYPE_LABEL) {
|
||||||
this->parent = parent;
|
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 {
|
class Constant : public Value {
|
||||||
public:
|
public:
|
||||||
Constant(const std::string &name, TypePtr_t type) : Value(name, type) {}
|
Constant(const std::string &name, TypePtr_t type) : Value(name, type) {}
|
||||||
|
|||||||
@ -12,4 +12,10 @@ public:
|
|||||||
virtual void run(const Module &module) = 0;
|
virtual void run(const Module &module) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PassMem2Reg : public Pass {
|
||||||
|
public:
|
||||||
|
PassMem2Reg() : Pass("mem2reg") {}
|
||||||
|
virtual void run(const Module &module) override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace antlrSysY
|
} // 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