summaryrefslogtreecommitdiff
path: root/ir_suif.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ir_suif.cc')
-rw-r--r--ir_suif.cc1438
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");
-}