summaryrefslogtreecommitdiff
path: root/ir_suif.cc
diff options
context:
space:
mode:
authordhuth <derickhuth@gmail.com>2014-08-27 09:52:06 -0600
committerdhuth <derickhuth@gmail.com>2014-08-27 09:52:06 -0600
commitbff810cc371a38f493d688c54f71013f5a7d53bf (patch)
treefbe86954bb3c01deb21da9e41ebff5baa2889a45 /ir_suif.cc
downloadchill-bff810cc371a38f493d688c54f71013f5a7d53bf.tar.gz
chill-bff810cc371a38f493d688c54f71013f5a7d53bf.tar.bz2
chill-bff810cc371a38f493d688c54f71013f5a7d53bf.zip
Initial commit
Diffstat (limited to 'ir_suif.cc')
-rw-r--r--ir_suif.cc1438
1 files changed, 1438 insertions, 0 deletions
diff --git a/ir_suif.cc b/ir_suif.cc
new file mode 100644
index 0000000..a0ea357
--- /dev/null
+++ b/ir_suif.cc
@@ -0,0 +1,1438 @@
+/*****************************************************************************
+ 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");
+}