CompilerSysY/include/llir_value.h
2023-05-16 00:41:02 +08:00

191 lines
5.4 KiB
C++

#pragma once
#include "3rdparty/easylogging++.h"
#include "common.h"
#include "llir_type.h"
#include <cassert>
#include <list>
#include <memory>
#include <shared_mutex>
#include <string>
#include <vector>
namespace antlrSysY {
class Value {
public:
std::string name;
TypePtr_t type;
Value(const std::string &name, TypePtr_t type) : name(name), type(type) {}
virtual ~Value() = default;
template <typename TT>
static bool isValueType(std::shared_ptr<Value> ptr) {
if (ptr.get()) {
// auto &r = *ptr.get();
// return typeid(r) == typeid(TT);
return dynamic_cast<TT *>(ptr.get()) != nullptr;
}
LOG(WARNING) << "Comparing with nullptr";
assert(0);
return false;
}
// it is caller's duty to check before use `asType`
template <typename TT>
static std::shared_ptr<TT> asValueType(std::shared_ptr<Value> ptr) {
return std::dynamic_pointer_cast<TT>(ptr);
}
virtual std::string to_string() {
return name + ": " + type->to_string();
}
virtual std::string to_IR_string() {
panic("No applicable for IR gen");
}
};
class User : public Value {
public:
};
class BasicBlock;
class Instruction;
class FParam : public Value {
public:
int ir_seqno = -1;
FParam(const std::string &name, TypePtr_t type) : Value(name, type) {}
virtual std::string to_string() override {
return type->to_string() + " @" + name + " %" + std::to_string(ir_seqno);
}
virtual std::string to_IR_string() override {
return type->to_IR_string() + " %" + std::to_string(ir_seqno);
}
};
typedef std::list<std::shared_ptr<antlrSysY::BasicBlock>>::iterator BasicBlockListNode_t;
class Function : public Value {
public:
std::vector<std::shared_ptr<FParam>> fparam_list;
std::list<std::shared_ptr<BasicBlock>> bb_list;
// we use empty basic_block to represent lib function
Function(const std::string &name, TypePtr_t ret_type) : Value(name, std::make_shared<FunctionType>(ret_type)) {}
std::shared_ptr<FunctionType> get_type() {
return std::dynamic_pointer_cast<FunctionType>(type);
}
bool is_libfunc() {
return bb_list.size() == 0;
}
virtual std::string to_string() override {
std::string params_str;
for (auto fparam : fparam_list) {
params_str += fparam->to_string() + ",";
}
return name + "(" + params_str + ") -> " + type->to_string();
}
};
class BasicBlock : public Value {
public:
int ir_seqno = -1;
std::vector<std::shared_ptr<Instruction>> inst_list;
std::shared_ptr<Function> parent;
BasicBlockListNode_t itr;
std::vector<std::shared_ptr<BasicBlock>> successors;
std::vector<std::shared_ptr<BasicBlock>> predecessors;
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) {}
};
class ConstantInt : public Constant {
public:
int value;
ConstantInt(const std::string &name, int value) : Constant(name, TypeHelper::TYPE_I32), value(value) {}
static std::shared_ptr<ConstantInt> make_shared(int value) {
return std::make_shared<ConstantInt>("", value);
}
virtual std::string to_string() override {
std::string str = type->to_string() + " " + std::to_string(value);
return str;
}
virtual std::string to_IR_string() override {
return type->to_IR_string() + " " + std::to_string(value);
}
};
class ConstantArr : public Constant {
public:
std::vector<ValuePtr_t> value_list;
ConstantArr(const std::string &name, const std::vector<ValuePtr_t> &value_list, std::shared_ptr<ArrayType> type)
: Constant(name, type), value_list(value_list) {}
int real_size() const {
return std::dynamic_pointer_cast<ArrayType>(type)->element_count;
}
static std::shared_ptr<ConstantArr> make_shared(
const std::string &name,
const std::vector<ValuePtr_t> &value_list,
std::shared_ptr<ArrayType> type
) {
return std::make_shared<ConstantArr>(name, value_list, type);
}
virtual std::string to_string() override {
std::string str = "{";
for (auto elem : value_list) {
if (elem)
str += elem->to_string() + ", ";
else
str += "{...}, ";
}
if (real_size() > value_list.size()) {
str += std::to_string(real_size() - value_list.size()) + " zeros";
}
str += "}";
return str;
}
};
typedef std::shared_ptr<Constant> ConstantPtr_t;
// emmm, actually it is more of a Instruction type
class GlobalVar : public Value {
public:
ConstantPtr_t init_value;
bool is_const;
GlobalVar(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const)
: Value(name, PointerType::make_shared(type)), init_value(init_value), is_const(is_const) {}
static std::shared_ptr<GlobalVar> make_shared(
const std::string &name,
TypePtr_t type,
ConstantPtr_t init_value,
bool is_const
) {
return std::make_shared<GlobalVar>(name, type, init_value, is_const);
}
virtual std::string to_IR_string() override {
std::string str = type->to_IR_string() + " @" + name;
return str;
}
};
std::shared_ptr<ConstantArr> gen_arr_hierarchy(
const std::shared_ptr<ArrayType> array_type,
const std::vector<ValuePtr_t> &const_array,
int base,
int length
);
} // namespace antlrSysY