diff options
Diffstat (limited to 'ir_suif.cc')
-rw-r--r-- | ir_suif.cc | 1438 |
1 files changed, 0 insertions, 1438 deletions
diff --git a/ir_suif.cc b/ir_suif.cc deleted file mode 100644 index a0ea357..0000000 --- a/ir_suif.cc +++ /dev/null @@ -1,1438 +0,0 @@ -/***************************************************************************** - Copyright (C) 2009-2011 University of Utah - All Rights Reserved. - - Purpose: - CHiLL's SUIF interface. - - Notes: - Array supports mixed pointer and array type in a single declaration. - - History: - 02/23/2009 Created by Chun Chen. -*****************************************************************************/ - -#include <typeinfo> -#include <useful.h> -#include "ir_suif.hh" -#include "ir_suif_utils.hh" -#include "chill_error.hh" - -// ---------------------------------------------------------------------------- -// Class: IR_suifScalarSymbol -// ---------------------------------------------------------------------------- - -std::string IR_suifScalarSymbol::name() const { - return vs_->name(); -} - - -int IR_suifScalarSymbol::size() const { - return vs_->type()->size(); -} - - -bool IR_suifScalarSymbol::operator==(const IR_Symbol &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_suifScalarSymbol *l_that = static_cast<const IR_suifScalarSymbol *>(&that); - return this->vs_ == l_that->vs_; -} - -IR_Symbol *IR_suifScalarSymbol::clone() const { - return new IR_suifScalarSymbol(ir_, vs_); -} - -// ---------------------------------------------------------------------------- -// Class: IR_suifArraySymbol -// ---------------------------------------------------------------------------- - -std::string IR_suifArraySymbol::name() const { - return vs_->name(); -} - - -int IR_suifArraySymbol::elem_size() const { - type_node *tn = vs_->type(); - if (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - - while (tn->is_array()) - tn = static_cast<array_type *>(tn)->elem_type(); - - return tn->size(); -} - - -int IR_suifArraySymbol::n_dim() const { - type_node *tn = vs_->type(); - if (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - - int n = 0; - while (true) { - if (tn->is_array()) { - n++; - tn = static_cast<array_type *>(tn)->elem_type(); - } - else if (tn->is_ptr()) { - n++; - tn = static_cast<ptr_type *>(tn)->ref_type(); - } - else - break; - } - - return n - indirect_; -} - - -omega::CG_outputRepr *IR_suifArraySymbol::size(int dim) const { - type_node *tn = vs_->type(); - if (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - - for (int i = 0; i < dim; i++) { - if (tn->is_array()) - tn = static_cast<array_type *>(tn)->elem_type(); - else if (tn->is_ptr()) - tn = static_cast<ptr_type *>(tn)->ref_type(); - else - throw ir_error("array parsing error"); - } - if (tn->is_ptr()) - return new omega::CG_suifRepr(operand()); - else if (!tn->is_array()) - throw ir_error("array parsing error"); - - array_bound ub = static_cast<array_type *>(tn)->upper_bound(); - int c = 1; - omega::CG_outputRepr *ub_repr = NULL; - if (ub.is_constant()) - c += ub.constant(); - else if (ub.is_variable()) { - var_sym *vs = ub.variable(); - - if (static_cast<const IR_suifCode *>(ir_)->init_code_ != NULL) { - tree_node_list *tnl = static_cast<omega::CG_suifRepr *>(static_cast<const IR_suifCode *>(ir_)->init_code_)->GetCode(); - tree_node_list_iter iter(tnl); - while(!iter.is_empty()) { - tree_node *tn = iter.step(); - if (tn->is_instr()) { - instruction *ins = static_cast<tree_instr *>(tn)->instr(); - operand dst = ins->dst_op(); - if (dst.is_symbol() && dst.symbol() == vs) { - operand op; - if (ins->opcode() == io_cpy) - op = ins->src_op(0).clone(); - else - op = operand(ins->clone()); - - ub_repr = new omega::CG_suifRepr(op); - break; - } - } - } - } - if (ub_repr == NULL) - ub_repr = new omega::CG_suifRepr(operand(vs)); - } - else - throw ir_error("array parsing error"); - - array_bound lb = static_cast<array_type *>(tn)->lower_bound(); - omega::CG_outputRepr *lb_repr = NULL; - if (lb.is_constant()) - c -= lb.constant(); - else if (lb.is_variable()) { - var_sym *vs = ub.variable(); - - tree_node_list *tnl = static_cast<omega::CG_suifRepr *>(static_cast<const IR_suifCode *>(ir_)->init_code_)->GetCode(); - tree_node_list_iter iter(tnl); - while(!iter.is_empty()) { - tree_node *tn = iter.step(); - if (tn->is_instr()) { - instruction *ins = static_cast<tree_instr *>(tn)->instr(); - operand dst = ins->dst_op(); - if (dst.is_symbol() && dst.symbol() == vs) { - operand op; - if (ins->opcode() == io_cpy) - op = ins->src_op(0).clone(); - else - op = operand(ins->clone()); - - lb_repr = new omega::CG_suifRepr(op); - break; - } - } - } - if (lb_repr == NULL) - lb_repr = new omega::CG_suifRepr(operand(vs)); - } - else - throw ir_error("array parsing error"); - - omega::CG_outputRepr *repr = ir_->builder()->CreateMinus(ub_repr, lb_repr); - if (c != 0) - repr = ir_->builder()->CreatePlus(repr, ir_->builder()->CreateInt(c)); - - return repr; -} - - -IR_ARRAY_LAYOUT_TYPE IR_suifArraySymbol::layout_type() const { - if (static_cast<const IR_suifCode *>(ir_)->is_fortran_) - return IR_ARRAY_LAYOUT_COLUMN_MAJOR; - else - return IR_ARRAY_LAYOUT_ROW_MAJOR; -} - - -bool IR_suifArraySymbol::operator==(const IR_Symbol &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_suifArraySymbol *l_that = static_cast<const IR_suifArraySymbol *>(&that); - return this->vs_ == l_that->vs_ && this->offset_ == l_that->offset_; -} - - -IR_Symbol *IR_suifArraySymbol::clone() const { - return new IR_suifArraySymbol(ir_, vs_, indirect_, offset_); -} - -// ---------------------------------------------------------------------------- -// Class: IR_suifConstantRef -// ---------------------------------------------------------------------------- - -bool IR_suifConstantRef::operator==(const IR_Ref &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_suifConstantRef *l_that = static_cast<const IR_suifConstantRef *>(&that); - - if (this->type_ != l_that->type_) - return false; - - if (this->type_ == IR_CONSTANT_INT) - return this->i_ == l_that->i_; - else - return this->f_ == l_that->f_; -} - - -omega::CG_outputRepr *IR_suifConstantRef::convert() { - if (type_ == IR_CONSTANT_INT) { - omega::CG_suifRepr *result = new omega::CG_suifRepr(operand(static_cast<int>(i_), type_s32)); - delete this; - return result; - } - else - throw ir_error("constant type not supported"); -} - - -IR_Ref *IR_suifConstantRef::clone() const { - if (type_ == IR_CONSTANT_INT) - return new IR_suifConstantRef(ir_, i_); - else if (type_ == IR_CONSTANT_FLOAT) - return new IR_suifConstantRef(ir_, f_); - else - throw ir_error("constant type not supported"); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_suifScalarRef -// ---------------------------------------------------------------------------- - -bool IR_suifScalarRef::is_write() const { - if (ins_pos_ != NULL && op_pos_ == -1) - return true; - else - return false; -} - - -IR_ScalarSymbol *IR_suifScalarRef::symbol() const { - return new IR_suifScalarSymbol(ir_, vs_); -} - - -bool IR_suifScalarRef::operator==(const IR_Ref &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_suifScalarRef *l_that = static_cast<const IR_suifScalarRef *>(&that); - - if (this->ins_pos_ == NULL) - return this->vs_ == l_that->vs_; - else - return this->ins_pos_ == l_that->ins_pos_ && this->op_pos_ == l_that->op_pos_; -} - - -omega::CG_outputRepr *IR_suifScalarRef::convert() { - omega::CG_suifRepr *result = new omega::CG_suifRepr(operand(vs_)); - delete this; - return result; -} - - -IR_Ref * IR_suifScalarRef::clone() const { - if (ins_pos_ == NULL) - return new IR_suifScalarRef(ir_, vs_); - else - return new IR_suifScalarRef(ir_, ins_pos_, op_pos_); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_suifArrayRef -// ---------------------------------------------------------------------------- - -bool IR_suifArrayRef::is_write() const { - return ::is_lhs(const_cast<in_array *>(ia_)); -} - - -omega::CG_outputRepr *IR_suifArrayRef::index(int dim) const { - operand op = find_array_index(ia_, n_dim(), dim, static_cast<const IR_suifCode *>(ir_)->is_fortran_); - return new omega::CG_suifRepr(op.clone()); -} - - -IR_ArraySymbol *IR_suifArrayRef::symbol() const { - in_array *current = ia_; - - // find the indirectness of the symbol, i.e., if it is (**A)[i,j] - int indirect = 0; - if (!static_cast<const IR_suifCode *>(ir_)->is_fortran_) { - operand op = ia_->base_op(); - while (op.is_instr()) { - instruction *ins = op.instr(); - if (ins->opcode() == io_lod) { - indirect++; - op = ins->src_op(0); - } - else - break; - } - if (op.is_symbol()) - indirect++; - } - - while (true) { - operand op = current->base_op(); - if (op.is_symbol()) { - return new IR_suifArraySymbol(ir_, op.symbol(), indirect); - } - else if (op.is_instr()) { - instruction *ins = op.instr(); - if (ins->opcode() == io_ldc) { - immed value = static_cast<in_ldc *>(ins)->value(); - if (value.is_symbol()) { - sym_node *the_sym = value.symbol(); - if (the_sym->is_var()) - return new IR_suifArraySymbol(ir_, static_cast<var_sym *>(the_sym), indirect); - else - break; - } - else - break; - } - else if (ins->opcode() == io_cvt) { - operand op = static_cast<in_rrr *>(ins)->src_op(); - if (op.is_symbol()) { - return new IR_suifArraySymbol(ir_, op.symbol(), indirect); - } - else if (op.is_instr()) { - instruction *ins = op.instr(); - if (ins->opcode() == io_lod) { - operand op = static_cast<in_rrr *>(ins)->src_op(); - if (op.is_symbol()) { - return new IR_suifArraySymbol(ir_, op.symbol(), indirect); - } - else if (op.is_instr()) { - instruction *ins = op.instr(); - if (ins->opcode() == io_array) { - current = static_cast<in_array *>(ins); - continue; - } - else if (ins->opcode() == io_add) { - operand op1 = ins->src_op(0); - operand op2 = ins->src_op(1); - if (!op1.is_symbol() || !op2.is_immed()) - throw ir_error("can't recognize array reference format"); - immed im = op2.immediate(); - if (!im.is_integer()) - throw ir_error("can't recognize array reference format"); - return new IR_suifArraySymbol(ir_, op1.symbol(), indirect, im.integer()); - } - else - break; - } - else - break; - } - else - break; - } - else - break; - } - else { - while (ins->opcode() == io_lod) { - operand op = ins->src_op(0); - if (op.is_instr()) - ins = op.instr(); - else if (op.is_symbol()) - return new IR_suifArraySymbol(ir_, op.symbol(), indirect); - else - break; - } - break; - } - } - else - break; - } - - fprintf(stderr, "Warning: null array symbol found, dependence graph bloated!\n"); - - return new IR_suifArraySymbol(ir_, NULL); -} - - -bool IR_suifArrayRef::operator==(const IR_Ref &that) const { - if (typeid(*this) != typeid(that)) - return false; - - const IR_suifArrayRef *l_that = static_cast<const IR_suifArrayRef *>(&that); - - return this->ia_ == l_that ->ia_; -} - - -omega::CG_outputRepr *IR_suifArrayRef::convert() { - omega::CG_suifRepr *result = new omega::CG_suifRepr(operand(this->ia_->clone())); - delete this; - return result; -} - - -IR_Ref *IR_suifArrayRef::clone() const { - return new IR_suifArrayRef(ir_, ia_); -} - - - -// ---------------------------------------------------------------------------- -// Class: IR_suifLoop -// ---------------------------------------------------------------------------- - -IR_ScalarSymbol *IR_suifLoop::index() const { - var_sym *vs = tf_->index(); - return new IR_suifScalarSymbol(ir_, vs); -} - -omega::CG_outputRepr *IR_suifLoop::lower_bound() const { - tree_node_list *tnl = tf_->lb_list(); - tree_node_list_iter iter(tnl); - if (iter.is_empty()) - return new omega::CG_suifRepr(operand()); - tree_node *tn = iter.step(); - if (!iter.is_empty()) - throw ir_error("cannot handle lower bound"); - if (tn->kind() != TREE_INSTR) - throw ir_error("cannot handle lower bound"); - instruction *ins = static_cast<tree_instr *>(tn)->instr(); - return new omega::CG_suifRepr(operand(ins)); -} - -omega::CG_outputRepr *IR_suifLoop::upper_bound() const { - tree_node_list *tnl = tf_->ub_list(); - tree_node_list_iter iter(tnl); - if (iter.is_empty()) - return new omega::CG_suifRepr(operand()); - tree_node *tn = iter.step(); - if (!iter.is_empty()) - throw ir_error("cannot handle lower bound"); - if (tn->kind() != TREE_INSTR) - throw ir_error("cannot handle lower bound"); - instruction *ins = static_cast<tree_instr *>(tn)->instr(); - return new omega::CG_suifRepr(operand(ins)); -} - -IR_CONDITION_TYPE IR_suifLoop::stop_cond() const { - if (tf_->test() == FOR_SLT || tf_->test() == FOR_ULT) - return IR_COND_LT; - else if (tf_->test() == FOR_SLTE || tf_->test() == FOR_ULTE) - return IR_COND_LE; - else if (tf_->test() == FOR_SGT || tf_->test() == FOR_UGT) - return IR_COND_GT; - else if (tf_->test() == FOR_SGTE || tf_->test() == FOR_UGTE) - return IR_COND_GE; - else - throw ir_error("loop stop condition unsupported"); -} - -IR_Block *IR_suifLoop::body() const { - tree_node_list *tnl = tf_->body(); - return new IR_suifBlock(ir_, tnl); -} - -int IR_suifLoop::step_size() const { - operand op = tf_->step_op(); - if (!op.is_null()) { - if (op.is_immed()) { - immed im = op.immediate(); - if (im.is_integer()) - return im.integer(); - else - throw ir_error("cannot handle non-integer stride"); - } - else - throw ir_error("cannot handle non-constant stride"); - } - else - return 1; -} - - -IR_Block *IR_suifLoop::convert() { - const IR_Code *ir = ir_; - tree_node_list *tnl = tf_->parent(); - tree_node_list_e *start, *end; - start = end = tf_->list_e(); - delete this; - return new IR_suifBlock(ir, tnl, start, end); -} - - -IR_Control *IR_suifLoop::clone() const { - return new IR_suifLoop(ir_, tf_); -} - -// ---------------------------------------------------------------------------- -// Class: IR_suifBlock -// ---------------------------------------------------------------------------- - -omega::CG_outputRepr *IR_suifBlock::extract() const { - tree_node_list *tnl = new tree_node_list; - tree_node_list_iter iter(tnl_); - while (!iter.is_empty()) { - tree_node *tn = iter.peek(); - if (tn->list_e() == start_) - break; - tn = iter.step(); - } - - while (!iter.is_empty()) { - tree_node *tn = iter.step(); - tnl->append(tn->clone()); - if (tn->list_e() == end_) - break; - } - - return new omega::CG_suifRepr(tnl); -} - -IR_Control *IR_suifBlock::clone() const { - return new IR_suifBlock(ir_, tnl_, start_, end_); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_suifIf -// ---------------------------------------------------------------------------- -omega::CG_outputRepr *IR_suifIf::condition() const { - tree_node_list *tnl = ti_->header(); - tree_node_list_iter iter(tnl); - if (iter.is_empty()) - throw ir_error("unrecognized if structure"); - tree_node *tn = iter.step(); - if (!iter.is_empty()) - throw ir_error("unrecognized if structure"); - if (!tn->is_instr()) - throw ir_error("unrecognized if structure"); - instruction *ins = static_cast<tree_instr *>(tn)->instr(); - if (!ins->opcode() == io_bfalse) - throw ir_error("unrecognized if structure"); - operand op = ins->src_op(0); - return new omega::CG_suifRepr(op); -} - -IR_Block *IR_suifIf::then_body() const { - tree_node_list *tnl = ti_->then_part(); - if (tnl == NULL) - return NULL; - tree_node_list_iter iter(tnl); - if (iter.is_empty()) - return NULL; - - return new IR_suifBlock(ir_, tnl); -} - -IR_Block *IR_suifIf::else_body() const { - tree_node_list *tnl = ti_->else_part(); - if (tnl == NULL) - return NULL; - tree_node_list_iter iter(tnl); - if (iter.is_empty()) - return NULL; - - return new IR_suifBlock(ir_, tnl); -} - - -IR_Block *IR_suifIf::convert() { - const IR_Code *ir = ir_; - tree_node_list *tnl = ti_->parent(); - tree_node_list_e *start, *end; - start = end = ti_->list_e(); - delete this; - return new IR_suifBlock(ir, tnl, start, end); -} - - -IR_Control *IR_suifIf::clone() const { - return new IR_suifIf(ir_, ti_); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_suifCode_Global_Init -// ---------------------------------------------------------------------------- - -IR_suifCode_Global_Init *IR_suifCode_Global_Init::pinstance = NULL; - - -IR_suifCode_Global_Init *IR_suifCode_Global_Init::Instance () { - if (pinstance == NULL) - pinstance = new IR_suifCode_Global_Init; - return pinstance; -} - - -IR_suifCode_Global_Init::IR_suifCode_Global_Init() { - LIBRARY(useful, init_useful, exit_useful); - LIBRARY(annotes, init_annotes, exit_annotes); - - int argc = 1; - char *argv[1]; - argv[0] = "chill"; - init_suif(argc, argv); -} - - -// ---------------------------------------------------------------------------- -// Class: IR_suifCode_Global_Cleanup -// ---------------------------------------------------------------------------- - -IR_suifCode_Global_Cleanup::~IR_suifCode_Global_Cleanup() { - delete IR_suifCode_Global_Init::Instance(); - exit_suif1(); -} - - -namespace { - IR_suifCode_Global_Cleanup suifcode_global_cleanup_instance; -} - -// ---------------------------------------------------------------------------- -// Class: IR_suifCode -// ---------------------------------------------------------------------------- - -IR_suifCode::IR_suifCode(const char *filename, int proc_num): IR_Code() { - IR_suifCode_Global_Init::Instance(); - - std::string new_filename(filename); - int pos = new_filename.find_last_of('.'); - new_filename = new_filename.substr(0, pos) + ".lxf"; - fileset->add_file(const_cast<char *>(filename), const_cast<char *>(new_filename.c_str())); - fileset->reset_iter(); - fse_ = fileset->next_file(); - fse_->reset_proc_iter(); - - int cur_proc = 0; - while ((psym_ = fse_->next_proc()) && cur_proc < proc_num) - ++cur_proc; - if (cur_proc != proc_num) { - throw ir_error("procedure number cannot be found"); - } - - if (psym_->src_lang() == src_fortran) - is_fortran_ = true; - else - is_fortran_ = false; - - if (!psym_->is_in_memory()) - psym_->read_proc(TRUE, is_fortran_); - push_clue(psym_->block()); - - symtab_ = psym_->block()->proc_syms(); - ocg_ = new omega::CG_suifBuilder(symtab_); -} - - -IR_suifCode::~IR_suifCode() { - tree_node_list *tnl = psym_->block()->body(); - - if (init_code_ != NULL) - tnl->insert_before(static_cast<omega::CG_suifRepr *>(init_code_)->GetCode(), tnl->head()); - if (cleanup_code_ != NULL) - tnl->insert_after(static_cast<omega::CG_suifRepr *>(cleanup_code_)->GetCode(), tnl->tail()); - - pop_clue(psym_->block()); - if (!psym_->is_written()) - psym_->write_proc(fse_); - psym_->flush_proc(); -} - - -IR_ScalarSymbol *IR_suifCode::CreateScalarSymbol(const IR_Symbol *sym, int) { - if (typeid(*sym) == typeid(IR_suifScalarSymbol)) { - type_node *tn = static_cast<const IR_suifScalarSymbol *>(sym)->vs_->type(); - while (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - var_sym *vs = symtab_->new_unique_var(tn); - return new IR_suifScalarSymbol(this, vs); - } - else if (typeid(*sym) == typeid(IR_suifArraySymbol)) { - type_node *tn = static_cast<const IR_suifArraySymbol *>(sym)->vs_->type(); - while (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - while (tn->is_array() || tn->is_ptr()) { - if (tn->is_array()) - tn = static_cast<array_type *>(tn)->elem_type(); - else if (tn->is_ptr()) - tn = static_cast<ptr_type *>(tn)->ref_type(); - } - while (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - var_sym *vs = symtab_->new_unique_var(tn); - return new IR_suifScalarSymbol(this, vs); - } - else - throw std::bad_typeid(); -} - - -IR_ArraySymbol *IR_suifCode::CreateArraySymbol(const IR_Symbol *sym, std::vector<omega::CG_outputRepr *> &size, int) { - type_node *tn; - - if (typeid(*sym) == typeid(IR_suifScalarSymbol)) { - tn = static_cast<const IR_suifScalarSymbol *>(sym)->vs_->type(); - } - else if (typeid(*sym) == typeid(IR_suifArraySymbol)) { - tn = static_cast<const IR_suifArraySymbol *>(sym)->vs_->type(); - if (tn->is_modifier()) - tn = static_cast<modifier_type *>(tn)->base(); - while (tn->is_array() || tn->is_ptr()) { - if (tn->is_array()) - tn = static_cast<array_type *>(tn)->elem_type(); - else if (tn->is_ptr()) - tn = static_cast<ptr_type *>(tn)->ref_type(); - } - } - else - throw std::bad_typeid(); - - if (is_fortran_) - for (int i = 0; i < size.size(); i++) { - var_sym *temporary = symtab_->new_unique_var(type_s32); - init_code_ = ocg_->StmtListAppend(init_code_, ocg_->CreateAssignment(0, new omega::CG_suifRepr(operand(temporary)), size[i])); - - tn = new array_type(tn, array_bound(1), array_bound(temporary)); - symtab_->add_type(tn); - } - else - for (int i = size.size()-1; i >= 0; i--) { - var_sym *temporary = symtab_->new_unique_var(type_s32); - init_code_ = ocg_->StmtListAppend(init_code_, ocg_->CreateAssignment(0, new omega::CG_suifRepr(operand(temporary)), size[i])); - - tn = new array_type(tn, array_bound(1), array_bound(temporary)); - symtab_->add_type(tn); - } - - static int suif_array_counter = 1; - std::string s = std::string("_P") + omega::to_string(suif_array_counter++); - var_sym *vs = new var_sym(tn, const_cast<char *>(s.c_str())); - vs->add_to_table(symtab_); - - return new IR_suifArraySymbol(this, vs); -} - - -IR_ScalarRef *IR_suifCode::CreateScalarRef(const IR_ScalarSymbol *sym) { - return new IR_suifScalarRef(this, static_cast<const IR_suifScalarSymbol *>(sym)->vs_); -} - - -IR_ArrayRef *IR_suifCode::CreateArrayRef(const IR_ArraySymbol *sym, std::vector<omega::CG_outputRepr *> &index) { - if (sym->n_dim() != index.size()) - throw std::invalid_argument("incorrect array symbol dimensionality"); - - const IR_suifArraySymbol *l_sym = static_cast<const IR_suifArraySymbol *>(sym); - - var_sym *vs = l_sym->vs_; - type_node *tn1 = vs->type(); - if (tn1->is_modifier()) - tn1 = static_cast<modifier_type *>(tn1)->base(); - - type_node *tn2 = tn1; - while (tn2->is_array() || tn2->is_ptr()) { - if (tn2->is_array()) - tn2 = static_cast<array_type *>(tn2)->elem_type(); - else if (tn2->is_ptr()) - tn2 = static_cast<ptr_type *>(tn2)->ref_type(); - } - - instruction *base_ins; - if (tn1->is_ptr()) { - base_symtab *cur_symtab; - - cur_symtab = symtab_; - type_node *found_array_tn = NULL; - while (cur_symtab != NULL) { - type_node_list_iter iter(cur_symtab->types()); - while (!iter.is_empty()) { - type_node *tn = iter.step(); - if (!tn->is_array()) - continue; - if (static_cast<array_type *>(tn)->elem_type() == static_cast<ptr_type *>(tn1)->ref_type()) { - array_bound b = static_cast<array_type *>(tn)->upper_bound(); - if (b.is_unknown()) { - found_array_tn = tn; - break; - } - } - } - if (found_array_tn == NULL) - cur_symtab = cur_symtab->parent(); - else - break; - } - - cur_symtab = symtab_; - type_node *found_ptr_array_tn = NULL; - while (cur_symtab != NULL) { - type_node_list_iter iter(cur_symtab->types()); - while (!iter.is_empty()) { - type_node *tn = iter.step(); - if (!tn->is_ptr()) - continue; - if (static_cast<ptr_type *>(tn)->ref_type() == found_array_tn) { - found_ptr_array_tn = tn; - break; - } - } - if (found_ptr_array_tn == NULL) - cur_symtab = cur_symtab->parent(); - else - break; - } - - if (found_ptr_array_tn == NULL) - throw ir_error("can't find the type for the to-be-created array"); - base_ins = new in_rrr(io_cvt, found_ptr_array_tn, operand(), operand(vs)); - } - else { - base_ins = new in_ldc(tn1->ptr_to(), operand(), immed(vs)); - } - - in_array *ia = new in_array(tn2->ptr_to(), operand(), operand(base_ins), tn2->size(), l_sym->n_dim()); - - for (int i = 0; i < index.size(); i++) { - int t; - if (is_fortran_) - t = index.size() - i - 1; - else - t = i; - - omega::CG_suifRepr *bound = static_cast<omega::CG_suifRepr *>(l_sym->size(t)); - ia->set_bound(t, bound->GetExpression()); - delete bound; - omega::CG_suifRepr *idx = static_cast<omega::CG_suifRepr *>(index[i]); - ia->set_index(t, idx->GetExpression()); - delete idx; - } - - return new IR_suifArrayRef(this, ia); -} - - -std::vector<IR_ArrayRef *> IR_suifCode::FindArrayRef(const omega::CG_outputRepr *repr) const { - std::vector<IR_ArrayRef *> arrays; - - tree_node_list *tnl = static_cast<const omega::CG_suifRepr *>(repr)->GetCode(); - if (tnl != NULL) { - tree_node_list_iter iter(tnl); - while (!iter.is_empty()) { - tree_node *tn = iter.step(); - switch (tn->kind()) { - case TREE_FOR: { - tree_for *tnf = static_cast<tree_for *>(tn); - omega::CG_suifRepr *r = new omega::CG_suifRepr(tnf->body()); - std::vector<IR_ArrayRef *> a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - break; - } - case TREE_IF: { - tree_if *tni = static_cast<tree_if *>(tn); - omega::CG_suifRepr *r = new omega::CG_suifRepr(tni->header()); - std::vector<IR_ArrayRef *> a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - r = new omega::CG_suifRepr(tni->then_part()); - a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - r = new omega::CG_suifRepr(tni->else_part()); - a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - break; - } - case TREE_BLOCK: { - omega::CG_suifRepr *r = new omega::CG_suifRepr(static_cast<tree_block *>(tn)->body()); - std::vector<IR_ArrayRef *> a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - break; - } - case TREE_INSTR: { - omega::CG_suifRepr *r = new omega::CG_suifRepr(operand(static_cast<tree_instr *>(tn)->instr())); - std::vector<IR_ArrayRef *> a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - break; - } - default: - throw ir_error("control structure not supported"); - } - } - } - else { - operand op = static_cast<const omega::CG_suifRepr *>(repr)->GetExpression(); - if (op.is_instr()) { - instruction *ins = op.instr(); - switch (ins->opcode()) { - case io_array: { - IR_suifArrayRef *ref = new IR_suifArrayRef(this, static_cast<in_array *>(ins)); - for (int i = 0; i < ref->n_dim(); i++) { - omega::CG_suifRepr *r = new omega::CG_suifRepr(find_array_index(ref->ia_, ref->n_dim(), i, is_fortran_)); - std::vector<IR_ArrayRef *> a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - arrays.push_back(ref); - break; - } - case io_str: - case io_memcpy: { - omega::CG_suifRepr *r1 = new omega::CG_suifRepr(ins->src_op(1)); - std::vector<IR_ArrayRef *> a1 = FindArrayRef(r1); - delete r1; - std::copy(a1.begin(), a1.end(), back_inserter(arrays)); - omega::CG_suifRepr *r2 = new omega::CG_suifRepr(ins->src_op(0)); - std::vector<IR_ArrayRef *> a2 = FindArrayRef(r2); - delete r2; - std::copy(a2.begin(), a2.end(), back_inserter(arrays)); - break; - } - default: - for (int i = 0; i < ins->num_srcs(); i++) { - omega::CG_suifRepr *r = new omega::CG_suifRepr(ins->src_op(i)); - std::vector<IR_ArrayRef *> a = FindArrayRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(arrays)); - } - } - } - } - - return arrays; -} - - -std::vector<IR_ScalarRef *> IR_suifCode::FindScalarRef(const omega::CG_outputRepr *repr) const { - std::vector<IR_ScalarRef *> scalars; - - tree_node_list *tnl = static_cast<const omega::CG_suifRepr *>(repr)->GetCode(); - if (tnl != NULL) { - tree_node_list_iter iter(tnl); - while (!iter.is_empty()) { - tree_node *tn = iter.step(); - switch (tn->kind()) { - case TREE_FOR: { - tree_for *tnf = static_cast<tree_for *>(tn); - omega::CG_suifRepr *r = new omega::CG_suifRepr(tnf->body()); - std::vector<IR_ScalarRef *> a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - break; - } - case TREE_IF: { - tree_if *tni = static_cast<tree_if *>(tn); - omega::CG_suifRepr *r = new omega::CG_suifRepr(tni->header()); - std::vector<IR_ScalarRef *> a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - r = new omega::CG_suifRepr(tni->then_part()); - a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - r = new omega::CG_suifRepr(tni->else_part()); - a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - break; - } - case TREE_BLOCK: { - omega::CG_suifRepr *r = new omega::CG_suifRepr(static_cast<tree_block *>(tn)->body()); - std::vector<IR_ScalarRef *> a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - break; - } - case TREE_INSTR: { - omega::CG_suifRepr *r = new omega::CG_suifRepr(operand(static_cast<tree_instr *>(tn)->instr())); - std::vector<IR_ScalarRef *> a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - break; - } - default: - throw ir_error("control structure not supported"); - } - } - } - else { - operand op = static_cast<const omega::CG_suifRepr *>(repr)->GetExpression(); - if (op.is_instr()) { - instruction *ins = op.instr(); - for (int i = 0; i < ins->num_srcs(); i++) { - operand op = ins->src_op(i); - if (op.is_symbol()) - scalars.push_back(new IR_suifScalarRef(this, ins, i)); - else if (op.is_instr()) { - omega::CG_suifRepr *r = new omega::CG_suifRepr(op); - std::vector<IR_ScalarRef *> a = FindScalarRef(r); - delete r; - std::copy(a.begin(), a.end(), back_inserter(scalars)); - } - } - - operand op = ins->dst_op(); - if (op.is_symbol()) - scalars.push_back(new IR_suifScalarRef(this, ins, -1)); - } - else if (op.is_symbol()) - scalars.push_back(new IR_suifScalarRef(this, op.symbol())); - } - - return scalars; -} - - -std::vector<IR_Control *> IR_suifCode::FindOneLevelControlStructure(const IR_Block *block) const { - std::vector<IR_Control *> controls; - - IR_suifBlock *l_block = static_cast<IR_suifBlock *>(const_cast<IR_Block *>(block)); - tree_node_list_iter iter(l_block->tnl_); - while(!iter.is_empty()) { - tree_node *tn = iter.peek(); - if (tn->list_e() == l_block->start_) - break; - iter.step(); - } - tree_node_list_e *start = NULL; - tree_node_list_e *prev = NULL; - while (!iter.is_empty()) { - tree_node *tn = iter.step(); - if (tn->kind() == TREE_FOR) { - if (start != NULL) { - controls.push_back(new IR_suifBlock(this, l_block->tnl_, start, prev)); - start = NULL; - } - controls.push_back(new IR_suifLoop(this, static_cast<tree_for *>(tn))); - } - else if (tn->kind() == TREE_IF) { - if (start != NULL) { - controls.push_back(new IR_suifBlock(this, l_block->tnl_, start, prev)); - start = NULL; - } - controls.push_back(new IR_suifIf(this, static_cast<tree_if *>(tn))); - } - else if (start == NULL && !is_null_statement(tn)) { - start = tn->list_e(); - } - prev = tn->list_e(); - if (prev == l_block->end_) - break; - } - - if (start != NULL && start != l_block->start_) - controls.push_back(new IR_suifBlock(this, l_block->tnl_, start, prev)); - - return controls; -} - - -IR_Block *IR_suifCode::MergeNeighboringControlStructures(const std::vector<IR_Control *> &controls) const { - if (controls.size() == 0) - return NULL; - - tree_node_list *tnl = NULL; - tree_node_list_e *start, *end; - for (int i = 0; i < controls.size(); i++) { - switch (controls[i]->type()) { - case IR_CONTROL_LOOP: { - tree_for *tf = static_cast<IR_suifLoop *>(controls[i])->tf_; - if (tnl == NULL) { - tnl = tf->parent(); - start = end = tf->list_e(); - } - else { - if (tnl != tf->parent()) - throw ir_error("controls to merge not at the same level"); - end = tf->list_e(); - } - break; - } - case IR_CONTROL_BLOCK: { - if (tnl == NULL) { - tnl = static_cast<IR_suifBlock *>(controls[0])->tnl_; - start = static_cast<IR_suifBlock *>(controls[0])->start_; - end = static_cast<IR_suifBlock *>(controls[0])->end_; - } - else { - if (tnl != static_cast<IR_suifBlock *>(controls[0])->tnl_) - throw ir_error("controls to merge not at the same level"); - end = static_cast<IR_suifBlock *>(controls[0])->end_; - } - break; - } - default: - throw ir_error("unrecognized control to merge"); - } - } - - return new IR_suifBlock(controls[0]->ir_, tnl, start, end); -} - - -IR_Block *IR_suifCode::GetCode() const { - return new IR_suifBlock(this, psym_->block()->body()); -} - - -void IR_suifCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) { - tree_node_list *tnl = static_cast<omega::CG_suifRepr *>(repr)->GetCode(); - - switch (old->type()) { - case IR_CONTROL_LOOP: { - tree_for *tf_old = static_cast<IR_suifLoop *>(old)->tf_; - tree_node_list *tnl_old = tf_old->parent(); - - tnl_old->insert_before(tnl, tf_old->list_e()); - tnl_old->remove(tf_old->list_e()); - delete tf_old; - - break; - } - case IR_CONTROL_BLOCK: { - IR_suifBlock *sb = static_cast<IR_suifBlock *>(old); - tree_node_list_iter iter(sb->tnl_); - bool need_deleting = false; - while (!iter.is_empty()) { - tree_node *tn = iter.step(); - tree_node_list_e *pos = tn->list_e(); - if (pos == sb->start_) { - sb->tnl_->insert_before(tnl, pos); - need_deleting = true; - } - if (need_deleting) { - sb->tnl_->remove(pos); - delete tn; - } - if (pos == sb->end_) - break; - } - - break; - } - default: - throw ir_error("control structure to be replaced not supported"); - } - - delete old; - delete repr; -} - - -void IR_suifCode::ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr) { - operand op = static_cast<omega::CG_suifRepr *>(repr)->GetExpression(); - - if (typeid(*old) == typeid(IR_suifArrayRef)) { - in_array *ia_orig = static_cast<IR_suifArrayRef *>(old)->ia_; - - if (op.is_instr()) { - instruction *ia_repl = op.instr(); - if (ia_repl->opcode() == io_array) { - if (ia_orig->elem_type()->is_struct()) { - static_cast<in_array *>(ia_repl)->set_offset(ia_orig->offset()); - struct_type *tn = static_cast<struct_type *>(ia_orig->elem_type()); - int left; - type_node *field_tn = tn->field_type(tn->find_field_by_offset(ia_orig->offset(), left)); - static_cast<in_array *>(ia_repl)->set_result_type(field_tn->ptr_to()); - } - replace_instruction(ia_orig, ia_repl); - delete ia_orig; - } - else { - instruction *parent_instr = ia_orig->dst_op().instr(); - if (parent_instr->opcode() == io_str) { - throw ir_error("replace left hand arrary reference not supported yet"); - } - else if (parent_instr->opcode() == io_lod) { - instruction *instr = parent_instr->dst_op().instr(); - if (instr->dst_op() == operand(parent_instr)) { - parent_instr->remove(); - instr->set_dst(op); - } - else { - for (int i = 0; i < instr->num_srcs(); i++) - if (instr->src_op(i) == operand(parent_instr)) { - parent_instr->remove(); - instr->set_src_op(i, op); - break; - } - } - - delete parent_instr; - } - else - throw ir_error("array reference to be replaced does not appear in any instruction"); - } - } - else if (op.is_symbol()) { - var_sym *vs = op.symbol(); - instruction *parent_instr = ia_orig->dst_op().instr(); - if (parent_instr->opcode() == io_str) { - tree_node *tn = parent_instr->parent(); - operand op = parent_instr->src_op(1).clone(); - instruction *new_instr = new in_rrr(io_cpy, vs->type(), operand(vs), op); - tree_node_list *tnl = tn->parent(); - tnl->insert_before(new tree_instr(new_instr), tn->list_e()); - tnl->remove(tn->list_e()); - - delete tn; - } - else if (parent_instr->opcode() == io_lod) { - instruction *instr = parent_instr->dst_op().instr(); - if (instr->dst_op() == operand(parent_instr)) { - parent_instr->remove(); - instr->set_dst(operand(vs)); - } - else { - for (int i = 0; i < instr->num_srcs(); i++) - if (instr->src_op(i) == operand(parent_instr)) { - parent_instr->remove(); - instr->set_src_op(i, operand(vs)); - break; - } - } - - delete parent_instr; - } - else - throw ir_error("array reference to be replaced does not appear in any instruction"); - } - else - throw ir_error("can't handle replacement expression"); - } - else - throw ir_error("replacing a scalar variable not implemented"); - - delete old; - delete repr; -} - - - -IR_OPERATION_TYPE IR_suifCode::QueryExpOperation(const omega::CG_outputRepr *repr) const { - operand op = static_cast<const omega::CG_suifRepr *>(repr)->GetExpression(); - - if (op.is_immed()) - return IR_OP_CONSTANT; - else if (op.is_symbol()) - return IR_OP_VARIABLE; - else if (op.is_instr()) { - instruction *ins = op.instr(); - switch (ins->opcode()) { - case io_cpy: - return IR_OP_ASSIGNMENT; - case io_add: - return IR_OP_PLUS; - case io_sub: - return IR_OP_MINUS; - case io_mul: - return IR_OP_MULTIPLY; - case io_div: - return IR_OP_DIVIDE; - case io_neg: - return IR_OP_NEGATIVE; - case io_min: - return IR_OP_MIN; - case io_max: - return IR_OP_MAX; - case io_cvt: - return IR_OP_POSITIVE; - default: - return IR_OP_UNKNOWN; - } - } - else if (op.is_null()) - return IR_OP_NULL; - else - return IR_OP_UNKNOWN; -} - - -IR_CONDITION_TYPE IR_suifCode::QueryBooleanExpOperation(const omega::CG_outputRepr *repr) const { - operand op = static_cast<const omega::CG_suifRepr *>(repr)->GetExpression(); - if (op.is_instr()) { - instruction *ins = op.instr(); - switch (ins->opcode()) { - case io_seq: - return IR_COND_EQ; - case io_sne: - return IR_COND_NE; - case io_sl: - return IR_COND_LT; - case io_sle: - return IR_COND_LE; - default: - return IR_COND_UNKNOWN; - } - } - else - return IR_COND_UNKNOWN; -} - - -std::vector<omega::CG_outputRepr *> IR_suifCode::QueryExpOperand(const omega::CG_outputRepr *repr) const { - std::vector<omega::CG_outputRepr *> v; - - operand op = static_cast<const omega::CG_suifRepr *>(repr)->GetExpression(); - if (op.is_immed() || op.is_symbol()) { - omega::CG_suifRepr *repr = new omega::CG_suifRepr(op); - v.push_back(repr); - } - else if (op.is_instr()) { - instruction *ins = op.instr(); - omega::CG_suifRepr *repr; - operand op1, op2; - switch (ins->opcode()) { - case io_cpy: - case io_neg: - case io_cvt: - op1 = ins->src_op(0); - repr = new omega::CG_suifRepr(op1); - v.push_back(repr); - break; - case io_add: - case io_sub: - case io_mul: - case io_div: - case io_min: - case io_max: - op1 = ins->src_op(0); - repr = new omega::CG_suifRepr(op1); - v.push_back(repr); - op2 = ins->src_op(1); - repr = new omega::CG_suifRepr(op2); - v.push_back(repr); - break; - case io_seq: - case io_sne: - case io_sl: - case io_sle: - op1 = ins->src_op(0); - repr = new omega::CG_suifRepr(op1); - v.push_back(repr); - op2 = ins->src_op(1); - repr = new omega::CG_suifRepr(op2); - v.push_back(repr); - break; - default: - throw ir_error("operation not supported"); - } - } - else - throw ir_error("operand type not supported"); - - return v; -} - - -// IR_Constant *IR_suifCode::QueryExpConstant(const CG_outputRepr *repr) const { -// CG_suifRepr *l_repr = static_cast<CG_suifRepr *>(const_cast<CG_outputRepr *>(repr)); - -// operand op = l_repr->GetExpression(); -// if (op.is_immed()) { -// immed im = op.immediate(); - -// switch (im.kind()) { -// case im_int: -// return new IR_suifConstant(this, static_cast<coef_t>(im.integer())); -// case im_extended_int: -// return new IR_suifConstant(this, static_cast<coef_t>(im.long_int())); -// case im_float: -// return new IR_suifConstant(this, im.flt()); -// default: -// assert(-1); -// } -// } -// else -// assert(-1); -// } - - -// IR_ScalarRef *IR_suifCode::QueryExpVariable(const CG_outputRepr *repr) const { -// CG_suifRepr *l_repr = static_cast<CG_suifRepr *>(const_cast<CG_outputRepr *>(repr)); - -// operand op = l_repr->GetExpression(); -// if (op.is_symbol()) -// return new IR_suifScalarRef(this, op.symbol()); -// else -// assert(-1); -// } - - -IR_Ref *IR_suifCode::Repr2Ref(const omega::CG_outputRepr *repr) const { - operand op = static_cast<const omega::CG_suifRepr *>(repr)->GetExpression(); - if (op.is_immed()) { - immed im = op.immediate(); - - switch (im.kind()) { - case im_int: - return new IR_suifConstantRef(this, static_cast<omega::coef_t>(im.integer())); - case im_extended_int: - return new IR_suifConstantRef(this, static_cast<omega::coef_t>(im.long_int())); - case im_float: - return new IR_suifConstantRef(this, im.flt()); - default: - throw ir_error("immediate value not integer or floatint point"); - } - } - else if (op.is_symbol()) - return new IR_suifScalarRef(this, op.symbol()); - else - throw ir_error("unrecognized reference type"); -} |