diff options
Diffstat (limited to 'include/ir_code.hh')
-rw-r--r-- | include/ir_code.hh | 282 |
1 files changed, 186 insertions, 96 deletions
diff --git a/include/ir_code.hh b/include/ir_code.hh index d695474..0946610 100644 --- a/include/ir_code.hh +++ b/include/ir_code.hh @@ -8,7 +8,7 @@ extra code generation. . Notes: - Unlike CG_outputRepr, IR_Symbol,IR_Ref and IR_Control are place holders + Unlike CG_outputRepr, IR_Symbol, IR_Ref and IR_Control are place holders to the underlying code, thus deleting or duplicating them does not affect the actual code. Similar to Omega builder's memory allocation strategy, all non-const pointer parameters of CG_outputRepr/IR_Symbol/IR_Ref/IR_Control @@ -22,60 +22,49 @@ #ifndef IR_CODE_HH #define IR_CODE_HH -/*! - * \file - * \brief CHiLL's compiler intermediate representation interface that extends Omega's builder interface to accomodate compiler analyses and extra code generation. - * - * Unlike CG_outputRepr, IR_Symbol,IR_Ref and IR_Control are place holders - * to the underlying code, thus deleting or duplicating them does not affect - * the actual code. Similar to Omega builder's memory allocation strategy, - * all non-const pointer parameters of CG_outputRepr/IR_Symbol/IR_Ref/IR_Control - * are destroyed after the call. - */ +#include <ir_enums.hh> +#include <chill_ast.hh> + +#include <vector> + +// needed for omega::coef_t below +#include <basic/util.h> // in omega ... why is this not in CG_output*.h? #include <code_gen/CG_outputRepr.h> #include <code_gen/CG_outputBuilder.h> -#include <vector> -enum IR_OPERATION_TYPE {IR_OP_CONSTANT, IR_OP_VARIABLE, - IR_OP_PLUS, IR_OP_MINUS, IR_OP_MULTIPLY, IR_OP_DIVIDE, - IR_OP_POSITIVE, IR_OP_NEGATIVE, - IR_OP_MIN, IR_OP_MAX, - IR_OP_ASSIGNMENT, - IR_OP_NULL, IR_OP_UNKNOWN}; -enum IR_CONTROL_TYPE {IR_CONTROL_LOOP, IR_CONTROL_IF, IR_CONTROL_WHILE, IR_CONTROL_BLOCK}; -enum IR_CONSTANT_TYPE {IR_CONSTANT_INT, IR_CONSTANT_FLOAT, - IR_CONSTANT_UNKNOWN}; -enum IR_CONDITION_TYPE {IR_COND_LT, IR_COND_LE, - IR_COND_GT, IR_COND_GE, - IR_COND_EQ, IR_COND_NE, - IR_COND_UNKNOWN}; -enum IR_ARRAY_LAYOUT_TYPE {IR_ARRAY_LAYOUT_ROW_MAJOR, - IR_ARRAY_LAYOUT_COLUMN_MAJOR, - IR_ARRAY_LAYOUT_SPACE_FILLING}; - -class IR_Code; - - -//! Base abstract class for scalar and array symbols. -/*! This is a place holder for related declaration in IR code.*/ + + +class IR_Code; // forward declaration + + +// Base abstract class for scalar and array symbols. This is a place +// holder for related declaration in IR code. struct IR_Symbol { const IR_Code *ir_; - + virtual ~IR_Symbol() {/* ir_ is not the responsibility of this object */} - virtual int n_dim() const = 0; + virtual int n_dim() const = 0; // IR_Symbol virtual std::string name() const = 0; virtual bool operator==(const IR_Symbol &that) const = 0; virtual bool operator!=(const IR_Symbol &that) const {return !(*this == that);} virtual IR_Symbol *clone() const = 0; /* shallow copy */ + + virtual bool isScalar() const { return false; } // default + virtual bool isArray() const { return false; } // default + virtual bool isPointer() const { return false; } // default + + //IR_SYMBOL_TYPE symtype; // base type: int, float, double, struct, .... typedef'd something + //IR_SYMBOL_TYPE getDatatype() ; }; struct IR_ScalarSymbol: public IR_Symbol { virtual ~IR_ScalarSymbol() {} - int n_dim() const {return 0;} + int n_dim() const {return 0;} // IR_ScalarSymbol virtual int size() const = 0; + bool isScalar() const { return true; } }; @@ -84,23 +73,33 @@ struct IR_ArraySymbol: public IR_Symbol { virtual int elem_size() const = 0; virtual omega::CG_outputRepr *size(int dim) const = 0; virtual IR_ARRAY_LAYOUT_TYPE layout_type() const = 0; + virtual IR_CONSTANT_TYPE elem_type() const = 0; + bool isArray() const { return true; } }; -//! Base abstract class for scalar and array references. -/*! This is a place holder for related code in IR code. */ +struct IR_PointerSymbol: public IR_Symbol { + virtual ~IR_PointerSymbol() {} + virtual omega::CG_outputRepr *size(int dim) const = 0; + virtual void set_size(int dim, omega::CG_outputRepr*) = 0; + virtual IR_CONSTANT_TYPE elem_type() const = 0; + bool isPointer() const { return true; } +}; + +// Base abstract class for scalar and array references. This is a +// place holder for related code in IR code. struct IR_Ref { const IR_Code *ir_; virtual ~IR_Ref() {/* ir_ is not the responsibility of this object */} - virtual int n_dim() const = 0; + virtual int n_dim() const = 0; // IR_Ref virtual bool is_write() const = 0; virtual std::string name() const = 0; virtual bool operator==(const IR_Ref &that) const = 0; virtual bool operator!=(const IR_Ref &that) const {return !(*this == that);} virtual omega::CG_outputRepr *convert() = 0; - //! shallow copy - virtual IR_Ref *clone() const = 0; + virtual IR_Ref *clone() const = 0; /* shallow copy */ + virtual void Dump() const { fprintf(stderr, "some IR_*Ref needs to implement Dump()\n"); int *i=0; int j=i[0]; }; }; @@ -108,7 +107,7 @@ struct IR_ConstantRef: public IR_Ref { IR_CONSTANT_TYPE type_; virtual ~IR_ConstantRef() {} - int n_dim() const {return 0;} + int n_dim() const {return 0;} // IR_ConstantRef bool is_write() const {return false;} std::string name() const {return std::string();} virtual bool is_integer() const {return type_ == IR_CONSTANT_INT;} @@ -118,10 +117,10 @@ struct IR_ConstantRef: public IR_Ref { struct IR_ScalarRef: public IR_Ref { virtual ~IR_ScalarRef() {} - int n_dim() const {return 0;} + int n_dim() const {return 0;} // IR_ScalarRef virtual IR_ScalarSymbol *symbol() const = 0; std::string name() const { - IR_ScalarSymbol *sym = symbol(); + IR_ScalarSymbol *sym = symbol(); // really inefficient. MAKE a symbol, just to get a name std::string s = sym->name(); delete sym; return s; @@ -137,54 +136,78 @@ struct IR_ScalarRef: public IR_Ref { struct IR_ArrayRef: public IR_Ref { virtual ~IR_ArrayRef() {} - int n_dim() const { + int n_dim() const { // IR_ArrayRef returns the size of the array IR_ArraySymbol *sym = symbol(); int n = sym->n_dim(); - delete sym; + // ?? delete sym; return n; } virtual omega::CG_outputRepr *index(int dim) const = 0; virtual IR_ArraySymbol *symbol() const = 0; - std::string name() const { - IR_ArraySymbol *sym = symbol(); + virtual std::string name() const { + // makes (constructs!) a symbol, just to copy a string! + IR_ArraySymbol *sym = symbol(); // TODO exceedingly wasteful std::string s = sym->name(); - delete sym; - return s; + // ?? delete sym; (goes out of scope, so deletes itself) + return s; // s ALSO goes out of scope but perhaps the info is copied at the other end } virtual int elem_size() const { IR_ArraySymbol *sym = symbol(); int s = sym->elem_size(); - delete sym; + // ?? delete sym; return s; } virtual IR_ARRAY_LAYOUT_TYPE layout_type() const { IR_ArraySymbol *sym = symbol(); IR_ARRAY_LAYOUT_TYPE t = sym->layout_type(); - delete sym; + // ?? delete sym; return t; } + virtual void Dump() const { fprintf(stderr, "IR_ArrayRef needs to implement Dump()\n"); }; +}; + +struct IR_PointerArrayRef: public IR_Ref { + + const IR_Code *ir_; + + virtual ~IR_PointerArrayRef() {} + int n_dim() const { // IR_PointerArrayRef returns size of the ... symbol? + IR_PointerSymbol *sym = symbol(); + int n = sym->n_dim(); + //Anand: Hack, fix later + //delete sym; + return n; + } + virtual omega::CG_outputRepr *index(int dim) const = 0; + virtual IR_PointerSymbol *symbol() const = 0; + std::string name() const { + IR_PointerSymbol *sym = symbol(); + std::string s = sym->name(); +//Anand: Hack, fix later + //delete sym; + return s; + } + + }; struct IR_Block; -//! Base abstract class for code structures. -/*! - * This is a place holder for the actual structure in the IR code. - * However, in cases that original source code may be transformed during - * loop initialization such as converting a while loop to a for loop or - * reconstructing the loop from low level IR code, the helper loop class (NOT - * IMPLEMENTED) must contain the transformed code that needs to be - * freed when out of service. - */ +// Base abstract class for code structures. This is a place holder +// for the actual structure in the IR code. However, in cases that +// original source code may be transformed during loop initialization +// such as converting a while loop to a for loop or reconstructing the +// loop from low level IR code, the helper loop class (NOT +// IMPLEMENTED) must contain the transformed code that needs to be +// freed when out of service. struct IR_Control { - const IR_Code *ir_; + const IR_Code *ir_; // hate this virtual ~IR_Control() {/* ir_ is not the responsibility of this object */} virtual IR_CONTROL_TYPE type() const = 0; virtual IR_Block *convert() = 0; - //! shallow copy - virtual IR_Control *clone() const = 0; + virtual IR_Control *clone() const = 0; /* shallow copy */ }; @@ -224,55 +247,98 @@ struct IR_While: public IR_Control { }; -//! Abstract class for compiler IR. +// Abstract class for compiler IR. class IR_Code { protected: - omega::CG_outputBuilder *ocg_; + // the only data members in IR_Code are Omega classes + omega::CG_outputBuilder *ocg_; // Omega Code Gen omega::CG_outputRepr *init_code_; omega::CG_outputRepr *cleanup_code_; + // OK, I lied + static int ir_pointer_counter; + static int ir_array_counter; + public: + + int getPointerCounter() { return ir_pointer_counter; } + int getArrayCounter() { return ir_array_counter; } + + // TODO can't get the initialize of counters to work !! + int getAndIncrementPointerCounter() { if (ir_pointer_counter == 0) ir_pointer_counter= 1; ir_pointer_counter++; return ir_pointer_counter-1; } + int getAndIncrementArrayCounter() { if (ir_array_counter == 0) ir_array_counter= 1; ir_array_counter += 1; return ir_array_counter-1; } + + // if all flavors of ir_code use chillAST internally ... + chillAST_FunctionDecl * func_defn; // the function we're modifying + chillAST_FunctionDecl *GetChillFuncDefinition() { return func_defn; }; + IR_Code() {ocg_ = NULL; init_code_ = cleanup_code_ = NULL;} - virtual ~IR_Code() { delete ocg_; delete init_code_; delete cleanup_code_; } - /* the content of init and cleanup code have already been released in derived classes */ + virtual ~IR_Code() { delete ocg_; delete init_code_; delete cleanup_code_; } /* the content of init and cleanup code have already been released in derived classes */ - /*! - * \param memory_type is for differentiating the location of - * where the new memory is allocated. this is useful for - * processors with heterogeneous memory hierarchy. - */ + omega::CG_outputRepr* init_code(){ return init_code_; } + + // memory_type is for differentiating the location of where the new memory is allocated. + // this is useful for processors with heterogeneous memory hierarchy. virtual IR_ScalarSymbol *CreateScalarSymbol(const IR_Symbol *sym, int memory_type) = 0; - virtual IR_ArraySymbol *CreateArraySymbol(const IR_Symbol *sym, std::vector<omega::CG_outputRepr *> &size, int memory_type) = 0; - + virtual IR_ScalarSymbol *CreateScalarSymbol(IR_CONSTANT_TYPE type, int memory_type, std::string name="" ) =0; + + virtual IR_ArraySymbol *CreateArraySymbol(const IR_Symbol *sym, + std::vector<omega::CG_outputRepr *> &size, + int memory_type) = 0; + virtual IR_ArraySymbol *CreateArraySymbol(omega::CG_outputRepr *type, + std::vector<omega::CG_outputRepr *> &size_repr) =0; + + virtual IR_PointerSymbol *CreatePointerSymbol(const IR_Symbol *sym, + std::vector<omega::CG_outputRepr *> &size_repr) =0; + virtual IR_PointerSymbol *CreatePointerSymbol(const IR_CONSTANT_TYPE type, + std::vector<omega::CG_outputRepr *> &size_repr, + std::string name="") =0; + + virtual IR_PointerSymbol *CreatePointerSymbol(omega::CG_outputRepr *type, + std::vector<omega::CG_outputRepr *> &size_repr) =0; + virtual IR_ScalarRef *CreateScalarRef(const IR_ScalarSymbol *sym) = 0; virtual IR_ArrayRef *CreateArrayRef(const IR_ArraySymbol *sym, std::vector<omega::CG_outputRepr *> &index) = 0; + + virtual omega::CG_outputRepr* CreateArrayRefRepr(const IR_ArraySymbol *sym, + std::vector<omega::CG_outputRepr *> &index) { + //IR_ArrayRef *AR = CreateArrayRef(sym, index); + //return new omega::CG_outputRepr(AR); + fprintf(stderr, "ir_code.hh SOME SUBCLASS OF ir_code did not implement CreateArrayRefRepr()\n"); + return NULL; + } + + virtual IR_PointerArrayRef *CreatePointerArrayRef( IR_PointerSymbol *sym, + std::vector<omega::CG_outputRepr *> &index) =0; virtual int ArrayIndexStartAt() {return 0;} - /*! - * Array references should be returned in their accessing order. - * - * ~~~ - * e.g. s1: A[i] = A[i-1] - * s2: B[C[i]] = D[i] + E[i] - * return A[i-1], A[i], D[i], E[i], C[i], B[C[i]] in this order. - * ~~~ - */ + virtual void CreateDefineMacro(std::string s,std::string args, omega::CG_outputRepr *repr) = 0; + virtual void CreateDefineMacro(std::string s,std::string args, std::string repr) = 0; + virtual void CreateDefineMacro(std::string s, std::vector<std::string> args,omega::CG_outputRepr *repr) {}; // TODO make pure virtual + + virtual omega::CG_outputRepr *CreateArrayType(IR_CONSTANT_TYPE type, omega::CG_outputRepr* size)=0; + virtual omega::CG_outputRepr *CreatePointerType(IR_CONSTANT_TYPE type)=0; + virtual omega::CG_outputRepr *CreatePointerType(omega::CG_outputRepr *type)=0; + virtual omega::CG_outputRepr *CreateScalarType(IR_CONSTANT_TYPE type)=0; + // Array references should be returned in their accessing order. + // e.g. s1: A[i] = A[i-1] + // s2: B[C[i]] = D[i] + E[i] + // return A[i-1], A[i], D[i], E[i], C[i], B[C[i]] in this order. virtual std::vector<IR_ArrayRef *> FindArrayRef(const omega::CG_outputRepr *repr) const = 0; + virtual std::vector<IR_PointerArrayRef *> FindPointerArrayRef(const omega::CG_outputRepr *repr) const = 0 ; virtual std::vector<IR_ScalarRef *> FindScalarRef(const omega::CG_outputRepr *repr) const = 0; + virtual bool parent_is_array(IR_ArrayRef *a)=0; - /*! - * If there is no sub structure interesting inside the block, return empty, - * so we know when to stop looking inside. - */ + // If there is no sub structure interesting inside the block, return empty, + // so we know when to stop looking inside. virtual std::vector<IR_Control *> FindOneLevelControlStructure(const IR_Block *block) const = 0; - /*! - * All controls must be in the same block, at the same level and in - * contiguous lexical order as appeared in parameter vector. - */ + // All controls must be in the same block, at the same level and in + // contiguous lexical order as appeared in parameter vector. virtual IR_Block *MergeNeighboringControlStructures(const std::vector<IR_Control *> &controls) const = 0; virtual IR_Block *GetCode() const = 0; + virtual IR_Control *GetCode(omega::CG_outputRepr *code) const = 0; virtual void ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) = 0; virtual void ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr) = 0; @@ -280,10 +346,34 @@ public: virtual IR_CONDITION_TYPE QueryBooleanExpOperation(const omega::CG_outputRepr *repr) const = 0; virtual std::vector<omega::CG_outputRepr *> QueryExpOperand(const omega::CG_outputRepr *repr) const = 0; virtual IR_Ref *Repr2Ref(const omega::CG_outputRepr *repr) const = 0; - - //! Codegen Omega code builder interface - omega::CG_outputBuilder *builder() const {return ocg_;} + + // Manu:: Added functions required for reduction operation + // virtual omega::CG_outputRepr * FromSameStmt(IR_ArrayRef *A, IR_ArrayRef *B) = 0; + virtual bool FromSameStmt(IR_ArrayRef *A, IR_ArrayRef *B) = 0; + virtual void printStmt(const omega::CG_outputRepr *repr) = 0; + virtual int getStmtType(const omega::CG_outputRepr *repr) = 0; + virtual IR_OPERATION_TYPE getReductionOp(const omega::CG_outputRepr *repr) = 0; + virtual IR_Control * FromForStmt(const omega::CG_outputRepr *repr) = 0; + + // Manu:: Added functions for scalar expansion + virtual IR_ArraySymbol *CreateArraySymbol(omega::CG_outputRepr *size, const IR_Symbol *sym) = 0; + virtual bool ReplaceRHSExpression(omega::CG_outputRepr *code, IR_Ref *ref) = 0; + virtual omega::CG_outputRepr * GetRHSExpression(omega::CG_outputRepr *code) = 0; + virtual omega::CG_outputRepr * GetLHSExpression(omega::CG_outputRepr *code) = 0; + virtual omega::CG_outputRepr *CreateMalloc(const IR_CONSTANT_TYPE type, std::string lhs, + omega::CG_outputRepr * size_repr)=0; + virtual omega::CG_outputRepr *CreateMalloc(omega::CG_outputRepr *type, std::string variable, + omega::CG_outputRepr * size_repr)=0; + virtual omega::CG_outputRepr *CreateFree(omega::CG_outputRepr * exp)=0; + + //void Dump() { ocg_->Dump(); }; + //--------------------------------------------------------------------------- + // CC Omega code builder interface here + + //--------------------------------------------------------------------------- + omega::CG_outputBuilder *builder() const { return ocg_;} }; #endif + |