You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.2 KiB
111 lines
3.2 KiB
12 months ago
|
#ifndef _SYSYF_FUNCTION_H_
|
||
|
#define _SYSYF_FUNCTION_H_
|
||
|
|
||
|
#include <iterator>
|
||
|
#include <list>
|
||
|
#include <cstddef>
|
||
|
#include <map>
|
||
|
#ifdef DEBUG
|
||
|
#include <cassert>
|
||
|
#endif
|
||
|
#include <set>
|
||
|
|
||
|
#include "User.h"
|
||
|
#include "Module.h"
|
||
|
#include "BasicBlock.h"
|
||
|
#include "Type.h"
|
||
|
|
||
|
namespace SysYF
|
||
|
{
|
||
|
namespace IR
|
||
|
{
|
||
|
class Module;
|
||
|
class Argument;
|
||
|
class BasicBlock;
|
||
|
class Type;
|
||
|
class FunctionType;
|
||
|
|
||
|
class Function : public Value
|
||
|
{
|
||
|
public:
|
||
|
~Function() = default;
|
||
|
static Ptr<Function> create(Ptr<FunctionType> ty, const std::string &name, Ptr<Module> parent);
|
||
|
|
||
|
Ptr<FunctionType> get_function_type() const;
|
||
|
|
||
|
Ptr<Type> get_return_type() const;
|
||
|
|
||
|
void add_basic_block(Ptr<BasicBlock> bb);
|
||
|
|
||
|
unsigned get_num_of_args() const;
|
||
|
unsigned get_num_basic_blocks() const;
|
||
|
|
||
|
Ptr<Module> get_parent() const;
|
||
|
|
||
|
PtrList<Argument>::iterator arg_begin() { return arguments_.begin(); }
|
||
|
PtrList<Argument>::iterator arg_end() { return arguments_.end(); }
|
||
|
|
||
|
void remove(Ptr<BasicBlock> bb);
|
||
|
Ptr<BasicBlock> get_entry_block() { return *basic_blocks_.begin(); }
|
||
|
|
||
|
PtrList<BasicBlock> &get_basic_blocks() { return basic_blocks_; }
|
||
|
PtrList<Argument> &get_args() { return arguments_; }
|
||
|
std::vector<PtrSet<Value>> &get_vreg_set(){ return vreg_set_;}
|
||
|
|
||
|
bool is_declaration() { return basic_blocks_.empty(); }
|
||
|
void set_unused_reg_num(std::set<int>& set){unused_reg_num_ = set;}
|
||
|
std::set<int>& get_unused_reg_num(){return unused_reg_num_;}
|
||
|
|
||
|
void set_instr_name();
|
||
|
std::string print();
|
||
|
|
||
|
private:
|
||
|
explicit Function(Ptr<FunctionType> ty, const std::string &name, Ptr<Module> parent);
|
||
|
void init(Ptr<FunctionType> ty, const std::string &name, Ptr<Module> parent);
|
||
|
void build_args();
|
||
|
|
||
|
private:
|
||
|
PtrList<BasicBlock> basic_blocks_; // basic blocks
|
||
|
PtrList<Argument> arguments_; // arguments
|
||
|
std::vector<PtrSet<Value>> vreg_set_;
|
||
|
Ptr<Module> parent_;
|
||
|
std::set<int> unused_reg_num_;
|
||
|
unsigned seq_cnt_;
|
||
|
// unsigned num_args_;
|
||
|
// We don't need this, all value inside function should be unnamed
|
||
|
// std::map<std::string, Ptr<Value>> sym_table_; // Symbol table of args/instructions
|
||
|
};
|
||
|
|
||
|
// Argument of Function, does not contain actual value
|
||
|
class Argument : public Value
|
||
|
{
|
||
|
public:
|
||
|
static Ptr<Argument> create(Ptr<Type> ty, const std::string &name = "", Ptr<Function> f = nullptr,
|
||
|
unsigned arg_no = 0);
|
||
|
~Argument() = default;
|
||
|
|
||
|
inline const Ptr<Function> get_parent() const { return parent_; }
|
||
|
inline Ptr<Function> get_parent() { return parent_; }
|
||
|
|
||
|
/// For example in "void foo(int a, float b)" a is 0 and b is 1.
|
||
|
unsigned get_arg_no() const {
|
||
|
#ifdef DEBUG
|
||
|
assert(parent_ && "can't get number of unparented arg");
|
||
|
#endif
|
||
|
return arg_no_;
|
||
|
}
|
||
|
|
||
|
virtual std::string print() override ;
|
||
|
private:
|
||
|
// Argument constructor.
|
||
|
explicit Argument(Ptr<Type> ty, const std::string &name = "", Ptr<Function> f = nullptr,
|
||
|
unsigned arg_no = 0)
|
||
|
: Value(ty, name), parent_(f), arg_no_(arg_no) {}
|
||
|
Ptr<Function> parent_;
|
||
|
unsigned arg_no_; // argument No.
|
||
|
};
|
||
|
|
||
|
}
|
||
|
}
|
||
|
#endif // _SYSYF_FUNCTION_H_
|