summaryrefslogtreecommitdiff
path: root/include/ir_code.hh
diff options
context:
space:
mode:
Diffstat (limited to 'include/ir_code.hh')
-rw-r--r--include/ir_code.hh282
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
+