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.

175 lines
3.9 KiB

#include "Module.h"
#include "Function.h"
#include "IRPrinter.h"
Function::Function(FunctionType *ty, const std::string &name, Module *parent)
: Value(ty, name), parent_(parent), seq_cnt_(0)
{
// num_args_ = ty->getNumParams();
parent->add_function(this);
build_args();
}
Function *Function::create(FunctionType *ty, const std::string &name, Module *parent)
{
return new Function(ty, name, parent);
}
FunctionType *Function::get_function_type() const
{
return static_cast<FunctionType *>(get_type());
}
Type *Function::get_return_type() const
{
return get_function_type()->get_return_type();
}
unsigned Function::get_num_of_args() const
{
return get_function_type()->get_num_of_args();
}
unsigned Function::get_num_basic_blocks() const
{
return basic_blocks_.size();
}
Module *Function::get_parent() const
{
return parent_;
}
void Function::remove(BasicBlock* bb)
{
basic_blocks_.remove(bb);
for (auto pre : bb->get_pre_basic_blocks())
{
pre->remove_succ_basic_block(bb);
}
for (auto succ : bb->get_succ_basic_blocks())
{
succ->remove_pre_basic_block(bb);
}
}
void Function::build_args()
{
auto *func_ty = get_function_type();
unsigned num_args = get_num_of_args();
for (int i = 0; i < num_args; i++) {
arguments_.push_back(new Argument(func_ty->get_param_type(i), "", this, i));
}
}
void Function::add_basic_block(BasicBlock *bb)
{
basic_blocks_.push_back(bb);
}
void Function::set_instr_name()
{
std::map<Value *, int> seq;
for (auto arg : this->get_args())
{
if ( seq.find(arg) == seq.end())
{
auto seq_num = seq.size() + seq_cnt_;
if ( arg->set_name("arg"+std::to_string(seq_num) ))
{
seq.insert( {arg, seq_num} );
}
}
}
for (auto bb : basic_blocks_)
{
if ( seq.find(bb) == seq.end())
{
auto seq_num = seq.size() + seq_cnt_;
if ( bb->set_name("label"+std::to_string(seq_num) ))
{
seq.insert( {bb, seq_num} );
}
}
for (auto instr : bb->get_instructions())
{
if ( !instr->is_void() && seq.find(instr) == seq.end())
{
auto seq_num = seq.size() + seq_cnt_;
if ( instr->set_name("op"+std::to_string(seq_num) ))
{
seq.insert( {instr, seq_num} );
}
}
}
}
seq_cnt_ += seq.size();
}
std::string Function::print()
{
set_instr_name();
std::string func_ir;
if ( this->is_declaration() )
{
func_ir += "declare ";
}
else
{
func_ir += "define ";
}
func_ir += this->get_return_type()->print();
func_ir += " ";
func_ir += print_as_op(this, false);
func_ir += "(";
//print arg
if ( this->is_declaration() )
{
for ( int i = 0 ; i < this->get_num_of_args() ; i++)
{
if(i)
func_ir += ", ";
func_ir += static_cast<FunctionType *>(this->get_type())->get_param_type(i)->print();
}
}
else
{
for ( auto arg = this->arg_begin(); arg != arg_end() ; arg++ )
{
if( arg != this->arg_begin() )
{
func_ir += ", ";
}
func_ir += static_cast<Argument *>(*arg)->print();
}
}
func_ir += ")";
//print bb
if( this->is_declaration() ) {
func_ir += "\n";
}
else
{
func_ir += " {";
func_ir += "\n";
for ( auto bb : this->get_basic_blocks() )
{
func_ir += bb->print();
}
func_ir += "}";
}
return func_ir;
}
std::string Argument::print()
{
std::string arg_ir;
arg_ir += this->get_type()->print();
arg_ir += " %";
arg_ir += this->get_name();
return arg_ir;
}