Skip to content

Commit

Permalink
Change from class for every opcode to base class for simular opcode
Browse files Browse the repository at this point in the history
+ Added opcodes: Sub, Mul, Div, Compare
+ Fixed IrDump for IfInst
  • Loading branch information
techie-mike committed Oct 8, 2023
1 parent d6b2308 commit 03b70de
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 42 deletions.
21 changes: 21 additions & 0 deletions src/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,25 @@ std::string Graph::GetMethodName() const
return name_method_;
}

Inst *Graph::CreateClearInstByOpcode(Opcode opc) {
switch(opc) {

#define CREATER_BY_OPCODE(OPCODE, BASE, ...) \
case Opcode::OPCODE: { \
auto *inst = new BASE(); \
assert(inst->GetOpcode() == Opcode::OPCODE || inst->GetOpcode() == Opcode::NONE); \
inst->SetOpcode(Opcode::OPCODE); \
return inst; \
} \

OPCODE_LIST(CREATER_BY_OPCODE)

#undef CREATE_CREATORS
default: {
std::cerr << "Incorrect opcode!\n";
return nullptr;
}
}
}

}
35 changes: 22 additions & 13 deletions src/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,35 @@ class Graph

void Dump(std::ostream &out);

#define CREATE_CREATORS(OPCODE) \
template <typename... Args> \
auto* Create##OPCODE##Inst(Args&&... args) { \
auto inst = new OPCODE##Inst(std::forward<Args>(args)...); \
inst->SetId(all_inst_.size()); \
all_inst_.push_back(inst); \
return inst; \
#define CREATE_CREATORS(OPCODE, BASE, ...) \
template <typename... Args> \
auto *Create##OPCODE##Inst(Args&&... args) { \
auto inst = new BASE(std::forward<Args>(args)...); \
/* TODO - Bad API, perhaps there is a better way */ \
assert(inst->GetOpcode() == Opcode::OPCODE || inst->GetOpcode() == Opcode::NONE); \
inst->SetOpcode(Opcode::OPCODE); \
inst->SetId(all_inst_.size()); \
all_inst_.push_back(inst); \
return inst; \
}

OPCODE_LIST(CREATE_CREATORS)

#undef CREATE_CREATORS

template <typename T>
auto* CreateInstByIndex(uint32_t index) {
Inst *CreateClearInstByOpcode(Opcode opc);

template <Opcode T>
auto* CreateInstByIndex(id_t index) {
if (!unit_test_mode_) {
std::cerr << "Function only for unit tests\n";
std::abort();
std::exit(1);
}
if (index < GetNumInsts() && GetInstByIndex(index) != nullptr) {
std::cerr << "Inst with index " << index << " already exist\n";
std::exit(1);
}
auto inst = new T();
auto inst = CreateClearInstByOpcode(T);
inst->SetId(index);
if (index >= all_inst_.size()) {
all_inst_.resize(index + 1);
Expand All @@ -56,15 +65,15 @@ class Graph
return inst;
}

Inst *GetInstByIndex(uint32_t index) {
Inst *GetInstByIndex(id_t index) {
return all_inst_.at(index);
}

void SetUnitTestMode() {
unit_test_mode_ = true;
}

uint32_t GetNumInsts() {
size_t GetNumInsts() {
return all_inst_.size();
}

Expand Down
24 changes: 23 additions & 1 deletion src/inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,31 @@ namespace compiler {

void Inst::Dump(std::ostream& out) {
out << std::setw(4) << std::to_string(GetId()) << std::string(".");
out << std::setw(10) << OPCODE_NAME.at(static_cast<size_t>(GetOpcode())) << std::string(" ");
DumpOpcode(out);
DumpInputs(out);
out << std::endl;
}

void Inst::DumpOpcode(std::ostream& out) {
out << std::setw(10) << OpcodeToString(GetOpcode()) << std::string(" ");
}

void CompareInst::DumpOpcode(std::ostream& out) {
out << std::setw(10) << OpcodeToString(GetOpcode()) << std::string(" ") << CcToString(GetCC()) << std::string(" ");
}

void IfInst::DumpOpcode(std::ostream& out) {
out << std::setw(10) << OpcodeToString(GetOpcode()) << std::string(" [T:->v") << GetTrueBranch()->GetId()
<< std::string(" F:->v") << GetFalseBranch()->GetId() << std::string("] ");
}


std::string OpcodeToString(Opcode opc) {
return OPCODE_NAME.at(static_cast<size_t>(opc));
}

std::string CcToString(ConditionCode cc) {
return CC_NAME.at(static_cast<size_t>(cc));
}

}
73 changes: 61 additions & 12 deletions src/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ namespace compiler {
* Full list of instructions, plus and minus show what support in compiler at the moment:
* + Constant
* + Add
* - Mul
* + Sub
* + Mul
* + Div
* + Region
* + Start
* + If
* - Jmp
* - Phi
* - Return
* - Compare
* + Compare
* - Parameter
* ======================================================================================
*/

using id_t = uint32_t;

std::string OpcodeToString(Opcode opc);
std::string CcToString(ConditionCode cc);

class Inst
{
public:
Expand All @@ -48,11 +55,13 @@ class Inst

void Dump(std::ostream& out);

uint32_t GetId() const {
virtual void DumpOpcode(std::ostream& out);

id_t GetId() const {
return id_;
}

void SetId(uint32_t id) {
void SetId(id_t id) {
id_ = id;
}

Expand All @@ -64,16 +73,20 @@ class Inst
type_ = type;
}

Opcode GetOpcode() {
Opcode GetOpcode() const {
return opc_;
}

virtual Inst *GetInput(uint32_t index) {
void SetOpcode(Opcode opc) {
opc_ = opc;
}

virtual Inst *GetInput(id_t index) {
std::cerr << "Inst with opcode " << OPCODE_NAME[static_cast<size_t>(GetOpcode())] << " don't have inputs";
std::abort();
}

virtual void SetInput(uint32_t index, Inst *inst) {
virtual void SetInput(id_t index, Inst *inst) {
std::cerr << "Inst with opcode " << OPCODE_NAME[static_cast<size_t>(GetOpcode())] << " don't have inputs";
std::abort();
}
Expand All @@ -86,7 +99,7 @@ class Inst


private:
uint32_t id_;
id_t id_;
Opcode opc_;
Type type_;
std::list<Inst *> *user_list;
Expand Down Expand Up @@ -116,15 +129,15 @@ class FixedInputs: public Inst
}
};

virtual Inst *GetInput(uint32_t index) override {
virtual Inst *GetInput(id_t index) override {
return inputs_.at(index);
}

const std::array<Inst *, N>& GetInputs() const {
return inputs_;
}

virtual void SetInput(uint32_t index, Inst *inst) override {
virtual void SetInput(id_t index, Inst *inst) override {
assert(index < N);
inputs_.at(index) = inst;
}
Expand Down Expand Up @@ -177,15 +190,15 @@ class DynamicInputs: public Inst
inputs_.erase(it);
}

virtual void SetInput(uint32_t index, Inst *inst) override {
virtual void SetInput(id_t index, Inst *inst) override {
auto it = inputs_.begin();
for (int i = 0; i < index; i++) {
it++;
}
inputs_.insert(it, inst);
}

virtual Inst *GetInput(uint32_t index) override {
virtual Inst *GetInput(id_t index) override {
auto it = inputs_.begin();
for (int i = 0; i < index; i++) {
it++;
Expand Down Expand Up @@ -243,6 +256,18 @@ class AddInst : public FixedInputs<2>

};

class BinaryOperation : public FixedInputs<2>
{
public:
BinaryOperation():
FixedInputs<2>() {}

BinaryOperation(Opcode opc):
FixedInputs<2>(opc) {}

BinaryOperation(Opcode opc, Type type, Inst *input0, Inst *input1):
FixedInputs<2>(opc, type, {{input0, input1}}) {}
};
class ConstantInst : public Inst, public ImmidiateProperty
{
public:
Expand Down Expand Up @@ -301,6 +326,8 @@ class IfInst : public FixedInputs<2>
SetBranch<BranchWay::False>(inst);
}

virtual void DumpOpcode(std::ostream& out) override;

private:
enum class BranchWay {
True = 0,
Expand All @@ -322,4 +349,26 @@ class IfInst : public FixedInputs<2>
std::array<Inst *, 2> branchs_;
};

class CompareInst : public FixedInputs<2>
{
public:
CompareInst():
FixedInputs<2>(Opcode::Compare, Type::BOOL) {};

void SetCC(ConditionCode cc) {
cc_ = cc;
}

ConditionCode GetCC() {
return cc_;
}

virtual void DumpOpcode(std::ostream& out) override;


private:
ConditionCode cc_;

};

}
29 changes: 27 additions & 2 deletions src/ir_constructor.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class IrConstructor {
~IrConstructor() {
delete graph_;
}
template<typename T>
IrConstructor &CreateInst(uint32_t index) {
template<Opcode T>
IrConstructor &CreateInst(id_t index) {
auto inst = graph_->CreateInstByIndex<T>(index);
current_inst_ = inst;
return *this;
Expand All @@ -38,6 +38,31 @@ class IrConstructor {
return *this;
}

IrConstructor &CC(ConditionCode cc) {
assert(current_inst_ != nullptr);

switch(current_inst_->GetOpcode()) {
case Opcode::Compare: {
static_cast<CompareInst *>(current_inst_)->SetCC(cc);
break;
}
default: {
assert(false && ("Should be unreachable!"));
}
}
return *this;
}

IrConstructor &Branches(id_t true_br, id_t false_br) {
assert(current_inst_ != nullptr);
if (current_inst_->GetOpcode() != Opcode::If) {
assert(false && ("Should be unreachable!"));
}
static_cast<IfInst *>(current_inst_)->SetTrueBranch(GetGraph()->GetInstByIndex(true_br));
static_cast<IfInst *>(current_inst_)->SetFalseBranch(GetGraph()->GetInstByIndex(false_br));
return *this;
}

template<typename... Args>
IrConstructor &Inputs(Args ...args) {
for (auto it : {args...}) {
Expand Down
Loading

0 comments on commit 03b70de

Please sign in to comment.