summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chill.cc3
-rw-r--r--src/chill_ast.cc6493
-rw-r--r--src/chillmodule.cc6
-rw-r--r--src/dep.cc133
-rwxr-xr-xsrc/ir_clang.cc3239
-rw-r--r--src/ir_rose.cc1699
-rw-r--r--src/ir_rose_utils.cc62
-rw-r--r--src/irtools.cc525
-rw-r--r--src/loop.cc3500
-rw-r--r--src/loop_basic.cc477
-rw-r--r--src/loop_datacopy.cc282
-rw-r--r--src/loop_unroll.cc118
-rw-r--r--src/omegatools.cc3007
13 files changed, 16809 insertions, 2735 deletions
diff --git a/src/chill.cc b/src/chill.cc
index 6ca0c4c..b91d383 100644
--- a/src/chill.cc
+++ b/src/chill.cc
@@ -9,7 +9,6 @@
#include "loop.hh"
#include <omega.h>
#include "ir_code.hh"
-#include "ir_rose.hh"
#include "chillmodule.hh" // Python wrapper functions for CHiLL
@@ -76,8 +75,6 @@ int main( int argc, char* argv[] )
lnum_start = get_loop_num_start();
lnum_end = get_loop_num_end();
DEBUG_PRINT("calling ROSE code gen? loop num %d\n", lnum);
- finalize_loop(lnum_start, lnum_end);
- ((IR_roseCode*)(ir_code))->finalizeRose();
delete ir_code;
}
Py_Finalize();
diff --git a/src/chill_ast.cc b/src/chill_ast.cc
new file mode 100644
index 0000000..93afd97
--- /dev/null
+++ b/src/chill_ast.cc
@@ -0,0 +1,6493 @@
+
+
+
+#include "chill_ast.hh"
+
+using namespace std;
+
+int chillAST_node::chill_scalar_counter = 0;
+int chillAST_node::chill_array_counter = 1;
+
+
+const char* Chill_AST_Node_Names[] = {
+ "Unknown AST node type",
+ "SourceFile",
+ "TypedefDecl",
+ "VarDecl",
+ // "ParmVarDecl", not used any more
+ "FunctionDecl",
+ "RecordDecl",
+ "MacroDefinition",
+ "CompoundStmt",
+ "ForStmt",
+ "TernaryOperator",
+ "BinaryOperator",
+ "UnaryOperator",
+ "ArraySubscriptExpr",
+ "MemberExpr",
+ "DeclRefExpr",
+ "IntegerLiteral",
+ "FloatingLiteral",
+ "ImplicitCastExpr", // not sure we need this
+ "ReturnStmt",
+ "CallExpr",
+ "DeclStmt",
+ "ParenExpr",
+ "CStyleCastExpr",
+ "CStyleAddressOf",
+ "IfStmt",
+ "SizeOf",
+ "Malloc",
+ "Free",
+ "NoOp",
+// CUDA specific
+ "CudaMalloc",
+ "CudaFree",
+ "CudaMemcpy",
+ "CudaKernelCall",
+ "CudaSyncthreads",
+ "fake1",
+ "fake2",
+ "fake3"
+};
+
+char *parseUnderlyingType( char *sometype ) {
+ int len = strlen(sometype);
+ //fprintf(stderr, "parseUnderlyingType( %s )\n", sometype);
+ char *underlying = strdup(sometype);
+ char *p;
+ char *start = underlying;
+
+ // ugly. we want to turn "float *" into "float" but "struct abc *" into struct abc.
+ // there are probably many more cases. have an approved list? TODO
+ if (strstr(underlying, "struct ")) start += 7; // (length("struct "))
+ //fprintf(stderr, "sometype '%s' start '%s'\n", sometype, start);
+ if (p = index(start, ' ')) *p = '\0'; // end at first space leak
+ if (p = index(start, '[')) *p = '\0'; // leak
+ if (p = index(start, '*')) *p = '\0'; // leak
+
+ return underlying;
+}
+
+void printSymbolTable( chillAST_SymbolTable *st ) {
+ //printf("%d entries\n", st->size());
+ if (!st) return;
+ for (int i=0; i<st->size(); i++) { printf("%d ", i ); (*st)[i]->printName(); printf("\n"); }
+ if (st->size() )printf("\n");
+ fflush(stdout);
+}
+
+void printSymbolTableMoreInfo( chillAST_SymbolTable *st ) {
+ //printf("%d entries\n", st->size());
+ if (!st) return;
+ for (int i=0; i<st->size(); i++) { printf("%d ", i ); (*st)[i]->print(); printf("\n"); }
+ if (st->size() )printf("\n");
+ fflush(stdout);
+}
+
+
+bool symbolTableHasVariableNamed( chillAST_SymbolTable *table, const char *name ) {
+ if (!table) return false; // ??
+ int numvars = table->size();
+ for (int i=0; i<numvars; i++) {
+ chillAST_VarDecl *vd = (*table)[i];
+ if (!strcmp(name, vd->varname)) return true; // need to check type?
+ }
+ return false;
+}
+
+
+
+chillAST_VarDecl *symbolTableFindVariableNamed( chillAST_SymbolTable *table, const char *name ){ // fwd decl TODO too many similar named functions
+ if (!table) return NULL; // ??
+
+ // see if name has a dot or arrow (->) indicating that it is a structure/class
+ const char *cdot = strstr( name, "." );
+ const char *carrow = strstr(name, "->"); // initial 'c' for const - can't change those
+
+ char *varname;
+ char *subpart = NULL;
+
+ if (cdot || carrow) {
+ fprintf(stderr, "symbolTableFindVariableNamed(), name '%s' looks like a struct\n", name);
+
+ // so, look for the first part in the symbol table.
+ // warning, this could be looking for a->b.c.d->e.f->g
+ varname = strdup( name );
+
+ char *dot = strstr(varname, "." );
+ char *arrow = strstr( varname, "->" );
+ if (dot != NULL && arrow != NULL ) { // dot AND arrow,
+ fprintf(stderr, "chillast.cc symbolTableFindVariableNamed(), name '%s' has both dot and arrow? TODO\n");
+ exit(-1);
+ }
+ else if (dot != NULL && !arrow) { // just dot(s). dot points to the first one
+ //fprintf(stderr, "name '%s' has dot(s)\n", varname);
+ *dot = '\0'; // end string at the dot
+ subpart = &(dot[1]);
+ fprintf(stderr, "will now look for a struct/class named %s that has member %s\n", varname, subpart);
+
+ }
+ else if (arrow != NULL && !dot) { // just arrow(s) arrow points to the first one
+ //fprintf(stderr, "name '%s' has arrow(s)\n", varname);
+ *arrow = '\0'; // end string at the arrow
+ subpart = &(arrow[2]);
+ fprintf(stderr, "will now look for a struct/class named %s that has member %s\n", varname, subpart);
+ }
+ else { // impossible
+ fprintf(stderr, "chillast.cc symbolTableFindVariableNamed(), varname '%s', looks like a struct, but I can't figure it out\n", varname);
+ exit(-1);
+ }
+ }
+ else {
+ varname = strdup(name);
+ }
+
+ int numvars = table->size();
+ for (int i=0; i<numvars; i++) {
+ chillAST_VarDecl *vd = (*table)[i];
+ if (!strcmp(varname, vd->varname)) {
+ fprintf(stderr, "found variable named %s\n", varname);
+
+ if (!subpart) return vd; // need to check type?
+
+ // OK, we have a variable, which looks like a struct/class, and a subpart that is some member names
+ //fprintf(stderr, "but I don't know how to check if it has member %s\n", subpart);
+
+ char *dot = strstr(subpart, "." );
+ char *arrow = strstr(subpart, "->" );
+
+ if (!dot && !arrow) { // whew, only one level of struct
+ //fprintf(stderr, "whew, only one level of struct\n");
+
+ // make sure this variable definition is a struct
+ if (vd->isAStruct()) {
+ //fprintf(stderr, "%s is a struct of type %s\n", varname, vd->getTypeString());
+ if (vd->isVarDecl()) {
+ chillAST_RecordDecl *rd = vd->getStructDef();
+ if (rd) {
+ //fprintf(stderr, "has a recordDecl\n");
+
+ chillAST_VarDecl *sp = rd->findSubpart( subpart );
+ if (sp) fprintf(stderr, "found a struct member named %s\n", subpart);
+ else fprintf(stderr, "DIDN'T FIND a struct member named %s\n", subpart);
+ return sp; // return the subpart??
+ }
+ else {
+ fprintf(stderr, "no recordDecl\n");
+ exit(-1);
+ }
+ }
+ else {
+ fprintf(stderr, "NOT a VarDecl???\n"); // impossible
+ }
+ }
+ else {
+ fprintf(stderr, "false alarm. %s is a variable, but doesn't have subparts\n", varname);
+ return NULL; // false alarm. a variable of the correct name exists, but is not a struct
+ }
+ }
+
+ fprintf(stderr, "chillast.cc symbolTableFindVariableNamed(), name '%s' can't figure out multiple levels of struct yet!\n");
+
+ exit(-1);
+ }
+ }
+ return NULL;
+}
+
+
+
+char *ulhack( char *brackets ) // remove UL from numbers, MODIFIES the argument!
+{
+ //fprintf(stderr, "ulhack( \"%s\" -> ", brackets);
+ // another hack. remove "UL" from integers
+ int len = strlen(brackets);
+ for (int i=0; i< len-2; i++) {
+ if (isdigit(brackets[i])) {
+ if (brackets[i+1] == 'U' && brackets[i+2] == 'L') {
+ // remove
+ for (int j=i+3; j<len; j++) brackets[j-2] = brackets[j];
+ len -=2;
+ brackets[len] = '\0';
+ }
+ }
+ }
+ //fprintf(stderr, "\"%s\" )\n", brackets);
+ return brackets;
+}
+
+
+char *restricthack( char *typeinfo ) // remove __restrict__ , MODIFIES the argument!
+{
+ //if (!isRestrict( typeinfo )) return typeinfo;
+
+ // there is a "__restrict__ " somewhere embedded. remove it.
+ // duplicate work
+ std::string r( "__restrict__" );
+ std::string t( typeinfo );
+ size_t index = t.find( r );
+
+ if (index == std::string::npos) return typeinfo;
+
+ char *c = &( typeinfo[index] );
+ char *after = c + 12;
+ if (*after == ' ') after++;
+
+ //fprintf(stderr, "after = '%s'\n", after);
+
+ while (*after != '\0') *c++ = *after++;
+ *c = '\0';
+
+ return typeinfo;
+
+}
+
+
+
+
+
+char *parseArrayParts( char *sometype ) {
+ int len = strlen(sometype);
+ char *arraypart = (char *)calloc(1 + strlen(sometype), sizeof(char));// leak
+
+ int c = 0;
+ for (int i=0; i<strlen(sometype); ) {
+ if ( sometype[i] == '*') arraypart[c++] = '*';
+ if ( sometype[i] == '[') {
+ while (sometype[i] != ']') {
+ arraypart[c++] = sometype[i++];
+ }
+ arraypart[c++] = ']';
+ }
+ i += 1;
+ }
+ ulhack(arraypart);
+ restricthack( arraypart );
+
+ //fprintf(stderr, "parseArrayParts( %s ) => %s\n", sometype, arraypart);
+ return arraypart;
+}
+
+
+
+
+
+
+
+char *splitTypeInfo( char *underlyingtype ) { // return the bracketed part of a type
+ char *ap = ulhack(parseArrayParts( underlyingtype )); // return this
+
+ // now need to remove all that from the underlyingtype to get
+ char *arraypart = strdup(""); // leak
+ if (index(underlyingtype, '[')) {
+ // looks like an array
+ free(arraypart);
+ char *start = index(underlyingtype, '['); // wrong. can have int *buh[32]
+ arraypart = strdup( start );
+ if (*(start-1) == ' ') start--; // hack
+ *start = '\0';
+
+ // ugly. very leaky
+ strcpy( underlyingtype, parseUnderlyingType( underlyingtype ));
+
+ // ulhack( arraypart );
+ }
+ return ap; // leak unless caller frees this
+}
+
+
+
+bool isRestrict( const char *sometype ) { // does not modify sometype
+ string r( "__restrict__" );
+ string t( sometype );
+ return (std::string::npos != t.find( r ) );
+}
+
+
+
+bool streq( const char *a, const char *b) { return !strcmp(a,b); }; // slightly less ugly // TODO enums
+
+void chillindent( int howfar, FILE *fp ) { for (int i=0; i<howfar; i++) fprintf(fp, " "); }
+
+
+
+chillAST_VarDecl * chillAST_node::findVariableNamed( const char *name ) { // generic, recursive
+ fprintf(stderr, "nodetype %s findVariableNamed( %s )\n", getTypeString(), name );
+ if (hasSymbolTable()) { // look in my symbol table if I have one
+ fprintf(stderr, "%s has a symbol table\n", getTypeString());
+ chillAST_VarDecl *vd = symbolTableFindVariableNamed( getSymbolTable(), name);
+ if (vd) {
+ fprintf(stderr, "found it\n");
+ return vd; // found locally
+ }
+ fprintf(stderr, "%s has a symbol table but couldn't find %s\n", getTypeString(), name );
+ }
+ if (!parent) {
+ fprintf(stderr, "%s has no parent\n", getTypeString());
+ return NULL; // no more recursion available
+ }
+ // recurse upwards
+ //fprintf(stderr, "recursing from %s up to parent %p\n", getTypeString(), parent);
+ fprintf(stderr, "recursing from %s up to parent\n", getTypeString());
+ return parent->findVariableNamed( name );
+}
+
+
+chillAST_RecordDecl * chillAST_node::findRecordDeclNamed( const char *name ) { // recursive
+ fprintf(stderr, "%s::findRecordDeclNamed( %s )\n", getTypeString(), name);
+ // look in children
+ int numchildren = children.size();
+ fprintf(stderr, "%d children\n", numchildren);
+ for (int i=0; i<numchildren; i++) {
+ fprintf(stderr, "child %d %s\n", i, children[i]->getTypeString());
+ if (children[i]->isRecordDecl()) {
+ chillAST_RecordDecl *RD = (chillAST_RecordDecl *)children[i];
+ fprintf(stderr, "it is a recordDecl named '%s' vs '%s'\n", RD->getName(), name);
+ if (!strcmp( RD->getName(), name )) {
+ fprintf(stderr, "FOUND IT\n");
+ return RD;
+ }
+ }
+ }
+
+ if (!parent) return NULL; // no more recursion available
+ // recurse upwards
+ return parent->findRecordDeclNamed( name );
+}
+
+
+void chillAST_node::printPreprocBEFORE( int indent, FILE *fp ) {
+ int numstmts = preprocessinginfo.size();
+ //if (0 != numstmts) {
+ // fprintf(fp, "chillAST_node::printPreprocBEFORE() %d statements\n", numstmts);
+ //}
+
+
+ for (int i=0; i< numstmts; i++) {
+ //fprintf(fp, "stmt %d %d\n", i, preprocessinginfo[i]->position);
+ if (preprocessinginfo[i]->position == CHILL_PREPROCESSING_LINEBEFORE ||
+ preprocessinginfo[i]->position == CHILL_PREPROCESSING_IMMEDIATELYBEFORE) {
+ //fprintf(stderr, "before %d\n", preprocessinginfo[i]->position);
+ preprocessinginfo[i]->print(indent, fp);
+ }
+ }
+}
+
+void chillAST_node::printPreprocAFTER( int indent, FILE *fp ) {
+ for (int i=0; i< preprocessinginfo.size(); i++) {
+ if (preprocessinginfo[i]->position == CHILL_PREPROCESSING_LINEAFTER ||
+ preprocessinginfo[i]->position == CHILL_PREPROCESSING_TOTHERIGHT) {
+ //fprintf(stderr, "after %d\n", preprocessinginfo[i]->position);
+ preprocessinginfo[i]->print(indent, fp);
+ }
+ }
+}
+
+
+chillAST_SourceFile::chillAST_SourceFile::chillAST_SourceFile() {
+ SourceFileName = strdup("No Source File");
+ asttype = CHILLAST_NODETYPE_SOURCEFILE;
+ parent = NULL; // top node
+ metacomment = NULL;
+ global_symbol_table = NULL;
+ global_typedef_table = NULL;
+ FileToWrite = NULL;
+ frontend = strdup("unknown");
+ isFromSourceFile = true;
+ filename = NULL;
+};
+
+chillAST_SourceFile::chillAST_SourceFile(const char *filename ) {
+ SourceFileName = strdup(filename);
+ asttype = CHILLAST_NODETYPE_SOURCEFILE;
+ parent = NULL; // top node
+ metacomment = NULL;
+ global_symbol_table = NULL;
+ global_typedef_table = NULL;
+ FileToWrite = NULL;
+ frontend = strdup("unknown");
+ isFromSourceFile = true;
+ filename = NULL;
+};
+
+void chillAST_SourceFile::print( int indent, FILE *fp ) {
+ //fprintf(stderr, "chillAST_SourceFile::print()\n");
+ fflush(fp);
+ fprintf(fp, "\n// this source derived from CHILL AST originally from file '%s' as parsed by frontend compiler %s\n\n", SourceFileName, frontend);
+ std::vector< char * > includedfiles;
+ int sofar = 0;
+
+ //fprintf(fp, "#define __rose_lt(x,y) ((x)<(y)?(x):(y))\n#define __rose_gt(x,y) ((x)>(y)?(x):(y))\n"); // help diff figure out what's going on
+
+ int numchildren = children.size();
+ //fprintf(stderr, "// sourcefile has %d children\n", numchildren);
+ //fprintf(stderr, "they are\n");
+ //for (int i=0; i<numchildren; i++) {
+ // fprintf(stderr, "%s ", children[i]->getTypeString());
+ // if (children[i]->isFunctionDecl()) {
+ // fprintf(stderr, "%s ", ((chillAST_FunctionDecl *)children[i])->functionName);
+ // }
+ // fprintf(stderr, "\n");
+ //}
+
+ for (int i=0; i<numchildren; i++) {
+ //fprintf(fp, "\n// child %d of type %s:\n", i, children[i]->getTypeString());
+ if (children[i]->isFromSourceFile) {
+ if (children[i]->isFunctionDecl()) {
+ fprintf(stderr, "\nchild %d function %s\n",i,((chillAST_FunctionDecl *)children[i])->functionName);
+ }
+ //fprintf(stderr, "child %d IS from source file\n", i);
+ //if (children[i]->isMacroDefinition()) fprintf(fp, "\n"); fflush(fp);
+ children[i]->print( indent, fp );
+ if (children[i]->isVarDecl()) fprintf(fp, ";\n"); fflush(fp); // top level vardecl\n");
+ }
+ else {
+ //fprintf(stderr, "child %d is not from source file\n", i);
+ // this should all go away
+
+#ifdef NOPE
+ if (children[i]->filename // not null and not empty string
+ //&& 0 != strlen(children[i]->filename)
+ ) { // should not be necessary
+ //fprintf(fp, "// need an include for %s\n", children[i]->filename);
+ bool rddid = false;
+ sofar = includedfiles.size();
+
+ for (int j=0; j<sofar; j++) {
+ //fprintf(stderr, "comparing %s and %s\n", includedfiles[j], children[i]->filename );
+ if (!strcmp( includedfiles[j], children[i]->filename) ) { // this file has already been included
+ rddid = true;
+ //fprintf(stderr, "already did that one\n");
+ }
+ }
+
+ if (false == rddid) { // we need to include it now
+ fprintf(fp, "#include \"%s\"\n", children[i]->filename);
+ includedfiles.push_back(strdup( children[i]->filename ));
+ }
+ //else {
+ // fprintf(fp, "already did\n");
+ //}
+ }
+#endif // NOPE
+
+
+ }
+ }
+
+ fflush(fp);
+
+ //fprintf(fp, "\n\n// functions??\n");
+ //for (int i=0; i<functions.size(); i++) {
+ // fprintf(fp, "\n\n"); functions[i]->print(0,fp); fflush(fp);
+ //}
+};
+
+
+
+
+void chillAST_SourceFile::printToFile( char *filename ) {
+ char fn[1024];
+
+ if (NULL == filename) { // build up a filename using original name and frontend if known
+ if (FileToWrite) {
+ strcpy( fn, FileToWrite );
+ }
+ else {
+ // input name with name of frontend compiler prepended
+ if (frontend) sprintf(fn, "%s_%s\0", frontend, SourceFileName);
+ else sprintf(fn, "UNKNOWNFRONTEND_%s\0", SourceFileName); // should never happen
+ }
+ }
+ else strcpy( fn, filename );
+
+ FILE *fp = fopen(fn, "w");
+ if (!fp) {
+ fprintf(stderr, "can't open file '%s' for writing\n", fn);
+ exit(-1);
+ }
+
+ //fprintf(fp, "\n\n");
+ //dump(0, fp);
+ fprintf(fp, "\n\n");
+ print(0, fp);
+
+}
+
+
+
+void chillAST_SourceFile::dump( int indent, FILE *fp ) {
+ fflush(fp);
+ fprintf(fp, "\n//CHILL AST originally from file '%s'\n", SourceFileName);
+ int numchildren = children.size();
+ for (int i=0; i<numchildren; i++) {
+ children[i]->dump( indent, fp );
+ }
+ fflush(fp);
+};
+
+
+
+chillAST_MacroDefinition * chillAST_SourceFile::findMacro( const char *name ) {
+ //fprintf(stderr, "chillAST_SourceFile::findMacro( %s )\n", name );
+
+ int numMacros = macrodefinitions.size();
+ for (int i=0; i<numMacros; i++) {
+ if (!strcmp( macrodefinitions[i]->macroName, name )) return macrodefinitions[i];
+ }
+ return NULL; // not found
+}
+
+
+chillAST_FunctionDecl * chillAST_SourceFile::findFunction( const char *name ) {
+ //fprintf(stderr, "chillAST_SourceFile::findMacro( %s )\n", name );
+
+ int numFuncs = functions.size();
+ for (int i=0; i<numFuncs; i++) {
+ if ( !strcmp( functions[i]->functionName, name )) return functions[i];
+ }
+ return NULL;
+}
+
+
+chillAST_node *chillAST_SourceFile::findCall( const char *name ) {
+ chillAST_MacroDefinition *macro = findMacro( name );
+ if (macro) return (chillAST_node *)macro;
+ chillAST_FunctionDecl *func =findFunction( name );
+ return func;
+}
+
+
+chillAST_VarDecl * chillAST_SourceFile::findVariableNamed( const char *name ) {
+ fprintf(stderr, "SOURCEFILE SPECIAL %s findVariableNamed( %s )\n", getTypeString(), name );
+ if (hasSymbolTable()) { // look in my symbol table if I have one
+ fprintf(stderr, "%s has a symbol table\n", getTypeString());
+ chillAST_VarDecl *vd = symbolTableFindVariableNamed( getSymbolTable(), name);
+ if (vd) {
+ fprintf(stderr, "found it\n");
+ return vd; // found locally
+ }
+ fprintf(stderr, "%s has a symbol table but couldn't find %s\n", getTypeString(), name );
+ }
+
+ fprintf(stderr, "looking for %s in SourceFile global_symbol_table\n", name);
+ chillAST_VarDecl *vd = symbolTableFindVariableNamed( global_symbol_table, name );
+ if (vd) {
+ fprintf(stderr, "found it\n");
+ return vd; // found locally
+ }
+
+ if (!parent) {
+ fprintf(stderr, "%s has no parent\n", getTypeString());
+ return NULL; // no more recursion available
+ }
+ // recurse upwards
+ //fprintf(stderr, "recursing from %s up to parent %p\n", getTypeString(), parent);
+ fprintf(stderr, "recursing from %s up to parent\n", getTypeString());
+ return parent->findVariableNamed( name );
+}
+
+
+
+chillAST_TypedefDecl::chillAST_TypedefDecl() {
+ underlyingtype = newtype = arraypart = NULL;
+ asttype = CHILLAST_NODETYPE_TYPEDEFDECL;
+ parent = NULL;
+ metacomment = NULL;
+ isStruct = isUnion = false;
+ structname = NULL;
+ rd = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_TypedefDecl::chillAST_TypedefDecl(char *t, char *nt, chillAST_node *par) {
+ //fprintf(stderr, "chillAST_TypedefDecl::chillAST_TypedefDecl( underlying type %s, newtype %s )\n", t, nt);
+ underlyingtype = strdup(t);
+ newtype = strdup(nt);
+ arraypart = NULL;
+ asttype = CHILLAST_NODETYPE_TYPEDEFDECL;
+ parent = NULL;
+ metacomment = NULL;
+ isStruct = isUnion = false;
+ structname = NULL;
+ rd = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_TypedefDecl::chillAST_TypedefDecl(char *t, char *a, char *p, chillAST_node *par) {
+ underlyingtype = strdup(t);
+ //fprintf(stderr, "chillAST_TypedefDecl::chillAST_TypedefDecl( underlying type %s )\n", underlyingtype);
+ newtype = strdup(a); // the new named type ??
+
+ arraypart = strdup(p); // array (p)art?
+ // splitarraypart(); // TODO
+
+ asttype = CHILLAST_NODETYPE_TYPEDEFDECL;
+ parent = par;
+ metacomment = NULL;
+ isStruct = isUnion = false;
+ structname = NULL;
+ rd = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+
+
+void chillAST_TypedefDecl::print( int indent, FILE *fp ) {
+ //fprintf(fp, "typedefdecl->print()\n");
+
+ printPreprocBEFORE(indent, fp);
+
+ if (isStruct) {
+ fprintf(fp, "\n/* A typedef STRUCT */\n"); chillindent(indent, fp);
+ }
+
+ chillindent(indent, fp);
+ fprintf(fp, "typedef "); fflush(fp);
+
+ if (rd) {
+ rd->print(indent, fp); // needs to not print the ending semicolon ??
+ }
+
+ else if (isStruct) {
+ fprintf(stderr, "/* no rd */\n");
+
+ //fprintf(fp, "struct %s\n", structname);
+ chillindent(indent, fp);
+ fprintf(fp, "{\n");
+ for (int i=0; i<subparts.size(); i++) {
+ //fprintf(fp, "a %s\n", subparts[i]->getTypeString());
+ subparts[i]->print(indent+1, fp);
+ fprintf(fp, ";\n");
+ }
+ fprintf(fp, "};\n");
+ }
+ else {
+ fprintf(fp, "/* NOT A STRUCT */ typedef %s %s%s;\n", underlyingtype, newtype, arraypart );
+ dump(); printf("\n\n"); fflush(stdout);
+ }
+
+ // then the newname
+ fprintf(fp, "%s;\n", newtype);
+ fflush(fp);
+ printPreprocAFTER(indent, fp);
+
+ return;
+}
+
+
+chillAST_VarDecl *chillAST_TypedefDecl::findSubpart( const char *name ) {
+ //fprintf(stderr, "chillAST_TypedefDecl::findSubpart( %s )\n", name);
+ //fprintf(stderr, "typedef %s %s\n", structname, newtype);
+
+ if (rd) { // we have a record decl look there
+ chillAST_VarDecl *sub = rd->findSubpart( name );
+ //fprintf(stderr, "rd found subpart %p\n", sub);
+ return sub;
+ }
+
+ // can this ever happen now ???
+ int nsub = subparts.size();
+ //fprintf(stderr, "%d subparts\n", nsub);
+ for (int i=0; i<nsub; i++) {
+ if ( !strcmp( name, subparts[i]->varname )) return subparts[i];
+ }
+ //fprintf(stderr, "subpart not found\n");
+
+
+ return NULL;
+}
+
+
+chillAST_RecordDecl * chillAST_TypedefDecl::getStructDef() {
+ if (rd) return rd;
+ return NULL;
+}
+
+
+
+chillAST_RecordDecl::chillAST_RecordDecl() {
+ asttype = CHILLAST_NODETYPE_RECORDDECL;
+ name = strdup("unknown"); // ??
+ originalname = NULL; // ??
+ isStruct = isUnion = false;
+ parent = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_RecordDecl::chillAST_RecordDecl( const char *nam, chillAST_node *p ) {
+ //fprintf(stderr, "chillAST_RecordDecl::chillAST_RecordDecl()\n");
+ asttype = CHILLAST_NODETYPE_RECORDDECL;
+ parent = p;
+ if (nam) name = strdup(nam);
+ else name = strdup("unknown"); // ??
+ originalname = NULL; // ?? // make them do it manually?
+ isStruct = isUnion = false;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_RecordDecl::chillAST_RecordDecl( const char *nam, const char *orig, chillAST_node *p ) {
+ fprintf(stderr, "chillAST_RecordDecl::chillAST_RecordDecl( %s, ( AKA %s ) )\n", nam, orig);
+ asttype = CHILLAST_NODETYPE_RECORDDECL;
+ parent = p;
+ if (p) p->addChild( this );
+
+ if (nam) name = strdup(nam);
+ else name = strdup("unknown"); // ??
+
+ originalname = NULL;
+ if (orig) originalname = strdup(orig);
+
+ isStruct = isUnion = false;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+
+chillAST_VarDecl * chillAST_RecordDecl::findSubpart( const char *nam ){
+ //fprintf(stderr, "chillAST_RecordDecl::findSubpart( %s )\n", nam);
+ int nsub = subparts.size();
+ //fprintf(stderr, "%d subparts\n", nsub);
+ for (int i=0; i<nsub; i++) {
+ //fprintf(stderr, "comparing to '%s' to '%s'\n", nam, subparts[i]->varname);
+ if ( !strcmp( nam, subparts[i]->varname )) return subparts[i];
+ }
+ fprintf(stderr, "chillAST_RecordDecl::findSubpart() couldn't find member NAMED %s in ", nam); print(); printf("\n\n"); fflush(stdout);
+
+ return NULL;
+}
+
+
+chillAST_VarDecl * chillAST_RecordDecl::findSubpartByType( const char *typ ){
+ //fprintf(stderr, "chillAST_RecordDecl::findSubpart( %s )\n", nam);
+ int nsub = subparts.size();
+ //fprintf(stderr, "%d subparts\n", nsub);
+ for (int i=0; i<nsub; i++) {
+ //fprintf(stderr, "comparing '%s' to '%s'\n", typ, subparts[i]->vartype);
+ if ( !strcmp( typ, subparts[i]->vartype )) return subparts[i];
+ }
+ //fprintf(stderr, "chillAST_RecordDecl::findSubpart() couldn't find member of TYPE %s in ", typ); print(); printf("\n\n"); fflush(stdout);
+
+ return NULL;
+}
+
+
+void chillAST_RecordDecl::print( int indent, FILE *fp ) {
+ //fprintf(fp, "chillAST_RecordDecl::print()\n");
+ if (isUnnamed) return;
+
+ printPreprocBEFORE(indent, fp);
+
+ chillindent(indent, fp);
+ if (isStruct) {
+ //fprintf(fp, "\n/* A Record Decl STRUCT */\n"); chillindent(indent, fp);
+ fprintf(fp, "struct ");
+ if ( strncmp( "unnamed", name, 7) ) fprintf(fp, "%s\n", name);
+
+ chillindent(indent, fp);
+ fprintf(fp, "{\n");
+ for (int i=0; i<subparts.size(); i++) {
+ //fprintf(fp, "a %s\n", subparts[i]->getTypeString());
+ subparts[i]->print(indent+1, fp);
+ fprintf(fp, ";\n");
+ }
+ fprintf(fp, "} ");
+ fprintf(fp, "\n"); // TODO need semicolon when defining struct. can't have it when part of a typedef. One of the following lines is correct in each case.
+ //fprintf(fp, ";\n");
+ }
+ else {
+ fprintf(fp, "/* UNKNOWN RECORDDECL print() */ ");
+ exit(-1);
+ }
+ printPreprocAFTER(indent, fp);
+ fflush(fp);
+}
+
+
+chillAST_SymbolTable * chillAST_RecordDecl::addVariableToSymbolTable( chillAST_VarDecl *vd ){
+ // for now, just bail. or do we want the struct to have an actual symbol table?
+ //fprintf(stderr, "chillAST_RecordDecl::addVariableToSymbolTable() ignoring struct member %s vardecl\n", vd->varname);
+ return NULL; // damn, I hope nothing uses this!
+}
+
+void chillAST_RecordDecl::printStructure( int indent, FILE *fp ) {
+ //fprintf(stderr, "chillAST_RecordDecl::printStructure()\n");
+ chillindent(indent, fp);
+ if (isStruct) {
+ fprintf(fp, "struct { ", name);
+ for (int i=0; i<subparts.size(); i++) {
+ subparts[i]->print( 0, fp); // ?? TODO indent level
+ fprintf(fp, "; ");
+ }
+ fprintf(fp, "} ");
+ }
+ else {
+ fprintf(fp, "/* UNKNOWN RECORDDECL printStructure() */ ");
+ exit(-1);
+ }
+ fflush(fp);
+}
+
+
+
+void chillAST_RecordDecl::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+
+}
+
+
+chillAST_FunctionDecl::chillAST_FunctionDecl() {
+ functionName = strdup("YouScrewedUp");
+ asttype = CHILLAST_NODETYPE_FUNCTIONDECL;
+ forwarddecl = externfunc = builtin = false;
+ uniquePtr = (void *) NULL;
+ this->setFunctionCPU();
+ parent = NULL;
+ metacomment = NULL;
+ //symbol_table = NULL; // eventually, pointing to body's symbol table
+ typedef_table = NULL;
+ body = new chillAST_CompoundStmt();
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_FunctionDecl::chillAST_FunctionDecl(const char *rt, const char *fname, chillAST_node *par) {
+ returnType = strdup(rt);
+ functionName = strdup(fname);
+ this->setFunctionCPU();
+ //fprintf(stderr, "functionName %s\n", functionName);
+ forwarddecl = externfunc = builtin = false;
+
+ asttype = CHILLAST_NODETYPE_FUNCTIONDECL;
+ parent = par;
+ metacomment = NULL;
+ if (par) par->getSourceFile()->addFunc( this );
+ // symbol_table = NULL; //use body's instead
+ typedef_table = NULL;
+ body = new chillAST_CompoundStmt();
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_FunctionDecl::chillAST_FunctionDecl(const char *rt, const char *fname, chillAST_node *par, void *unique) {
+ fprintf(stderr, "chillAST_FunctionDecl::chillAST_FunctionDecl with unique %p\n", unique);
+ returnType = strdup(rt);
+ functionName = strdup(fname);
+ this->setFunctionCPU();
+ //fprintf(stderr, "functionName %s\n", functionName);
+ forwarddecl = externfunc = builtin = false;
+
+ body = new chillAST_CompoundStmt();
+ asttype = CHILLAST_NODETYPE_FUNCTIONDECL;
+ uniquePtr = unique; // a quick way to check equivalence. DO NOT ACCESS THROUGH THIS
+ parent = par;
+ metacomment = NULL;
+ if (par) par->getSourceFile()->addFunc( this );
+ //symbol_table = NULL; // use body's
+ typedef_table = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+void chillAST_FunctionDecl::addParameter( chillAST_VarDecl *p) {
+ fprintf(stderr, "%s chillAST_FunctionDecl::addParameter( 0x%x param %s) total of %d parameters\n", functionName, p, p->varname, 1+parameters.size());
+
+ if (symbolTableHasVariableNamed( &parameters, p->varname)) { // NOT recursive. just in FunctionDecl
+ fprintf(stderr, "chillAST_FunctionDecl::addParameter( %s ), parameter already exists?\n", p->varname);
+ // exit(-1); // ??
+ return; // error?
+ }
+
+ parameters.push_back(p);
+ //addSymbolToTable( parameters, p );
+ fprintf(stderr, "setting %s isAParameter\n", p->varname);
+ p->isAParameter = true;
+
+ p->setParent( this ); // ?? unclear TODO
+ //p->dump(); printf("\naddparameter done\n\n"); fflush(stdout);
+}
+
+
+
+void chillAST_FunctionDecl::addDecl( chillAST_VarDecl *vd) { // to symbol table ONLY
+ fprintf(stderr, "chillAST_FunctionDecl::addDecl( %s )\n", vd->varname);
+ if (!body) {
+ //fprintf(stderr, "had no body\n");
+ body = new chillAST_CompoundStmt();
+
+ //body->symbol_table = symbol_table; // probably wrong if this ever does something
+ }
+
+ //fprintf(stderr, "before body->addvar(), func symbol table had %d entries\n", symbol_table->size());
+ //fprintf(stderr, "before body->addvar(), body symbol table was %p\n", body->symbol_table);
+ //fprintf(stderr, "before body->addvar(), body symbol table had %d entries\n", body->symbol_table->size());
+ //adds to body symbol table, and makes sure function has a copy. probably dumb
+ body->symbol_table = body->addVariableToSymbolTable( vd );
+ //fprintf(stderr, "after body->addvar(), func symbol table had %d entries\n", symbol_table->size());
+}
+
+chillAST_VarDecl *chillAST_FunctionDecl::hasParameterNamed( const char *name ) {
+ int numparams = parameters.size();
+ for (int i=0; i<numparams; i++) {
+ if (!strcmp(name, parameters[i]->varname)) return parameters[i]; // need to check type?
+ }
+ return NULL;
+}
+
+
+// similar to symbolTableHasVariableNamed() but returns the variable definition
+chillAST_VarDecl *chillAST_FunctionDecl::funcHasVariableNamed( const char *name ) { // NOT recursive
+ //fprintf(stderr, "chillAST_FunctionDecl::funcHasVariableNamed( %s )\n", name );
+
+ // first check the parameters
+ int numparams = parameters.size();
+ for (int i=0; i<numparams; i++) {
+ chillAST_VarDecl *vd = parameters[i];
+ if (!strcmp(name, vd->varname)) {
+ //fprintf(stderr, "yep, it's parameter %d\n", i);
+ return vd; // need to check type?
+ }
+ }
+ //fprintf(stderr, "no parameter named %s\n", name);
+
+ chillAST_SymbolTable *st = getSymbolTable();
+ if (!st) {
+ fprintf(stderr,"and no symbol_table, so no variable named %s\n", name);
+ return NULL; // no symbol table so no variable by that name
+ }
+
+
+ int numvars = st->size();
+ //fprintf(stderr, "checking against %d variables\n", numvars);
+ for (int i=0; i<numvars; i++) {
+ chillAST_VarDecl *vd = (*st)[i];
+ //fprintf(stderr, "comparing '%s' to '%s'\n", name, vd->varname);
+ if (!strcmp(name, vd->varname)) {
+ //fprintf(stderr, "yep, it's variable %d\n", i);
+ fprintf(stderr, "%s was already defined in the function body\n", vd->varname);
+ return vd; // need to check type?
+ }
+ }
+ fprintf(stderr, "not a parameter or variable named %s\n", name);
+ return NULL;
+}
+
+
+
+
+void chillAST_FunctionDecl::setBody( chillAST_node * bod ) {
+ //fprintf(stderr, "%s chillAST_FunctionDecl::setBody( 0x%x ) total of %d children\n", functionName, bod, 1+children.size());
+ if (bod->isCompoundStmt()) body = (chillAST_CompoundStmt *)bod;
+ else {
+ body = new chillAST_CompoundStmt();
+ body->addChild( bod );
+ }
+ //symbol_table = body->getSymbolTable();
+ //addChild(bod);
+ bod->setParent( this ); // well, ...
+}
+
+
+void chillAST_FunctionDecl::insertChild(int i, chillAST_node* node) {
+ fprintf(stderr, "chillAST_FunctionDecl::insertChild() "); node->print(0,stderr); fprintf(stderr, "\n\n");
+ body->insertChild( i, node );
+
+ if (node->isVarDecl()) {
+ chillAST_VarDecl *vd = ((chillAST_VarDecl *) node);
+ fprintf(stderr, "functiondecl %s inserting a VarDecl named %s\n", functionName, vd->varname);
+ chillAST_SymbolTable *st = getSymbolTable();
+ if (!st) {
+ fprintf(stderr, "symbol table is NULL!\n");
+ }
+ else {
+ fprintf(stderr, "%d entries in the symbol table\n", st->size());
+ printSymbolTable( getSymbolTable() );
+ }
+ fprintf(stderr, "\n\n");
+ }
+}
+
+void chillAST_FunctionDecl::addChild(chillAST_node* node) {
+ fprintf(stderr, "chillAST_FunctionDecl::addChild( ) "); node->print(0,stderr); fprintf(stderr, "\n\n");
+ if (node->isVarDecl()) {
+ chillAST_VarDecl *vd = ((chillAST_VarDecl *) node);
+ fprintf(stderr, "functiondecl %s adding a VarDecl named %s\n", functionName, vd->varname);
+ }
+
+ body->addChild( node );
+ node->parent = this; // this, or body??
+}
+
+
+void chillAST_FunctionDecl::printParameterTypes( FILE *fp ) { // also prints names
+ //fprintf(stderr, "\n\n%s chillAST_FunctionDecl::printParameterTypes()\n", functionName);
+ fprintf(fp, "( ");
+ int numparameters = parameters.size();
+ for (int i=0; i<numparameters; i++) {
+ if (i!=0) fprintf(fp, ", ");
+ chillAST_VarDecl *p = parameters[i];
+ p->print(0, fp); // note: no indent, as this is in the function parens
+ }
+ fprintf(fp, " )"); // end of input parameters
+
+}
+
+
+
+
+void chillAST_FunctionDecl::print( int indent, FILE *fp ) {
+ //fprintf(fp, "\n// functiondecl %p \n", this);
+ //chillindent(indent, fp);
+ //fprintf(fp, "//(functiondecl) %d parameters\n", numparameters);
+
+ printPreprocBEFORE(indent, fp);
+
+ fprintf(fp, "\n");
+ chillindent(indent, fp);
+
+ if (externfunc) fprintf(fp, "extern ");
+
+ if (function_type == CHILL_FUNCTION_GPU) fprintf(fp, "__global__ ");
+ fprintf(fp, "%s %s", returnType, functionName );
+ printParameterTypes(fp);
+
+
+
+ // non-parameter variables (now must have explicit vardecl in the body)
+ //int numvars = symbol_table.size();
+ //for (int i=0; i<numvars; i++) {
+ // symbol_table[i]->print(1,fp);
+ // fprintf(fp, ";\n");
+ //}
+
+ // now the body
+ if (!(externfunc || forwarddecl)) {
+ if (body) {
+ fprintf(fp, "\n{\n");
+ //chillindent(indent+1, fp); fprintf(fp, "//body\n"); fflush(fp);
+ body->print( indent+1, fp);
+ fprintf(fp, "\n");
+ //chillindent(indent+1, fp); fprintf(fp, "//END body\n"); fflush(fp);
+
+ // tidy up
+ chillindent(indent, fp);
+ fprintf(fp, "}\n");
+ } // if body
+ else {
+ fprintf(fp, "{}\n"); // should never happen, but not external and no body
+ }
+ }
+ else { // extern func or forward decl. just end forward declaration
+ fprintf(fp, "; // fwd decl\n");
+ }
+
+ printPreprocAFTER(indent, fp);
+
+ fflush(fp);
+}
+
+
+
+void chillAST_FunctionDecl::dump( int indent, FILE *fp ) {
+ fprintf(fp, "\n");
+ fprintf(fp, "// isFromSourceFile ");
+ if (filename) fprintf(fp, "%s ", filename);
+ if (isFromSourceFile) fprintf(fp, "true\n");
+ else fprintf(fp, "false\n");
+ chillindent(indent, fp);
+ fprintf(fp, "(FunctionDecl %s %s(", returnType, functionName );
+
+ int numparameters = parameters.size();
+ for (int i=0; i<numparameters; i++) {
+ if (i!=0) fprintf(fp, ", ");
+ chillAST_VarDecl *p = parameters[i];
+ //fprintf(stderr, "param type %s vartype %s\n", p->getTypeString(), p->vartype);
+ p->print(0, fp); // note: no indent, as this is in the function parens, ALSO print, not dump
+ }
+ fprintf(fp, ")\n"); // end of input parameters
+
+ // now the body -
+ if (body) body->dump( indent+1 , fp);
+
+ // tidy up
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+
+
+
+
+
+void chillAST_FunctionDecl::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_FunctionDecl::gatherVarDecls()\n");
+ //if (0 < children.size()) fprintf(stderr, "functiondecl has %d children\n", children.size());
+ //fprintf(stderr, "functiondecl has %d parameters\n", numParameters());
+ for (int i=0; i<numParameters(); i++) parameters[i]->gatherVarDecls( decls );
+ //fprintf(stderr, "after parms, %d decls\n", decls.size());
+ for (int i=0; i<children.size(); i++) children[i]->gatherVarDecls( decls );
+ //fprintf(stderr, "after children, %d decls\n", decls.size());
+ body->gatherVarDecls( decls ); // todo, figure out if functiondecl has actual children
+ //fprintf(stderr, "after body, %d decls\n", decls.size());
+ //for (int d=0; d<decls.size(); d++) {
+ // decls[d]->print(0,stderr); fprintf(stderr, "\n");
+ //}
+}
+
+
+void chillAST_FunctionDecl::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //if (0 < children.size()) fprintf(stderr, "functiondecl has %d children\n", children.size());
+
+ for (int i=0; i<numParameters(); i++) parameters[i]->gatherScalarVarDecls( decls );
+ for (int i=0; i<children.size(); i++) children[i]->gatherScalarVarDecls( decls );
+ body->gatherScalarVarDecls( decls ); // todo, figure out if functiondecl has actual children
+}
+
+
+void chillAST_FunctionDecl::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //if (0 < children.size()) fprintf(stderr, "functiondecl has %d children\n", children.size());
+
+ for (int i=0; i<numParameters(); i++) parameters[i]->gatherArrayVarDecls( decls );
+ for (int i=0; i<children.size(); i++) children[i]->gatherArrayVarDecls( decls );
+ body->gatherArrayVarDecls( decls ); // todo, figure out if functiondecl has actual children
+}
+
+
+chillAST_VarDecl *chillAST_FunctionDecl::findArrayDecl( const char *name ) {
+ //fprintf(stderr, "chillAST_FunctionDecl::findArrayDecl( %s )\n", name );
+ chillAST_VarDecl *p = hasParameterNamed( name );
+ //if (p) fprintf(stderr, "function %s has parameter named %s\n", functionName, name );
+ if (p && p->isArray()) return p;
+
+ chillAST_VarDecl *v = funcHasVariableNamed ( name );
+ //if (v) fprintf(stderr, "function %s has symbol table variable named %s\n", functionName, name );
+ if (v && v->isArray()) return v;
+
+ // declared variables that may not be in symbol table but probably should be
+ vector<chillAST_VarDecl*> decls ;
+ gatherArrayVarDecls( decls );
+ for (int i=0; i<decls.size(); i++) {
+ chillAST_VarDecl *vd = decls[i];
+ if (0 == strcmp(vd->varname, name ) && vd->isArray()) return vd;
+ }
+
+ //fprintf(stderr, "can't find array named %s in function %s \n", name, functionName);
+ return NULL;
+}
+
+
+void chillAST_FunctionDecl::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherVarUsage( decls );
+ body->gatherVarUsage( decls ); // todo, figure out if functiondecl has actual children
+}
+
+
+void chillAST_FunctionDecl::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherDeclRefExprs( refs );
+ body->gatherDeclRefExprs( refs ); // todo, figure out if functiondecl has actual children
+}
+
+
+
+void chillAST_FunctionDecl::cleanUpVarDecls() {
+ //fprintf(stderr, "\ncleanUpVarDecls() for function %s\n", functionName);
+ vector<chillAST_VarDecl*> used;
+ vector<chillAST_VarDecl*> defined;
+ vector<chillAST_VarDecl*> deletethese;
+
+ gatherVarUsage( used );
+ gatherVarDecls( defined );
+
+ //fprintf(stderr, "\nvars used: \n");
+ //for ( int i=0; i< used.size(); i++) {
+ //used[i]->print(0, stderr); fprintf(stderr, "\n");
+ //}
+ //fprintf(stderr, "\n");
+ //fprintf(stderr, "\nvars defined: \n");
+ //for ( int i=0; i< defined.size(); i++) {
+ // defined[i]->print(0, stderr); fprintf(stderr, "\n");
+ //}
+ //fprintf(stderr, "\n");
+
+ for ( int j=0; j < defined.size(); j++) {
+ //fprintf(stderr, "j %d defined %s\n", j, defined[j]->varname);
+ bool definedandused = false;
+ for ( int i=0; i < used.size(); i++) {
+ if (used[i] == defined[j]) {
+ //fprintf(stderr, "i %d used %s\n", i, used[i]->varname);
+ //fprintf(stderr, "\n");
+ definedandused = true;
+ break;
+ }
+ }
+
+ if (!definedandused) {
+ if ( defined[j]->isParmVarDecl() ) {
+ //fprintf(stderr, "we'd remove %s except that it's a parameter. Maybe someday\n", defined[j]->varname);
+ }
+ else {
+ //fprintf(stderr, "we can probably remove the definition of %s\n", defined[j]->varname);
+ deletethese.push_back( defined[j] );
+ }
+ }
+ }
+
+
+ //fprintf(stderr, "deleting %d vardecls\n", deletethese.size());
+ for (int i=0; i<deletethese.size(); i++) {
+ //fprintf(stderr, "deleting varDecl %s\n", deletethese[i]->varname);
+ chillAST_node *par = deletethese[i]->parent;
+ par->removeChild( par->findChild( deletethese[i] ));
+ }
+
+
+ //fprintf(stderr, "\n\nnow check for vars used but not defined\n");
+ // now check for vars used but not defined?
+ for ( int j=0; j < used.size(); j++) {
+ //fprintf(stderr, "%s is used\n", used[j]->varname);
+ bool definedandused = false;
+ for ( int i=0; i < defined.size(); i++) {
+ if (used[j] == defined[i]) {
+ //fprintf(stderr, "%s is defined\n", defined[i]->varname);
+ definedandused = true;
+ break;
+ }
+ }
+ if (!definedandused) {
+ //fprintf(stderr, "%s is used but not defined?\n", used[j]->varname);
+ // add it to the beginning of the function
+ insertChild(0, used[j]);
+ }
+ }
+
+}
+
+//void chillAST_FunctionDecl::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl ) {
+// for (int i=0; i<children.size(); i++) children[i]->replaceVarDecls( olddecl, newdecl );
+//}
+
+
+bool chillAST_FunctionDecl::findLoopIndexesToReplace( chillAST_SymbolTable *symtab, bool forcesync ) {
+ if (body) body->findLoopIndexesToReplace( symtab, false );
+ return false;
+}
+
+
+
+ chillAST_node *chillAST_FunctionDecl::constantFold() {
+ //fprintf(stderr, "chillAST_FunctionDecl::constantFold()\n");
+ // parameters can't have constants?
+ int numparameters = parameters.size();
+ for (int i=0; i<numparameters; i++) {
+ parameters[i]->constantFold();
+ }
+ if (body) body = (chillAST_CompoundStmt *)body->constantFold();
+ return this;
+ }
+
+
+chillAST_MacroDefinition::chillAST_MacroDefinition() {
+ macroName = strdup("UNDEFINEDMACRO");
+ rhsString = NULL;
+ asttype = CHILLAST_NODETYPE_MACRODEFINITION;
+ parent = NULL;
+ metacomment = NULL;
+ symbol_table = NULL;
+ //rhsideString = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_MacroDefinition::chillAST_MacroDefinition(const char *mname, chillAST_node *par) {
+ macroName = strdup(mname);
+ rhsString = NULL;
+ asttype = CHILLAST_NODETYPE_MACRODEFINITION;
+ parent = par;
+ metacomment = NULL;
+ symbol_table = NULL;
+ //rhsideString = NULL;
+
+ if (par) par->getSourceFile()->addMacro( this );
+
+ //fprintf(stderr, "chillAST_MacroDefinition::chillAST_MacroDefinition( %s, ", mname);
+ //if (par) fprintf(stderr, " parent NOT NULL);\n");
+ //else fprintf(stderr, " parent NULL);\n");
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_MacroDefinition::chillAST_MacroDefinition(const char *mname, const char *rhs, chillAST_node *par) {
+ macroName = strdup(mname);
+ rhsString = strdup(rhs);
+ asttype = CHILLAST_NODETYPE_MACRODEFINITION;
+ parent = par;
+ metacomment = NULL;
+ symbol_table = NULL;
+
+ if (par) par->getSourceFile()->addMacro( this );
+
+ //fprintf(stderr, "chillAST_MacroDefinition::chillAST_MacroDefinition( %s, ", mname);
+ //if (par) fprintf(stderr, " parent NOT NULL);\n");
+ //else fprintf(stderr, " parent NULL);\n");
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+chillAST_node* chillAST_MacroDefinition::clone() {
+
+ // TODO ?? cloning a macro makes no sense
+ return this;
+#ifdef CONFUSED
+
+ //fprintf(stderr, "chillAST_MacroDefinition::clone() for %s\n", macroName);
+ chillAST_MacroDefinition *clo = new chillAST_MacroDefinition( macroName, parent);
+ for (int i=0; i<parameters.size(); i++) clo->addParameter( parameters[i] );
+ clo->setBody( body->clone() );
+ return clo;
+#endif
+
+}
+
+
+void chillAST_MacroDefinition::setBody( chillAST_node * bod ) {
+ fprintf(stderr, "%s chillAST_MacroDefinition::setBody( 0x%x )\n", macroName, bod);
+ body = bod;
+ fprintf(stderr, "body is:\n"); body->print(0,stderr); fprintf(stderr, "\n\n");
+ rhsString = body->stringRep();
+ bod->setParent( this ); // well, ...
+}
+
+
+void chillAST_MacroDefinition::addParameter( chillAST_VarDecl *p) {
+ //fprintf(stderr, "%s chillAST_MacroDefinition::addParameter( 0x%x ) total of %d children\n", functionName, p, 1+children.size());
+ parameters.push_back(p);
+ fprintf(stderr, "macro setting %s isAParameter\n", p->varname);
+ p->isAParameter = true;
+ p->setParent( this );
+
+ addVariableToSymbolTable( p );
+}
+
+
+chillAST_VarDecl *chillAST_MacroDefinition::hasParameterNamed( const char *name ) {
+ int numparams = parameters.size();
+ for (int i=0; i<numparams; i++) {
+ if (!strcmp(name, parameters[i]->varname)) return parameters[i]; // need to check type?
+ }
+ return NULL;
+}
+
+
+void chillAST_MacroDefinition::insertChild(int i, chillAST_node* node) {
+ body->insertChild( i, node );
+}
+
+void chillAST_MacroDefinition::addChild(chillAST_node* node) {
+ body->addChild( node );
+ node->parent = this; // this, or body??
+}
+
+
+void chillAST_MacroDefinition::dump( int indent, FILE *fp ) {
+ fprintf(fp, "\n");
+ chillindent(indent, fp);
+ fprintf(fp, "(MacroDefinition %s(", macroName);
+ for (int i=0; i<numParameters(); i++) {
+ fprintf(fp, "\n");
+ chillindent(indent+1, fp);
+ fprintf(fp, "(%s)", parameters[i]->varname);
+ }
+ fprintf(fp, ")\n");
+ body->dump( indent+1, fp);
+ if (rhsString) fprintf(fp, " (aka %s)");
+ fprintf(fp, "\n");
+ fflush(fp);
+}
+
+
+void chillAST_MacroDefinition::print( int indent, FILE *fp ) { // UHOH TODO
+ //fprintf(fp, "\n"); // ignore indentation
+ //fprintf(stderr, "macro has %d parameters\n", numParameters());
+
+ printPreprocBEFORE(indent, fp);
+
+ fprintf(fp, "#define %s", macroName);
+ if (0 != numParameters()) {
+ fprintf(fp, "(");
+ for (int i=0; i<numParameters(); i++) {
+ if (i) fprintf(fp, ",");
+ fprintf(fp, "%s", parameters[i]->varname);
+ }
+ fprintf(fp, ") ");
+ }
+
+ if (body) body->print(0, fp); // TODO should force newlines out of multiline macros
+ fprintf(fp, "\n");
+}
+
+
+
+
+chillAST_ForStmt::chillAST_ForStmt() {
+ init = cond = incr = NULL;
+ body = new chillAST_CompoundStmt();
+
+ asttype = CHILLAST_NODETYPE_LOOP; // breaking with tradition, this was CHILL_AST_FORSTMT
+ conditionoperator = IR_COND_UNKNOWN;
+ parent = NULL;
+ metacomment = NULL;
+ symbol_table = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+chillAST_ForStmt::chillAST_ForStmt( chillAST_node *ini, chillAST_node *con, chillAST_node *inc, chillAST_node *bod, chillAST_node *par) {
+ parent = par;
+ metacomment = NULL;
+ init = ini;
+ cond = con;
+ incr = inc;
+ body = bod;
+ init->setParent( this );
+ cond->setParent( this );
+ incr->setParent( this );
+
+ //fprintf(stderr, "chillAST_ForStmt::chillAST_ForStmt() bod %p\n", bod);
+
+ if (body) body->setParent( this ); // not sure this should be legal
+
+ asttype = CHILLAST_NODETYPE_LOOP; // breaking with tradition, this was CHILL_AST_FORSTMT
+
+ if (!cond->isBinaryOperator()) {
+ fprintf(stderr, "ForStmt conditional is of type %s. Expecting a BinaryOperator\n", cond->getTypeString());
+ exit(-1);
+ }
+ chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *)cond;
+ char *condstring = bo->op;
+ if (!strcmp(condstring, "<")) conditionoperator = IR_COND_LT;
+ else if (!strcmp(condstring, "<=")) conditionoperator = IR_COND_LE;
+ else if (!strcmp(condstring, ">")) conditionoperator = IR_COND_GT;
+ else if (!strcmp(condstring, ">=")) conditionoperator = IR_COND_GE;
+ else {
+ fprintf(stderr, "ForStmt, illegal/unhandled end condition \"%s\"\n", condstring);
+ fprintf(stderr, "currently can only handle <, >, <=, >=\n");
+ exit(1);
+ }
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+bool chillAST_ForStmt::lowerBound( int &l ) { // l is an output (passed as reference)
+
+ // above, cond must be a binaryoperator ... ???
+ if (conditionoperator == IR_COND_LT ||
+ conditionoperator == IR_COND_LE ) {
+
+ // lower bound is rhs of init
+ if (!init->isBinaryOperator()) {
+ fprintf(stderr, "chillAST_ForStmt::lowerBound() init is not a chillAST_BinaryOperator\n");
+ exit(-1);
+ }
+
+ chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *)init;
+ if (!init->isAssignmentOp()) {
+ fprintf(stderr, "chillAST_ForStmt::lowerBound() init is not an assignment chillAST_BinaryOperator\n");
+ exit(-1);
+ }
+
+ //fprintf(stderr, "rhs "); bo->rhs->print(0,stderr); fprintf(stderr, " ");
+ l = bo->rhs->evalAsInt(); // float could be legal I suppose
+ //fprintf(stderr, " %d\n", l);
+ return true;
+ }
+ else if (conditionoperator == IR_COND_GT ||
+ conditionoperator == IR_COND_GE ) { // decrementing
+ // lower bound is rhs of cond (not init)
+ chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *)cond;
+ l = bo->rhs->evalAsInt(); // float could be legal I suppose
+ return true;
+ }
+
+ // some case we don't handle ??
+ fprintf(stderr, "chillAST_ForStmt::lowerBound() can't find lower bound of ");
+ print(0,stderr);
+ fprintf(stderr, "\n\n");
+ return false; // or exit ???
+}
+
+
+bool chillAST_ForStmt::upperBound( int &u ) { // u is an output (passed as reference)
+
+ // above, cond must be a binaryoperator ... ???
+ if (conditionoperator == IR_COND_GT ||
+ conditionoperator == IR_COND_GE ) { // decrementing
+
+ // upper bound is rhs of init
+ if (!init->isBinaryOperator()) {
+ fprintf(stderr, "chillAST_ForStmt::upperBound() init is not a chillAST_BinaryOperator\n");
+ exit(-1);
+ }
+
+ chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *)init;
+ if (!init->isAssignmentOp()) {
+ fprintf(stderr, "chillAST_ForStmt::upperBound() init is not an assignment chillAST_BinaryOperator\n");
+ exit(-1);
+ }
+
+ u = bo->rhs->evalAsInt(); // float could be legal I suppose
+ return true;
+ }
+ else if (conditionoperator == IR_COND_LT ||
+ conditionoperator == IR_COND_LE ) {
+ //fprintf(stderr, "upper bound is rhs of cond ");
+ // upper bound is rhs of cond (not init)
+ chillAST_BinaryOperator *bo = (chillAST_BinaryOperator *)cond;
+ //bo->rhs->print(0,stderr);
+ u = bo->rhs->evalAsInt(); // float could be legal I suppose
+
+ if (conditionoperator == IR_COND_LT) u -= 1;
+
+ //fprintf(stderr, " %d\n", u);
+ return true;
+ }
+
+ // some case we don't handle ??
+ fprintf(stderr, "chillAST_ForStmt::upperBound() can't find upper bound of ");
+ print(0,stderr);
+ fprintf(stderr, "\n\n");
+ return false; // or exit ???
+}
+
+
+
+
+void chillAST_ForStmt::printControl( int in, FILE *fp ) {
+ chillindent(in, fp);
+ fprintf(fp, "for (");
+ init->print(0, fp);
+ fprintf(fp, "; ");
+ cond->print(0, fp);
+ fprintf(fp, "; ");
+ incr->print(0, fp);
+ fprintf(fp, ")");
+ fflush(fp);
+}
+
+
+void chillAST_ForStmt::print( int indent, FILE *fp ) {
+ printPreprocBEFORE(indent, fp);
+ //fprintf(fp, "chillAST_ForStmt::print()\n");
+ if (metacomment) {
+ chillindent(indent, fp);
+ //for(int i=0; i<indent; i++) fprintf(fp, "..");
+ fprintf(fp, "// %s\n", metacomment);
+ }
+
+ printControl(indent, fp); // does not do a newline or bracket
+ fprintf(fp, " {\n");
+
+
+ // I have no idea what made me do this next bit.
+ // A forstmt with compounds inside compounds ???
+ // this should probably all go away
+
+ chillAST_node *b = body;
+ //fprintf(fp, "b children %d\n", b->getNumChildren());
+ //fprintf(fp, "body child 0 of type %s\n", b->children[0]->getTypeString());
+ //fprintf(stderr, "forstmt body type %s\n", Chill_AST_Node_Names[b->asttype] );
+ // deal with a tree of compound statements, in an ugly way. leave the ugliness
+ while (1 == b->getNumChildren() && b->children[0]->isCompoundStmt()) {
+ b = b->children[0];
+ }
+
+
+ // this was to sometimes not enclose in a bracket. stupid. always enclose in a bracket.
+ //if (1 == b->getNumChildren() && b->children[0]->isForStmt()) fprintf(fp, ") {\n" );
+ //else if (1 == b->getNumChildren() ) fprintf(fp, ") { ?? \n" ); // to allow for() for( ) to not have open bracket?
+ //else {
+ //fprintf(fp, ")\n");
+ //chillindent(in, fp);
+ //fprintf(fp, "{\n" );
+
+ //fprintf(fp, ")");
+ //}
+
+ b->print(indent+1, fp );
+
+ // I think this can't happen any more. body is always a compound statement
+ if (b->asttype == CHILLAST_NODETYPE_BINARYOPERATOR) { // a single assignment statement
+ fprintf(fp, ";\n");
+ }
+
+ // always print brackets
+
+ //if ((1 == b->getNumChildren() && b->children[0]->isForStmt()) ||
+ // (1 != b->getNumChildren() )) {
+ chillindent(indent, fp);
+ fprintf(fp, "}\n" );
+ //}
+
+ printPreprocAFTER(indent, fp);
+ fflush(fp); //
+}
+
+void chillAST_ForStmt::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(ForStmt \n");
+
+ init->dump(indent+1, fp);
+ cond->dump(indent+1, fp);
+ incr->dump(indent+1, fp);
+ body->dump(indent+1, fp);
+
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+}
+
+chillAST_node *chillAST_ForStmt::constantFold() {
+ init = init->constantFold();
+ cond = cond->constantFold();
+ incr = incr->constantFold();
+ body = body->constantFold();
+ return this;
+ }
+
+
+ chillAST_node *chillAST_ForStmt::clone() {
+ chillAST_ForStmt *fs = new chillAST_ForStmt( init->clone(), cond->clone(), incr->clone(), body->clone(), parent);
+ fs->isFromSourceFile = isFromSourceFile;
+ if (filename) fs->filename = strdup(filename);
+ return fs;
+ }
+
+void chillAST_ForStmt::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_ForStmt::gatherVarDecls()\n");
+ //fprintf(stderr, "chillAST_ForStmt::gatherVarDecls() before %d\n", decls.size());
+ // TODO clear a loop_var_decls variable and then walk it ?
+ init->gatherVarDecls( decls );
+ cond->gatherVarDecls( decls );
+ incr->gatherVarDecls( decls );
+ body->gatherVarDecls( decls );
+ //fprintf(stderr, "after %d\n", decls.size());
+}
+
+void chillAST_ForStmt::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_ForStmt::gatherScalarVarDecls() before %d\n", decls.size());
+ init->gatherScalarVarDecls( decls );
+ cond->gatherScalarVarDecls( decls );
+ incr->gatherScalarVarDecls( decls );
+ body->gatherScalarVarDecls( decls );
+}
+
+void chillAST_ForStmt::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_ForStmt::gatherArrayVarDecls() before %d\n", decls.size());
+ init->gatherArrayVarDecls( decls );
+ cond->gatherArrayVarDecls( decls );
+ incr->gatherArrayVarDecls( decls );
+ body->gatherArrayVarDecls( decls );
+}
+
+void chillAST_ForStmt::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ init->gatherArrayRefs( refs, 0 ); // 0 ??
+ cond->gatherArrayRefs( refs, 0 ); // 0 ??
+ incr->gatherArrayRefs( refs, 0 ); // 0 ??
+ body->gatherArrayRefs( refs, 0 ); // 0 ??
+}
+
+void chillAST_ForStmt::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ init->gatherScalarRefs( refs, 0 ); // 0 ??
+ cond->gatherScalarRefs( refs, 0 ); // 0 ??
+ incr->gatherScalarRefs( refs, 0 ); // 0 ??
+ body->gatherScalarRefs( refs, 0 ); // 0 ??
+}
+
+void chillAST_ForStmt::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ init->gatherDeclRefExprs( refs );
+ cond->gatherDeclRefExprs( refs );
+ incr->gatherDeclRefExprs( refs );
+ body->gatherDeclRefExprs( refs );
+}
+
+
+
+void chillAST_ForStmt::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ init->gatherVarUsage( decls );
+ cond->gatherVarUsage( decls );
+ incr->gatherVarUsage( decls );
+ body->gatherVarUsage( decls );
+}
+
+void chillAST_ForStmt::gatherStatements(std::vector<chillAST_node*> &statements ){
+
+ // for completeness, should do all 4. Maybe someday
+ //init->gatherStatements( statements );
+ //cond->gatherStatements( statements );
+ //incr->gatherStatements( statements );
+ body->gatherStatements( statements );
+}
+
+
+
+void chillAST_ForStmt::addSyncs() {
+ //fprintf(stderr, "\nchillAST_ForStmt::addSyncs() ");
+ //fprintf(stderr, "for (");
+ //init->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //cond->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //incr->print(0, stderr);
+ //fprintf(stderr, ")\n");
+
+ if (!parent) {
+ fprintf(stderr, "uhoh, chillAST_ForStmt::addSyncs() ForStmt has no parent!\n");
+ fprintf(stderr, "for (");
+ init->print(0, stderr);
+ fprintf(stderr, "; ");
+ cond->print(0, stderr);
+ fprintf(stderr, "; ");
+ incr->print(0, stderr);
+ fprintf(stderr, ")\n");
+
+ return; // exit?
+ }
+
+ if (parent->isCompoundStmt()) {
+ //fprintf(stderr, "ForStmt parent is CompoundStmt 0x%x\n", parent);
+ vector<chillAST_node*> chillin = parent->getChildren();
+ int numc = chillin.size();
+ //fprintf(stderr, "ForStmt parent is CompoundStmt 0x%x with %d children\n", parent, numc);
+ for (int i=0; i<numc; i++) {
+ if (this == parent->getChild(i)) {
+ //fprintf(stderr, "forstmt 0x%x is child %d of %d\n", this, i, numc);
+ chillAST_CudaSyncthreads *ST = new chillAST_CudaSyncthreads();
+ parent->insertChild(i+1, ST); // corrupts something ...
+ //fprintf(stderr, "Create a call to __syncthreads() 2\n");
+ //parent->addChild(ST); // wrong, but safer still kills
+ }
+ }
+
+ chillin = parent->getChildren();
+ int nowc = chillin.size();
+ //fprintf(stderr, "old, new number of children = %d %d\n", numc, nowc);
+
+ }
+ else {
+ fprintf(stderr, "chillAST_ForStmt::addSyncs() unhandled parent type %s\n", parent->getTypeString());
+ exit(-1);
+ }
+
+ //fprintf(stderr, "leaving addSyncs()\n");
+}
+
+
+
+
+void chillAST_ForStmt::removeSyncComment() {
+ //fprintf(stderr, "chillAST_ForStmt::removeSyncComment()\n");
+ if (metacomment && strstr(metacomment, "~cuda~") && strstr(metacomment, "preferredIdx: ")) {
+ char *ptr = strlen( "preferredIdx: " ) + strstr(metacomment, "preferredIdx: ");
+ *ptr = '\0';
+ }
+}
+
+
+bool chillAST_ForStmt::findLoopIndexesToReplace(chillAST_SymbolTable *symtab, bool forcesync ) {
+ fprintf(stderr, "\nchillAST_ForStmt::findLoopIndexesToReplace( force = %d )\n", forcesync);
+ //if (metacomment) fprintf(stderr, "metacomment '%s'\n", metacomment);
+
+ bool force = forcesync;
+ bool didasync = false;
+ if (forcesync) {
+ //fprintf(stderr, "calling addSyncs() because PREVIOUS ForStmt in a block had preferredIdx\n");
+ addSyncs();
+ didasync = true;
+ }
+
+ //fprintf(stderr, "chillAST_ForStmt::findLoopIndexesToReplace()\n");
+ if (metacomment && strstr(metacomment, "~cuda~") && strstr(metacomment, "preferredIdx: ")) {
+ //fprintf(stderr, "metacomment '%s'\n", metacomment);
+
+ char *copy = strdup(metacomment);
+ char *ptr = strstr(copy, "preferredIdx: ");
+ char *vname = ptr + strlen( "preferredIdx: " );
+ char *space = strstr(vname, " "); // TODO index()
+ if (space) {
+ //fprintf(stderr, "vname = '%s'\n", vname);
+ force = true;
+ }
+
+ if ((!didasync) && force ) {
+ //fprintf(stderr, "calling addSyncs() because ForStmt metacomment had preferredIdx '%s'\n", vname);
+ addSyncs();
+ removeSyncComment();
+ didasync = true;
+ }
+
+ if (space) *space = '\0'; // if this is multiple words, grab the first one
+ //fprintf(stderr, "vname = '%s'\n", vname);
+
+ //fprintf(stderr, "\nfor (");
+ //init->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //cond->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //incr->print(0, stderr);
+ //fprintf(stderr, ") %s\n", metacomment );
+ //fprintf(stderr, "prefer '%s'\n", vname );
+
+ vector<chillAST_VarDecl*> decls;
+ init->gatherVarLHSUsage( decls );
+ //cond->gatherVarUsage( decls );
+ //incr->gatherVarUsage( decls );
+ //fprintf(stderr, "forstmt has %d vardecls in init, cond, inc\n", decls.size());
+
+ if ( 1 != decls.size()) {
+ fprintf(stderr, "uhoh, preferred index in for statement, but multiple variables used\n");
+ print(0,stderr);
+ fprintf(stderr, "\nvariables are:\n");
+ for (int i=0; i<decls.size(); i++) {
+ decls[i]->print(0,stderr); fprintf(stderr, "\n");
+ }
+ exit(0);
+ }
+ chillAST_VarDecl* olddecl = decls[0];
+
+ // RIGHT NOW, change all the references that this loop wants swapped out
+ // find vardecl for named preferred index. it has to already exist
+ fprintf(stderr, "RIGHT NOW, change all the references that this loop wants swapped out \n");
+
+ chillAST_VarDecl *newguy = findVariableNamed( vname ); // recursive
+ if (!newguy) {
+ fprintf(stderr, "there was no variable named %s anywhere I could find\n", vname);
+ }
+
+ // wrong - this only looks at variables defined in the forstmt, not
+ // in parents of the forstmt
+ //int numsym = symtab->size();
+ //fprintf(stderr, "%d symbols\n", numsym);
+ //for (int i=0; i<numsym; i++) {
+ // fprintf(stderr, "sym %d is '%s'\n", i, (*symtab)[i]->varname);
+ // if (!strcmp(vname, (*symtab)[i]->varname)) {
+ // newguy = (*symtab)[i];
+ // }
+ //}
+ if (!newguy) {
+ fprintf(stderr, "chillAST_ForStmt::findLoopIndexesToReplace() there is no defined variable %s\n", vname);
+
+ // make one ?? seems like this should never happen
+ newguy = new chillAST_VarDecl( olddecl->vartype, vname, ""/*?*/, NULL );
+ // insert actual declaration in code location? how?
+
+ // find parent of the ForStmt?
+ // find parent^n of the ForStmt that is not a Forstmt?
+ // find parent^n of the Forstmt that is a FunctionDecl?
+ chillAST_node *contain = findContainingNonLoop();
+ if (contain == NULL) {
+ fprintf(stderr, "nothing but loops all the way up?\n");
+ exit(0);
+ }
+ fprintf(stderr, "containing non-loop is a %s\n", contain->getTypeString());
+
+ contain->print(0,stderr);
+ contain->insertChild( 0, newguy ); // ugly order TODO
+ contain->addVariableToSymbolTable( newguy ); // adds to first enclosing symbolTable
+
+ if (! symbolTableHasVariableNamed( contain->getSymbolTable(), vname )) {
+ fprintf(stderr, "container doesn't have a var names %s afterwards???\n", vname);
+ exit(-1);
+ }
+ }
+
+
+ // swap out old for new in init, cond, incr, body
+ if (newguy) {
+ fprintf(stderr, "\nwill replace %s with %s in init, cond, incr\n", olddecl->varname, newguy->varname);
+ fprintf(stderr, "was: for (");
+ init->print(0, stderr);
+ fprintf(stderr, "; ");
+ cond->print(0, stderr);
+ fprintf(stderr, "; ");
+ incr->print(0, stderr);
+ fprintf(stderr, ")\n");
+
+
+ init->replaceVarDecls( olddecl, newguy );
+ cond->replaceVarDecls( olddecl, newguy );
+ incr->replaceVarDecls( olddecl, newguy );
+
+ fprintf(stderr, " is: for (");
+ init->print(0, stderr);
+ fprintf(stderr, "; ");
+ cond->print(0, stderr);
+ fprintf(stderr, "; ");
+ incr->print(0, stderr);
+ fprintf(stderr, ")\n\n");
+
+ fprintf(stderr,"recursing to ForStmt body of type %s\n", body->getTypeString());
+ body->replaceVarDecls( olddecl, newguy );
+
+ fprintf(stderr, "\nafter recursing to body, this loop is (there should be no %s)\n", olddecl->varname);
+ print(0, stderr); fprintf(stderr, "\n");
+
+ }
+
+ //if (!space) // there was only one preferred
+ //fprintf(stderr, "removing metacomment\n");
+ metacomment = NULL; // memleak
+
+ }
+
+ // check for more loops. We may have already swapped variables out in body (right above here)
+ body->findLoopIndexesToReplace( symtab, false ) ;
+
+ return force;
+}
+
+void chillAST_ForStmt::replaceChild( chillAST_node *old, chillAST_node *newchild ){
+ //fprintf(stderr, "chillAST_ForStmt::replaceChild() REALLY CALLING BODY->ReplaceCHILD\n");
+ body->replaceChild( old, newchild );
+}
+
+
+
+void chillAST_ForStmt::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ // logic problem if my loop var is olddecl!
+
+ //fprintf(stderr, "chillAST_ForStmt::replaceVarDecls( old %s, new %s )\n", olddecl->varname, newdecl->varname);
+
+ // this is called for inner loops!
+ init->replaceVarDecls( olddecl, newdecl );
+ cond->replaceVarDecls( olddecl, newdecl );
+ incr->replaceVarDecls( olddecl, newdecl );
+ body->replaceVarDecls( olddecl, newdecl );
+}
+
+
+void chillAST_ForStmt::gatherLoopIndeces( std::vector<chillAST_VarDecl*> &indeces ) {
+ //fprintf(stderr, "chillAST_ForStmt::gatherLoopIndeces()\nloop is:\n"); print(0,stderr);
+
+ vector<chillAST_VarDecl*> decls;
+ init->gatherVarLHSUsage( decls );
+ cond->gatherVarLHSUsage( decls );
+ incr->gatherVarLHSUsage( decls );
+ // note: NOT GOING INTO BODY OF THE LOOP
+
+ int numdecls = decls.size();
+ //fprintf(stderr, "gatherLoopIndeces(), %d lhs vardecls for this ForStmt\n", numdecls);
+
+ for (int i=0; i<decls.size(); i++) {
+ //fprintf(stderr, "%s %p\n", decls[i]->varname, decls[i] );
+ indeces.push_back( decls[i] );
+ }
+
+ // Don't forget to keep heading upwards!
+ if (parent) {
+ //fprintf(stderr, "loop %p has parent of type %s\n", this, parent->getTypeString());
+ parent->gatherLoopIndeces( indeces );
+ }
+ //else fprintf(stderr, "this loop has no parent???\n");
+
+}
+
+
+void chillAST_ForStmt::gatherLoopVars( std::vector<std::string> &loopvars ) {
+ //fprintf(stderr, "gathering loop vars for loop for (");
+ //init->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //cond->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //incr->print(0, stderr);
+ //fprintf(stderr, ")\n" );
+
+ //init->dump(0, stderr);
+
+
+ vector<chillAST_VarDecl*> decls;
+ init->gatherVarLHSUsage( decls );
+ cond->gatherVarLHSUsage( decls );
+ incr->gatherVarLHSUsage( decls );
+ // note: NOT GOING INTO BODY OF THE LOOP
+
+ for (int i=0; i<decls.size(); i++) loopvars.push_back( strdup( decls[i]->varname ));
+
+}
+
+
+void chillAST_ForStmt::loseLoopWithLoopVar( char *var ) {
+
+ //fprintf(stderr, "\nchillAST_ForStmt::loseLoopWithLoopVar( %s )\n", var );
+
+ // now recurse (could do first, I suppose)
+ // if you DON'T do this first, you may have already replaced yourself with this loop body
+ // the body will no longer have this forstmt as parent, it will have the forstmt's parent as its parent
+ //fprintf(stderr, "forstmt 0x%x, recursing loseLoop to body 0x%x of type %s with parent 0x%x of type %s\n", this, body, body->getTypeString(), body->parent, body->parent->getTypeString());
+ body->loseLoopWithLoopVar( var ) ;
+
+
+
+
+ // if *I* am a loop to be replaced, tell my parent to replace me with my loop body
+
+ std::vector<std::string> loopvars;
+ gatherLoopVars( loopvars );
+
+ if (loopvars.size() != 1) {
+ fprintf(stderr, "uhoh, loop has more than a single loop var and trying to loseLoopWithLoopVar()\n");
+ print(0,stderr);
+ fprintf(stderr, "\nvariables are:\n");
+ for (int i=0; i<loopvars.size(); i++) {
+ fprintf(stderr, "%s\n", loopvars[i].c_str());
+ }
+
+ exit(-1);
+ }
+
+ //fprintf(stderr, "my loop var %s, looking for %s\n", loopvars[0].c_str(), var );
+ if (!strcmp(var, loopvars[0].c_str())) {
+ //fprintf(stderr, "OK, trying to lose myself! for (");
+ //init->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //cond->print(0, stderr);
+ //fprintf(stderr, "; ");
+ //incr->print(0, stderr);
+ //fprintf(stderr, ")\n" );
+
+ if (!parent) {
+ fprintf(stderr, "chillAST_ForStmt::loseLoopWithLoopVar() I have no parent!\n");
+ exit(-1);
+ }
+
+ vector<chillAST_VarDecl*> decls;
+ init->gatherVarLHSUsage( decls ); // this can fail if init is outside the loop
+ cond->gatherVarLHSUsage( decls );
+ incr->gatherVarLHSUsage( decls );
+ if (decls.size() > 1) {
+ fprintf(stderr, "chill_ast.cc multiple loop variables confuses me\n");
+ exit(-1);
+ }
+ chillAST_node *newstmt = body;
+
+ // ACTUALLY, if I am being replaced, and my loop conditional is a min (Ternary), then wrap my loop body in an if statement
+ if (cond->isBinaryOperator()) { // what else could it be?
+ chillAST_BinaryOperator *BO = (chillAST_BinaryOperator *) cond;
+ if (BO->rhs->isTernaryOperator()) {
+
+ chillAST_TernaryOperator *TO = (chillAST_TernaryOperator *)BO->rhs;
+ chillAST_BinaryOperator *C = (chillAST_BinaryOperator *)TO->condition;
+
+ //fprintf(stderr, "loop condition RHS is ternary\nCondition RHS");
+ C->print(); printf("\n"); fflush(stdout);
+ chillAST_node *l = C->lhs;
+ if (l->isParenExpr()) l = ((chillAST_ParenExpr *)l)->subexpr;
+ chillAST_node *r = C->rhs;
+ if (r->isParenExpr()) r = ((chillAST_ParenExpr *)r)->subexpr;
+
+ //fprintf(stderr, "lhs is %s rhs is %s\n", l->getTypeString(), r->getTypeString());
+
+ chillAST_node *ifcondrhs = NULL;
+ if (!(l->isConstant())) ifcondrhs = l;
+ else if (!(r->isConstant())) ifcondrhs = r;
+ else {
+ // should never happen. 2 constants. infinite loop
+ fprintf(stderr, "chill_ast.cc INIFNITE LOOP?\n");
+ this->print(0,stderr); fprintf(stderr, "\n\n");
+ exit(-1);
+ }
+
+ // wrap the loop body in an if
+ chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr( decls[0] );
+ chillAST_BinaryOperator *ifcond = new chillAST_BinaryOperator( DRE, "<=", ifcondrhs );
+ chillAST_IfStmt *ifstmt = new chillAST_IfStmt( ifcond, body, NULL, NULL );
+
+ newstmt = ifstmt;
+ }
+ }
+
+ //fprintf(stderr, "forstmt 0x%x has parent 0x%x of type %s\n", this, parent, parent->getTypeString());
+ //fprintf(stderr, "forstmt will be replaced by\n");
+ //newstmt->print(0,stderr); fprintf(stderr, "\n\n");
+
+ parent->replaceChild( this, newstmt );
+ }
+
+
+}
+
+
+
+
+
+chillAST_BinaryOperator::chillAST_BinaryOperator() {
+ //fprintf(stderr, "chillAST_BinaryOperator::chillAST_BinaryOperator() %p no parent\n", this);
+ fprintf(stderr, "chillAST_BinaryOperator::chillAST_BinaryOperator() no parent\n");
+ lhs = rhs = NULL;
+ op = NULL;
+ asttype = CHILLAST_NODETYPE_BINARYOPERATOR;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+chillAST_BinaryOperator::chillAST_BinaryOperator(chillAST_node *l, const char *oper, chillAST_node *r, chillAST_node *par) {
+ //fprintf(stderr, "chillAST_BinaryOperator::chillAST_BinaryOperator( l %p %s r %p, parent %p) this %p\n", l, oper, r, par, this);
+ fprintf(stderr, "chillAST_BinaryOperator::chillAST_BinaryOperator( l %s r )\n", oper);
+
+ //if (l && r ) {
+ // fprintf(stderr, "("); l->print(0,stderr); fprintf(stderr, ") %s (", oper); r->print(0,stderr); fprintf(stderr, ")\n\n");
+ //}
+
+ lhs = l;
+ rhs = r;
+ parent = par;
+
+ if (lhs) lhs->setParent( this );
+ if (rhs) rhs->setParent( this ); // may only have part of the lhs and rhs when binop is created
+ op = strdup(oper);
+ asttype = CHILLAST_NODETYPE_BINARYOPERATOR;
+
+ // if this writes to lhs and lhs type has an 'imwrittento' concept, set that up
+ if (isAssignmentOp()) {
+ if (lhs && lhs->isArraySubscriptExpr()) {
+ ((chillAST_ArraySubscriptExpr*)lhs)->imwrittento = true;
+ //fprintf(stderr, "chillAST_BinaryOperator, op '=', lhs is an array reference LVALUE\n");
+ }
+ }
+ if (isAugmentedAssignmentOp()) { // += etc
+ //fprintf(stderr, "isAugmentedAssignmentOp() "); print(); fflush(stdout);
+ if (lhs && lhs->isArraySubscriptExpr()) {
+ //fprintf(stderr, "lhs is also read from "); lhs->print(); fflush(stdout);
+ ((chillAST_ArraySubscriptExpr*)lhs)->imreadfrom = true; // note will ALSO have imwrittento true
+ }
+ }
+
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+int chillAST_BinaryOperator::evalAsInt() {
+ // very limited. allow +-*/ and integer literals ...
+ if (isAssignmentOp()) return rhs->evalAsInt(); // ?? ignores/loses lhs info
+
+ if (!strcmp("+", op)) {
+ //fprintf(stderr, "chillAST_BinaryOperator::evalAsInt() %d + %d\n", lhs->evalAsInt(), rhs->evalAsInt());
+ return lhs->evalAsInt() + rhs->evalAsInt();
+ }
+ if (!strcmp("-", op)) return lhs->evalAsInt() - rhs->evalAsInt();
+ if (!strcmp("*", op)) return lhs->evalAsInt() * rhs->evalAsInt();
+ if (!strcmp("/", op)) return lhs->evalAsInt() / rhs->evalAsInt();
+
+ fprintf(stderr, "chillAST_BinaryOperator::evalAsInt() unhandled op '%s'\n", op);
+ segfault();
+}
+
+chillAST_IntegerLiteral *chillAST_BinaryOperator::evalAsIntegerLiteral() {
+ return new chillAST_IntegerLiteral( evalAsInt() ); // ??
+}
+
+void chillAST_BinaryOperator::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(BinaryOperator '%s'\n", op);
+
+ if (lhs) lhs->dump(indent+1, fp); // lhs could be null
+ else { chillindent(indent+1, fp); fprintf(fp, "(NULL)\n"); }
+ fflush(fp);
+
+ if (rhs) rhs->dump(indent+1, fp); // rhs could be null
+ else { chillindent(indent+1, fp); fprintf(fp, "(NULL)\n"); }
+ fflush(fp);
+
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+void chillAST_BinaryOperator::print( int indent, FILE *fp ) { // TODO this needparens logic is wrong
+ printPreprocBEFORE(indent, fp);
+
+ chillindent( indent, fp );
+ bool needparens = false;
+ if (lhs) {
+ if (lhs->isImplicitCastExpr()) {
+ // fprintf(stderr, "\nlhs 0x%x isImplicitCastExpr()\n", lhs);
+ // fprintf(stderr, "lhs subexpr 0x%x\n", ((chillAST_ImplicitCastExpr*)lhs)->subexpr);
+ // fprintf(stderr, "lhs subexpr type %s\n", ((chillAST_ImplicitCastExpr*)lhs)->subexpr->getTypeString());
+ //
+ if (((chillAST_ImplicitCastExpr*)lhs)->subexpr->isNotLeaf()) needparens = true;
+ }
+ else if (lhs->isNotLeaf()) {
+ if (isMinusOp() && lhs->isPlusOp()) needparens = false;
+ else if (isPlusMinusOp() && lhs->isMultDivOp()) needparens = false;
+ else needparens = true;
+ }
+ }
+
+ //fprintf(stderr, "\n\nbinop ");
+ //lhs->printonly(0,stderr);
+ //fprintf(stderr," %s ",op);
+ //rhs->printonly(0,stderr);
+ //fprintf(stderr,"\n");
+ //fprintf(stderr, "op is %s lhs %s rhs %s\n", op, lhs->getTypeString(), rhs->getTypeString());
+ //fprintf(stderr, "lhs "); lhs->printonly(0, stderr); fprintf(stderr, " ");
+ //fprintf(stderr, "lhs needparens = %d\n", needparens);
+
+
+ if (needparens) fprintf(fp, "(");
+ if (lhs) lhs->print( 0, fp );
+ else fprintf(fp, "(NULL)");
+ if (needparens) fprintf(fp, ")");
+
+ fprintf( fp, " %s ", op);
+
+ needparens = false;
+ //fprintf(stderr, "binop rhs is of type %s\n", rhs->getTypeString());
+ if (rhs) {
+ if (rhs->isImplicitCastExpr()) {
+ if (((chillAST_ImplicitCastExpr*)rhs)->subexpr->isNotLeaf()) needparens = true;
+ }
+ //else if (rhs->isNotLeaf()) needparens = true; // too many parens. test too simple
+ else if (rhs->isNotLeaf()) {
+ // really need the precedence ordering, and check relative of op and rhs op
+ if (isMinusOp() ) needparens = true; // safer. perhaps complicated thing on rhs of a minus
+ else if (isPlusMinusOp() && rhs->isMultDivOp()) needparens = false;
+ else needparens = true;
+ }
+ }
+ //fprintf(stderr, "rhs "); rhs->printonly(0, stderr); fprintf(stderr, " ");
+ //fprintf(stderr, "rhs needparens = %d\n\n", needparens);
+ //if (!needparens) fprintf(stderr, "rhs isNotLeaf() = %d\n", rhs->isNotLeaf());
+
+ if (needparens) fprintf(fp, "(");
+ if (rhs) rhs->print( 0, fp );
+ else fprintf(fp, "(NULL)");
+ if (needparens) fprintf(fp, ")");
+ fflush(fp);
+ printPreprocAFTER(indent, fp);
+
+}
+
+
+char *chillAST_BinaryOperator::stringRep(int indent ) {
+ std::string s = string( lhs->stringRep() ) + " " + op + " " + string(lhs->stringRep() );
+ return strdup( s.c_str() );
+}
+
+
+
+void chillAST_BinaryOperator::printonly( int indent, FILE *fp ) {
+
+ lhs->printonly( indent, fp );
+ fprintf( fp, " %s ", op);
+ rhs->printonly( 0, fp );
+ fflush(fp);
+
+
+
+}
+
+
+class chillAST_node* chillAST_BinaryOperator::constantFold() {
+ //fprintf(stderr, "\nchillAST_BinaryOperator::constantFold() ");
+ //print(0,stderr); fprintf(stderr, "\n");
+
+ lhs = lhs->constantFold();
+ rhs = rhs->constantFold();
+
+ chillAST_node *returnval = this;
+
+ if (lhs->isConstant() && rhs->isConstant() ) {
+ //fprintf(stderr, "binop folding constants\n"); print(0,stderr); fprintf(stderr, "\n");
+
+ if (streq(op, "+") || streq(op, "-") || streq(op, "*")) {
+ if (lhs->isIntegerLiteral() && rhs->isIntegerLiteral()) {
+ chillAST_IntegerLiteral *l = (chillAST_IntegerLiteral *)lhs;
+ chillAST_IntegerLiteral *r = (chillAST_IntegerLiteral *)rhs;
+ chillAST_IntegerLiteral *I;
+
+ if (streq(op, "+")) I = new chillAST_IntegerLiteral(l->value+r->value, parent);
+ if (streq(op, "-")) I = new chillAST_IntegerLiteral(l->value-r->value, parent);
+ if (streq(op, "*")) I = new chillAST_IntegerLiteral(l->value*r->value, parent);
+
+ returnval = I;
+ //fprintf(stderr, "%d %s %d becomes %d\n", l->value,op, r->value, I->value);
+ }
+ else { // at least one is a float
+
+ // usually don't want to do this for floats or doubles
+ // could probably check for special cases like 0.0/30.0 or X/X or X/1.0
+#ifdef FOLDFLOATS
+ float lval, rval;
+ if (lhs->isIntegerLiteral()) {
+ lval = (float) ((chillAST_IntegerLiteral *)lhs)->value;
+ }
+ else {
+ lval = ((chillAST_FloatingLiteral *)lhs)->value;
+ }
+
+ if (rhs->isIntegerLiteral()) {
+ rval = (float) ((chillAST_IntegerLiteral *)rhs)->value;
+ }
+ else {
+ rval = ((chillAST_FloatingLiteral *)rhs)->value;
+ }
+
+ chillAST_FloatingLiteral *F;
+ if (streq(op, "+")) F = new chillAST_FloatingLiteral(lval + rval, parent);
+ if (streq(op, "-")) F = new chillAST_FloatingLiteral(lval - rval, parent);
+ if (streq(op, "*")) F = new chillAST_FloatingLiteral(lval * rval, parent);
+
+ returnval = F;
+#endif
+
+ }
+ }
+ //else fprintf(stderr, "can't fold op '%s' yet\n", op);
+ }
+
+ //fprintf(stderr, "returning "); returnval->print(0,stderr); fprintf(stderr, "\n");
+ return returnval;
+}
+
+
+class chillAST_node* chillAST_BinaryOperator::clone() {
+ //fprintf(stderr, "chillAST_BinaryOperator::clone() "); print(); printf("\n"); fflush(stdout);
+
+ chillAST_node* l = lhs->clone();
+ chillAST_node* r = rhs->clone();
+ chillAST_BinaryOperator *bo = new chillAST_BinaryOperator( l, op, r, parent );
+ l->setParent( bo );
+ r->setParent( bo );
+ bo->isFromSourceFile = isFromSourceFile;
+ if (filename) bo->filename = strdup(filename);
+ return bo;
+}
+
+void chillAST_BinaryOperator::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ //fprintf(stderr, "chillAST_BinaryOperator::gatherArrayRefs()\n");
+ //print(); fflush(stdout); fprintf(stderr, "\n");
+ //if (isAugmentedAssignmentOp()) {
+ // fprintf(stderr, "%s is augmented assignment\n", op);
+ //}
+
+ //if (isAssignmentOp()) {
+ // fprintf(stderr, "%s is assignment\n", op);
+ //}
+
+ //if (isAugmentedAssignmentOp()) { // lhs is ALSO on the RHS, NOT as a write
+ // if (lhs->isArraySubscriptExpr()) { // probably some case where this fails
+ // ((chillAST_ArraySubscriptExpr *) lhs)->imreadfrom = true;
+ // //lhs->&gatherArrayRefs( refs, 0 );
+ // }
+ //}
+
+ //fprintf(stderr, "in chillAST_BinaryOperator::gatherArrayRefs(), %d &arrayrefs before\n", refs.size());
+ lhs->gatherArrayRefs( refs, isAssignmentOp() );
+ //fprintf(stderr, "in chillAST_BinaryOperator::gatherArrayRefs(), %d &arrayrefs after lhs\n", refs.size());
+ rhs->gatherArrayRefs( refs, 0 );
+ //fprintf(stderr, "in chillAST_BinaryOperator::gatherArrayRefs(), %d &refs\n", refs.size());
+
+ //for (int i=0; i<refs.size(); i++) {
+ // fprintf(stderr, "%s\n", (*refs)[i]->basedecl->varname);
+ //}
+
+}
+
+void chillAST_BinaryOperator::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ lhs->gatherScalarRefs( refs, isAssignmentOp() );
+ rhs->gatherScalarRefs( refs, 0 );
+}
+
+
+void chillAST_BinaryOperator::replaceChild( chillAST_node *old, chillAST_node *newchild ) {
+ //fprintf(stderr, "\nbinop::replaceChild( old 0x%x, new ) lhs 0x%x rhd 0x%x\n", old, lhs, rhs);
+
+ // will pointers match??
+ if (lhs == old) setLHS( newchild );
+ else if (rhs == old) setRHS( newchild );
+
+ // silently ignore?
+ //else {
+ // fprintf(stderr, "\nERROR chillAST_BinaryOperator::replaceChild( old 0x%x, new ) lhs 0x%x rhd 0x%x\n", old, lhs, rhs);
+ // fprintf(stderr, "old is not a child of this BinaryOperator\n");
+ // print();
+ // dump();
+ // exit(-1);
+ //}
+}
+
+
+
+void chillAST_BinaryOperator::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_BinaryOperator::gatherVarDecls()\n");
+
+ //fprintf(stderr, "chillAST_BinaryOperator::gatherVarDecls() before %d\n", decls.size());
+ //print(0,stderr); fprintf(stderr, "\n");
+ //fprintf(stderr, "lhs is %s\n", lhs->getTypeString());
+ if (lhs) lhs->gatherVarDecls( decls ); // 'if' to deal with partially formed
+ if (rhs) rhs->gatherVarDecls( decls );
+ //fprintf(stderr, "after %d\n", decls.size());
+}
+
+
+void chillAST_BinaryOperator::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_BinaryOperator::gatherScalarVarDecls() before %d\n", decls.size());
+ //fprintf(stderr, "lhs is %s\n", lhs->getTypeString());
+ lhs->gatherScalarVarDecls( decls );
+ rhs->gatherScalarVarDecls( decls );
+ //fprintf(stderr, "after %d\n", decls.size());
+}
+
+
+void chillAST_BinaryOperator::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_BinaryOperator::gatherArrayVarDecls() before %d\n", decls.size());
+ //fprintf(stderr, "lhs is %s\n", lhs->getTypeString());
+ lhs->gatherArrayVarDecls( decls );
+ rhs->gatherArrayVarDecls( decls );
+ //fprintf(stderr, "after %d\n", decls.size());
+}
+
+
+
+void chillAST_BinaryOperator::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ lhs->gatherDeclRefExprs( refs );
+ rhs->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_BinaryOperator::gatherStatements(std::vector<chillAST_node*> &statements ){
+
+ // what's legit?
+ if (isAssignmentOp()) {
+ statements.push_back( this );
+ }
+
+}
+
+
+
+
+void chillAST_BinaryOperator::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ lhs->gatherVarUsage( decls );
+ rhs->gatherVarUsage( decls );
+}
+
+void chillAST_BinaryOperator::gatherVarLHSUsage( vector<chillAST_VarDecl*> &decls ) {
+ lhs->gatherVarUsage( decls );
+}
+
+ void chillAST_BinaryOperator::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl) {
+ //if (!strcmp(op, "<=")) {
+ // fprintf(stderr, "chillAST_BinaryOperator::replaceVarDecls( old %s, new %s)\n", olddecl->varname, newdecl->varname );
+ // print(); printf("\n"); fflush(stdout);
+ // fprintf(stderr, "binaryoperator, lhs is of type %s\n", lhs->getTypeString());
+ // fprintf(stderr, "binaryoperator, rhs is of type %s\n", rhs->getTypeString());
+ //}
+ lhs->replaceVarDecls( olddecl, newdecl );
+ rhs->replaceVarDecls( olddecl, newdecl );
+ //if (!strcmp(op, "<=")) {
+ // print(); printf("\n\n"); fflush(stdout);
+ //}
+ }
+
+
+bool chillAST_BinaryOperator::isSameAs( chillAST_node *other ){
+ if (!other->isBinaryOperator()) return false;
+ chillAST_BinaryOperator *o = (chillAST_BinaryOperator *)other;
+ if (strcmp(op, o->op)) return false; // different operators
+ return lhs->isSameAs( o->lhs ) && rhs->isSameAs( o->rhs ); // recurse
+}
+
+
+
+
+chillAST_TernaryOperator::chillAST_TernaryOperator() {
+ op = strdup("?"); // the only one so far
+ condition = lhs = rhs = NULL;
+ asttype = CHILLAST_NODETYPE_TERNARYOPERATOR;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_TernaryOperator::chillAST_TernaryOperator(const char *oper, chillAST_node *c, chillAST_node *l, chillAST_node *r, chillAST_node *par) {
+
+ op = strdup(oper);
+ condition = c; condition->setParent( this );
+ lhs = l; lhs->setParent( this );
+ rhs = r; rhs->setParent( this );
+ asttype = CHILLAST_NODETYPE_TERNARYOPERATOR;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_TernaryOperator::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(TernaryOperator '%s'\n", op);
+ condition->dump(indent+1, fp);
+ lhs->dump(indent+1, fp);
+ rhs->dump(indent+1, fp);
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+void chillAST_TernaryOperator::print( int indent, FILE *fp ) {
+ printPreprocBEFORE(indent, fp);
+ chillindent(indent, fp);
+ fprintf(fp, "(");
+ condition->print(0,fp);
+ fprintf(fp, "%s", op);
+ lhs->print(0,fp);
+ fprintf(fp, ":");
+ rhs->print(0,fp);
+ fprintf(fp, ")");
+ fflush(fp);
+}
+
+void chillAST_TernaryOperator::replaceChild( chillAST_node *old, chillAST_node *newchild ) {
+ //fprintf(stderr, "\nbinop::replaceChild( old 0x%x, new ) lhs 0x%x rhd 0x%x\n", old, lhs, rhs);
+
+ // will pointers match??
+ if (lhs == old) setLHS( newchild );
+ else if (rhs == old) setRHS( newchild );
+ else if (condition == old) setCond( newchild );
+
+ // silently ignore?
+ //else {
+ //}
+}
+
+
+void chillAST_TernaryOperator::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ condition->gatherVarDecls( decls );
+ lhs->gatherVarDecls( decls );
+ rhs->gatherVarDecls( decls );
+}
+
+void chillAST_TernaryOperator::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ condition->gatherScalarVarDecls( decls );
+ lhs->gatherScalarVarDecls( decls );
+ rhs->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_TernaryOperator::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ condition->gatherArrayVarDecls( decls );
+ lhs->gatherArrayVarDecls( decls );
+ rhs->gatherArrayVarDecls( decls );
+}
+
+
+
+void chillAST_TernaryOperator::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ condition->gatherDeclRefExprs( refs );
+ lhs->gatherDeclRefExprs( refs );
+ rhs->gatherDeclRefExprs( refs );
+}
+
+
+
+void chillAST_TernaryOperator::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ condition->gatherVarUsage( decls );
+ lhs->gatherVarUsage( decls );
+ rhs->gatherVarUsage( decls );
+}
+
+void chillAST_TernaryOperator::gatherVarLHSUsage( vector<chillAST_VarDecl*> &decls ) {
+ // this makes no sense for ternary ??
+}
+
+void chillAST_TernaryOperator::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl) {
+ condition->replaceVarDecls( olddecl, newdecl );
+ lhs->replaceVarDecls( olddecl, newdecl );
+ rhs->replaceVarDecls( olddecl, newdecl );
+}
+
+void chillAST_TernaryOperator::printonly( int indent, FILE *fp ) {
+ fprintf(fp, "(");
+ condition->printonly(0,fp);
+ fprintf(fp, "%s", op);
+ lhs->printonly(0,fp);
+ fprintf(fp, ":");
+ rhs->printonly(0,fp);
+ fprintf(fp, ")");
+ fflush(fp);
+}
+
+
+class chillAST_node* chillAST_TernaryOperator::constantFold() {
+ condition = condition->constantFold();
+ lhs = lhs->constantFold();
+ rhs = rhs->constantFold();
+
+ chillAST_node *returnval = this;
+
+ if (condition->isConstant()) {
+ //fprintf(stderr, "ternop folding constants\n");
+ //print(0,stderr);
+ //fprintf(stderr, "\n");
+
+ // assume op is "?"
+ // TODO
+ /*
+
+ if (streq(op, "+") || streq(op, "-") || streq(op, "*")) {
+ if (lhs->isIntegerLiteral() && rhs->isIntegerLiteral()) {
+ chillAST_IntegerLiteral *l = (chillAST_IntegerLiteral *)lhs;
+ chillAST_IntegerLiteral *r = (chillAST_IntegerLiteral *)rhs;
+ chillAST_IntegerLiteral *I;
+
+ if (streq(op, "+")) I = new chillAST_IntegerLiteral(l->value+r->value, parent);
+ if (streq(op, "-")) I = new chillAST_IntegerLiteral(l->value-r->value, parent);
+ if (streq(op, "*")) I = new chillAST_IntegerLiteral(l->value*r->value, parent);
+
+ returnval = I;
+ //fprintf(stderr, "%d %s %d becomes %d\n", l->value,op, r->value, I->value);
+ }
+ else { // at least one is a float
+ float lval, rval;
+ if (lhs->isIntegerLiteral()) {
+ lval = (float) ((chillAST_IntegerLiteral *)lhs)->value;
+ }
+ else {
+ lval = ((chillAST_FloatingLiteral *)lhs)->value;
+ }
+ if (rhs->isIntegerLiteral()) {
+ rval = (float) ((chillAST_IntegerLiteral *)rhs)->value;
+ }
+ else {
+ rval = ((chillAST_FloatingLiteral *)rhs)->value;
+ }
+
+ chillAST_FloatingLiteral *F;
+ if (streq(op, "+")) F = new chillAST_FloatingLiteral(lval + rval, parent);
+ if (streq(op, "-")) F = new chillAST_FloatingLiteral(lval - rval, parent);
+ if (streq(op, "*")) F = new chillAST_FloatingLiteral(lval * rval, parent);
+
+ returnval = F;
+ }
+ }
+ else fprintf(stderr, "can't fold op '%s' yet\n", op);
+ */
+ }
+
+ return returnval;
+}
+
+class chillAST_node* chillAST_TernaryOperator::clone() {
+ chillAST_node* c = condition->clone();
+ chillAST_node* l = lhs->clone();
+ chillAST_node* r = rhs->clone();
+ chillAST_TernaryOperator *to = new chillAST_TernaryOperator( op, l, r, parent );
+ c->setParent( to );
+ l->setParent( to );
+ r->setParent( to );
+ to->isFromSourceFile = isFromSourceFile;
+ filename = NULL;
+ return to;
+}
+
+void chillAST_TernaryOperator::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ condition->gatherArrayRefs( refs, isAssignmentOp() );
+ lhs->gatherArrayRefs( refs, isAssignmentOp() );
+ rhs->gatherArrayRefs( refs, 0 );
+}
+
+void chillAST_TernaryOperator::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ condition->gatherScalarRefs( refs, isAssignmentOp() );
+ lhs->gatherScalarRefs( refs, isAssignmentOp() );
+ rhs->gatherScalarRefs( refs, 0 );
+}
+
+
+
+
+
+
+
+chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() {
+ //fprintf(stderr, "\n%p chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() 0\n", this);
+ asttype = CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR;
+ base = index = NULL;
+ basedecl = NULL; //fprintf(stderr, "setting basedecl NULL for ASE %p\n", this);
+ imwrittento = false; // ??
+ imreadfrom = false; // ??
+ parent = NULL;
+ metacomment = NULL;
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() NEED TO FAKE A LOCATION\n");
+ isFromSourceFile = true; // default
+ filename = NULL;
+ //fprintf(stderr, "\nASE %p is empty\n", this);
+}
+
+
+
+chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr( chillAST_node *bas, chillAST_node *indx, chillAST_node *par, void *unique ) {
+
+ //fprintf(stderr, "\nchillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() 1\n");
+ //fprintf(stderr, "ASE index %p ", indx); indx->print(0,stderr); fprintf(stderr, "\n");
+ asttype = CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR;
+ bas->setParent( this );
+ if (bas->isImplicitCastExpr()) base = ((chillAST_ImplicitCastExpr*)bas)->subexpr; // probably wrong
+ else base = bas;
+ if (indx->isImplicitCastExpr()) index = ((chillAST_ImplicitCastExpr*)indx)->subexpr; // probably wrong
+ else index = indx;
+
+ base->setParent( this );
+ index->setParent( this );
+
+ imwrittento = false; // ??
+ imreadfrom = false; // ??
+ uniquePtr = (void *) unique;
+ //fprintf(stderr,"chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() original = 0x%x\n", uniquePtr);
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() 1 calling multibase()\n");
+ basedecl = multibase();//fprintf(stderr, "%p ASE 1 basedecl = %p\n",this,basedecl);
+ //basedecl->print(); printf("\n");
+ //basedecl->dump(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "basedecl varname %s\n", basedecl->varname);
+ isFromSourceFile = true; // default
+ filename = NULL;
+
+ //fprintf(stderr, "\nASE %p parent %p ", this, parent); print(0,stderr); fprintf(stderr, "\n\n");
+}
+
+
+
+chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr( chillAST_node *bas, chillAST_node *indx, bool writtento, chillAST_node *par, void *unique ) {
+ //fprintf(stderr, "\nchillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() 2 parent %p\n", par );
+ //fprintf(stderr, "ASE %p index %p ", this, indx); indx->print(0,stderr); fprintf(stderr, "\n");
+
+ asttype = CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR;
+ bas->setParent( this );
+ if (bas->isImplicitCastExpr()) base = ((chillAST_ImplicitCastExpr*)bas)->subexpr; // probably wrong
+ else base = bas;
+
+ if (indx->isImplicitCastExpr()) index = ((chillAST_ImplicitCastExpr*)indx)->subexpr; // probably wrong
+ else index = indx;
+
+ //fprintf(stderr, "setting parent of base %p to %p\n", base, this);
+ //fprintf(stderr, "setting parent of index %p to %p\n", index, this);
+ base->setParent( this );
+ index->setParent( this );
+
+ imwrittento = writtento; // ??
+ //fprintf(stderr, "ASE %p imwrittento %d\n", this, imwrittento);
+ imreadfrom = false; // ??
+
+ uniquePtr = (void *) unique;
+ //fprintf(stderr,"chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() original = 0x%x\n", uniquePtr);
+
+ basedecl = multibase();
+
+ //fprintf(stderr, "%p ASE 2 basedecl = %p\n", this, basedecl);
+ //printf("basedecl is "); fflush(stdout); basedecl->print(); printf("\n"); fflush(stdout);
+ //basedecl->dump(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "basedecl varname %s\n", basedecl->varname);
+ isFromSourceFile = true; // default
+ filename = NULL;
+
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() 2 DONE\n");
+ //print(0,stderr); fprintf(stderr, "\n\n");
+ //fprintf(stderr, "\nASE %p parent %p ", this, parent); print(0,stderr); fprintf(stderr, "\n\n");
+ }
+
+
+
+chillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr( chillAST_VarDecl *v, std::vector<chillAST_node *> indeces, chillAST_node *par) {
+ //fprintf(stderr, "\nchillAST_ArraySubscriptExpr::chillAST_ArraySubscriptExpr() 4\n");
+ //fprintf(stderr,"chillAST_ArraySubscriptExpr( chillAST_VarDecl *v, std::vector<int> indeces)\n");
+ asttype = CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR;
+ parent = par;
+ //if (parent == NULL) {
+ // fprintf(stderr, "dammit. ASE %p has no parent\n", this);
+ //}
+
+
+ int numindeces = indeces.size();
+ for (int i=0; i<numindeces; i++) {
+ fprintf(stderr, "ASE index %d ", i); indeces[i]->print(0,stderr); fprintf(stderr, "\n");
+ // printf("[");
+ // indeces[i]->print();
+ // printf("]");
+ }
+ //fflush(stdout);
+ //fprintf(stderr, "\n");
+
+ chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr( v->vartype, v->varname, v, NULL);
+ basedecl = v; // ??
+ //fprintf(stderr, "%p ASE 3 basedecl = %p ", this, basedecl);
+ //fprintf(stderr, "of type %s\n", basedecl->getTypeString());
+ //basedecl->print(); printf("\n");
+ //basedecl->dump(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "basedecl varname %s\n", basedecl->varname);
+
+ chillAST_ArraySubscriptExpr *rent = this; // parent for subnodes
+
+ // these are on the top level ASE that we're creating here
+ base = (chillAST_node *) DRE;
+ index = indeces[ numindeces-1];
+
+ base->setParent( this );
+ index->setParent(this);
+
+ for (int i=numindeces-2; i>=0; i--) {
+
+ chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr( DRE, indeces[i], rent, 0);
+ rent->base = ASE; //
+ rent = ASE;
+ }
+
+ imwrittento = false;
+ imreadfrom = false;
+ //fprintf(stderr, "ASE is "); print(); printf("\n\n"); fflush(stdout);
+ isFromSourceFile = true; // default
+ filename = NULL;
+
+ //fprintf(stderr, "\nASE %p parent %p ", this, parent); print(0,stderr); fprintf(stderr, "\n\n");
+}
+
+
+
+chillAST_node *chillAST_node::getEnclosingStatement( int level ) { // TODO do for subclasses?
+
+ //fprintf(stderr, "chillAST_node::getEnclosingStatement( level %d ) node type %s\n", level, getTypeString());
+ //print(); printf("\n"); fflush(stdout);
+
+ // so far, user will ONLY call this directly on an array subscript expression
+ if (isArraySubscriptExpr()) return parent->getEnclosingStatement( level+1);
+
+ if (level != 0) {
+ if (isBinaryOperator() ||
+ isUnaryOperator() ||
+ isTernaryOperator() ||
+ isReturnStmt() ||
+ isCallExpr()
+ ) return this;
+
+
+ // things that are not endpoints. recurse through parent
+ if (isMemberExpr()) return parent->getEnclosingStatement( level+1 );
+ if (isImplicitCastExpr()) return parent->getEnclosingStatement( level+1 );
+ if (isSizeof()) return parent->getEnclosingStatement( level+1 );
+ if (isCStyleCastExpr()) return parent->getEnclosingStatement( level+1 );
+ return NULL;
+ }
+
+ fprintf(stderr, "getEnclosingStatement() level %d type %s, returning NULL\n", level, getTypeString());
+ segfault();
+
+ return NULL;
+}
+
+
+
+void chillAST_ArraySubscriptExpr::gatherIndeces(std::vector<chillAST_node*>&ind) {
+ if (base->isArraySubscriptExpr()) ((chillAST_ArraySubscriptExpr *)base)->gatherIndeces( ind );
+ ind.push_back( index );
+}
+
+
+
+void chillAST_ArraySubscriptExpr::dump( int indent, FILE *fp ) {
+// fprintf(stderr, "\n%p chillAST_ArraySubscriptExpr::dump() basedecl %p\n", basedecl);
+
+ char *local;
+ if (basedecl && basedecl->vartype) {
+ local = strdup( basedecl->vartype );
+ }
+ else {
+ fprintf(stderr, "%p chillAST_ArraySubscriptExpr::dump(), no basedecl ???\n",this);
+ local = strdup("");
+ //fprintf(stderr, "base is "); base->dump(); printf("\n"); base->print(); printf("\n"); fflush(stdout);
+ //print(); printf("\n"); fflush(stdout);
+ }
+
+
+ char *space = rindex(local, ' '); // can't use index because it's a class member!
+ if (space) *space = '\0'; // turn "float *" into "float"
+
+ chillindent(indent, fp);
+ //fprintf(fp, "(ArraySubscriptExpr '%s' ", local);
+ if (basedecl) {
+ //fprintf(stderr, " chillAST_ArraySubscriptExpr::dump() basedecl is of type %s\n", basedecl->getTypeString());
+ fprintf(fp, "(ArraySubscriptExpr (%s) '%s' ", basedecl->varname, local);
+ }
+ else fprintf(stderr, " chillAST_ArraySubscriptExpr::dump() has no basedecl\n");
+ free(local);
+
+ if (imwrittento) {
+ if (imreadfrom) fprintf(fp, "lvalue AND rvalue\n");
+ else fprintf(fp, "lvalue\n");
+ }
+ else fprintf(fp, "rvalue\n");
+ base->dump( indent+1, fp );
+ index->dump(indent+1, fp);
+
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+
+
+void chillAST_ArraySubscriptExpr::print( int indent, FILE *fp ) {
+ base->print( indent, fp );
+ fprintf(fp, "[");
+ index->print(0, fp);
+ fprintf(fp, "]");
+ fflush(fp);
+}
+
+char *chillAST_ArraySubscriptExpr::stringRep(int indent ) {
+ fprintf(stderr, "chillAST_ArraySubscriptExpr::stringRep\n");
+
+ char *blurb;
+ char *b = base->stringRep(0);
+ char *i = index->stringRep(0);
+ // combine. shoudl be using strings. much cleaner TODO
+ std::string s = string(b) + "[" + string(i) + "]";
+ fprintf(stderr, "ASE stringrep %s\n", s.c_str());
+ return strdup( s.c_str());
+
+
+}
+
+
+void chillAST_ArraySubscriptExpr::printonly( int indent, FILE *fp ) {
+ base->printonly( indent, fp );
+ fprintf(fp, "[");
+ index->printonly(0, fp);
+ fprintf(fp, "]");
+ fflush(fp);
+}
+
+
+void chillAST_ArraySubscriptExpr::print( int indent, FILE *fp ) const {
+ base->print( indent, fp );
+ fprintf(fp, "[");
+ index->print(0, fp);
+ fprintf(fp, "]");
+ fflush(fp);
+};
+
+
+chillAST_VarDecl *chillAST_ArraySubscriptExpr::multibase() {
+ // return the VARDECL of the thing the subscript is an index into
+ //this should probably be a chillAST_node function instead of having all these ifs
+ //print(); printf("\n"); fflush(stdout);
+ //base->print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::multibase() base of type %s\n", base->getTypeString());
+
+ return base->multibase();
+
+ // this will be used to SET basedecl
+ //basedecl = NULL; // do this so we don't confuse ourselves looking at uninitialized basedecl
+
+ chillAST_node *b = base;
+ //fprintf(stderr, "base is of type %s\n", b->getTypeString());
+
+ if (!b) return NULL; // just in case ??
+
+ if (base->asttype == CHILLAST_NODETYPE_IMPLICITCASTEXPR) { // bad coding
+ b = ((chillAST_ImplicitCastExpr*)b)->subexpr;
+ }
+
+ if (b->asttype == CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR) { // multidimensional array!
+ // recurse
+ return ((chillAST_ArraySubscriptExpr *)b)->multibase();
+ }
+
+ if (b->asttype == CHILLAST_NODETYPE_DECLREFEXPR) return(((chillAST_DeclRefExpr*)b)->getVarDecl());
+
+
+ if (b->isBinaryOperator()) {
+ // presumably a dot or pointer ref that resolves to an array
+ chillAST_BinaryOperator *BO = (chillAST_BinaryOperator *) b;
+ if ( strcmp(BO->op, ".") ) {
+ fprintf(stderr, "chillAST_ArraySubscriptExpr::multibase(), UNHANDLED case:\n");
+ fprintf(stderr, "base is binary operator, of type %s\n", BO->op);
+ exit(-1);
+ }
+
+ chillAST_node *l = BO->lhs;
+ chillAST_node *r = BO->rhs;
+ printf("L %s\nR %s\n", l->getTypeString(), r->getTypeString());
+ exit(-1);
+
+ return NULL; // TODO do checks?
+ }
+
+ if (b->isMemberExpr()) {
+ //c.i[c.count] we want i member of inspector
+
+ chillAST_MemberExpr *ME = (chillAST_MemberExpr *) b;
+ //fprintf(stderr, "multibase() Member Expression "); ME->print(); printf("\n"); fflush(stdout);
+
+ chillAST_node *n = ME->base; // WRONG want the MEMBER
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::multibase() Member Expression base of type %s\n", n->getTypeString());
+ //fprintf(stderr, "base is "); ME->base->dump();
+
+ // NEED to be able to get lowest level recorddecl or typedef from this base
+
+ fprintf(stderr, "chillast.cc, L2315, bailing??\n");
+ exit(0);
+
+ if (!n->isDeclRefExpr()) {
+ fprintf(stderr, "MemberExpr member is not chillAST_DeclRefExpr\n");
+ exit(-1);
+ }
+ chillAST_DeclRefExpr *DRE = (chillAST_DeclRefExpr *)n;
+ n = DRE->decl;
+ //fprintf(stderr, "DRE decl is of type %s\n", n->getTypeString());
+ assert( n->isVarDecl() );
+ chillAST_VarDecl *vd = (chillAST_VarDecl *) n;
+ vd->print(); printf("\n"); fflush(stdout);
+
+ chillAST_TypedefDecl *tdd = vd->typedefinition;
+ chillAST_RecordDecl *rd = vd->vardef;
+ //fprintf(stderr, "tdd %p rd %p\n", tdd, rd);
+
+ print(); printf("\n");
+ dump(); printf("\n"); fflush(stdout);
+
+ assert( tdd != NULL || rd != NULL );
+
+ chillAST_VarDecl *sub;
+ if (tdd) sub = tdd->findSubpart( ME->member );
+ if (rd) sub = rd->findSubpart( ME->member );
+
+ //fprintf(stderr, "subpart is "); sub->print(); printf("\n"); fflush(stdout);
+
+ return sub; // what if the sub is an array ?? TODO
+ }
+
+
+ fprintf(stderr, "chillAST_ArraySubscriptExpr::multibase(), UNHANDLED case %s\n",
+ b->getTypeString());
+ print(); printf("\n"); fflush(stdout);
+ fprintf(stderr, "base is: "); b->print(); printf("\n"); fflush(stdout);
+ segfault();
+}
+
+
+chillAST_node *chillAST_ArraySubscriptExpr::getIndex(int dim) {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::getIndex( %d )\n", dim);
+
+ chillAST_node *b = base;
+
+ int depth = 0;
+ std::vector<chillAST_node*> ind;
+ chillAST_node *curindex = index;
+ for (;;) {
+ if (b->asttype == CHILLAST_NODETYPE_IMPLICITCASTEXPR) b = ((chillAST_ImplicitCastExpr*)b)->subexpr;
+ else if (b->asttype == CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR) {
+ //fprintf(stderr, "base "); b->print(); fprintf(stderr, "\n");
+ //fprintf(stderr, "index "); curindex->print(); fprintf(stderr, "\n");
+ ind.push_back(curindex);
+ curindex = ((chillAST_ArraySubscriptExpr*)b)->index;
+ b = ((chillAST_ArraySubscriptExpr*)b)->base;
+ depth++;
+ }
+ else {
+ //fprintf(stderr, "base "); b->print(); fprintf(stderr, "\n");
+ //fprintf(stderr, "index "); curindex->print(); fprintf(stderr, "\n");
+ //fprintf(stderr, "stopping at base type %s\n", b->getTypeString());
+ ind.push_back(curindex);
+ break;
+ }
+ }
+ //fprintf(stderr, "depth %d\n", depth );
+ //for (int i=0; i<ind.size(); i++) { ind[i]->print(); fprintf(stderr, "\n"); }
+
+ return ind[ depth - dim ];
+ /*
+ if (dim == 0) return index; // single dimension
+ fprintf(stderr, "DIM NOT 0\n");
+ // multidimension
+ chillAST_node *b = base;
+ if (base->asttype == CHILLAST_NODETYPE_IMPLICITCASTEXPR) { // bad coding
+ b = ((chillAST_ImplicitCastExpr*)b)->subexpr;
+ }
+ if (b->asttype == CHILLAST_NODETYPE_IMPLICITCASTEXPR) { // bad coding
+ b = ((chillAST_ImplicitCastExpr*)b)->subexpr;
+ }
+
+ b->print(); printf("\n"); fflush(stdout);
+ if (b->asttype == CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR) {
+ return ((chillAST_ArraySubscriptExpr *)b)->getIndex(dim-1);
+ }
+
+ fprintf(stderr, "chillAST_ArraySubscriptExpr::getIndex() failed\n");
+ */
+ exit(-1);
+}
+
+
+
+
+class chillAST_node* chillAST_ArraySubscriptExpr::constantFold() {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::constantFold()\n");
+ base = base->constantFold();
+ index = index->constantFold();
+ return this;
+}
+
+class chillAST_node* chillAST_ArraySubscriptExpr::clone() {
+ //fprintf(stderr,"chillAST_ArraySubscriptExpr::clone() old imwrittento %d\n", imwrittento);
+ //fprintf(stderr, "cloning ASE %p ", this); print(0,stderr); printf(" with parent %p\n", parent); fflush(stdout);
+ //fprintf(stderr, "base %p base->parent %p index %p index->parent %p\n", base, base->parent, index, index->parent);
+
+ //fprintf(stderr, "old base "); base->print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "old base "); base->dump(); printf("\n"); fflush(stdout);
+ if (base->isDeclRefExpr()) {
+ chillAST_VarDecl *vd = (chillAST_VarDecl *)(((chillAST_DeclRefExpr *)base)->decl);
+ //fprintf(stderr, "old decl "); vd->print(); printf("\n");fflush(stdout);
+ //fprintf(stderr, "old decl "); vd->dump(); printf("\n");fflush(stdout);
+ }
+ chillAST_node *b = base->clone();
+ //fprintf(stderr, "new base "); b->print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "new base "); b->dump(); printf("\n"); fflush(stdout);
+
+ chillAST_node *i = index->clone();
+ //fprintf(stderr, "new index "); i->print(); printf("\n"); fflush(stdout);
+
+
+ //if (!index->parent) {
+ // fprintf(stderr, "ASE %p SOURCE OF CLONE INDEX %p of type %s HAS NO PARENT\n", this, index, index->getTypeString());
+ // fprintf(stderr, "ASE SOURCE IS "); print(0,stderr); fprintf(stderr, "\n\n");
+ //}
+ //fprintf(stderr, "cloning AST %p, after cloning base and index, creating a new ASE\n", this);
+ chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr( b, i, imwrittento, parent, uniquePtr /* ?? */ );
+ //fprintf(stderr, "cloned AST will be %p with parent %p and base %p index %p\n", ASE, parent, b, i);
+
+ ASE->imreadfrom = false; // don't know this yet
+ //ASE->imreadfrom = imreadfrom; // ??
+ //if (ASE->imreadfrom) {
+ // fprintf(stderr, "in chillAST_ArraySubscriptExpr::clone(), imreadfrom is being set. \n");
+ // ASE->print(); fflush(stdout); fprintf(stderr, "\n");
+ //}
+
+ //fprintf(stderr, "cloned result "); ASE->print(); printf("\n\n\n"); fflush(stdout);
+ //fprintf(stderr, "ASE clone() this 0x%x clone 0x%x\n", this, ASE);
+ ASE->isFromSourceFile = isFromSourceFile;
+ if (filename) ASE->filename = strdup(filename);
+ return ASE;
+}
+
+void chillAST_ArraySubscriptExpr::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::gatherArrayRefs setting imwrittento %d for ", writtento);
+//fprintf(stderr, "%s ", base->getTypeString());
+//base->print(); printf("\n"); fflush(stdout);
+
+ //fprintf(stderr, "found an array subscript. &refs 0x%x ", refs);
+ if (!imwrittento) imwrittento = writtento; // may be both written and not for +=
+ fflush(stdout);
+
+ //fprintf(stderr, "recursing on index "); index->print(0,stderr); fprintf(stderr, "\n");
+ index->gatherArrayRefs( refs, 0 ); // recurse first
+ //fprintf(stderr, "adding this "); print(0,stderr); fprintf(stderr, "\n");
+ //fprintf(stderr, "refs[%d] = 0x%x = ", refs.size(), this); print(); fflush(stdout);
+ refs.push_back( this );
+
+ //fprintf(stderr, " size now %d\n", refs.size());
+
+}
+
+void chillAST_ArraySubscriptExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ index->gatherScalarRefs( refs, 0 );
+}
+
+void chillAST_ArraySubscriptExpr::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::gatherVarDecls()\n");
+
+ base->gatherVarDecls( decls );
+ index->gatherVarDecls( decls );
+}
+
+
+void chillAST_ArraySubscriptExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::gatherScalarVarDecls()\n");
+ //fprintf(stderr, "base %s index %s\n", base->getTypeString(), index->getTypeString());
+ base->gatherScalarVarDecls( decls );
+ index->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_ArraySubscriptExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::gatherArrayVarDecls()\n");
+ //fprintf(stderr, "base %s index %s\n", base->getTypeString(), index->getTypeString());
+ base->gatherArrayVarDecls( decls );
+ index->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_ArraySubscriptExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ base->gatherDeclRefExprs( refs );
+ index->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_ArraySubscriptExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ base->gatherVarUsage( decls );
+ index->gatherVarUsage( decls );
+}
+
+
+void chillAST_ArraySubscriptExpr::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ base->replaceVarDecls( olddecl, newdecl );
+ index->replaceVarDecls( olddecl, newdecl );
+}
+
+
+void chillAST_ArraySubscriptExpr::replaceChild( chillAST_node *old, chillAST_node *newchild ) {
+ //fprintf(stderr,"chillAST_ArraySubscriptExpr::replaceChild()\n");
+
+ // arraysubscriptexpression doesn t really have children (should it?)
+ // try index ???
+ if (old == index) {
+ //fprintf(stderr, "old is index\n");
+ index = newchild;
+ index->parent = this;
+ return;
+ }
+
+ // try base ??? unclear if this makes sense TODO
+ if (old == base) {
+ //fprintf(stderr, "old is base\n");
+ base = newchild;
+ base->parent = this;
+ return;
+ }
+
+ fprintf(stderr, "chillAST_ArraySubscriptExpr::replaceChild() old is not base or index\n");
+ print(0,stderr); fprintf(stderr, "\nchild: ");
+ if (!old) fprintf(stderr, "oldchild NULL!\n");
+ old->print(0,stderr); fprintf(stderr, "\nnew: ");
+ newchild->print(0,stderr); fprintf(stderr, "\n");
+ segfault(); // make easier for gdb
+};
+
+
+bool chillAST_ArraySubscriptExpr::operator!=( const chillAST_ArraySubscriptExpr &other) {
+ bool opposite = *this == other;
+ return !opposite;
+}
+
+
+
+bool chillAST_ArraySubscriptExpr::operator==( const chillAST_ArraySubscriptExpr &other) {
+ //fprintf(stderr, "chillAST_ArraySubscriptExpr::operator==\n");
+ //fprintf(stderr, "this->basedecl 0x%x other.basedecl 0x%x\n", this->basedecl, other.basedecl);
+ //this->basedecl->print(); printf("\n\n");
+ //other.basedecl->print(); printf("\n"); fflush(stdout);
+
+ //this->print(); printf(" 0x%x == 0x%x ",this->uniquePtr, other.uniquePtr ); other.print(); printf(" ?? "); fflush(stdout);
+ //if ( this->uniquePtr == other.uniquePtr) fprintf(stderr, "t\n");
+ //else fprintf(stderr, "f\n");
+ return this->uniquePtr == other.uniquePtr;
+}
+
+
+
+
+
+chillAST_MemberExpr::chillAST_MemberExpr() {
+ asttype = CHILLAST_NODETYPE_MEMBEREXPR;
+ base = NULL;
+ member = NULL;
+ parent = NULL;
+ metacomment = NULL;
+ exptype = CHILL_MEMBER_EXP_DOT;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_MemberExpr::chillAST_MemberExpr( chillAST_node *bas, const char *mem, chillAST_node *p, void *unique, CHILL_MEMBER_EXP_TYPE t ) {
+ asttype = CHILLAST_NODETYPE_MEMBEREXPR;
+ base = bas;
+ if (base) base->setParent( this );
+ if (mem) member = strdup( mem );
+ parent = p;
+ metacomment = NULL;
+ uniquePtr = unique;
+ exptype = t;
+ isFromSourceFile = true; // default
+ filename = NULL;
+
+ return; // ignore tests below ?? TODO ??
+
+
+ // base needs to RESOLVE to a decl ref expr but may not BE one
+ // A.b . c lhs is a binop or memberexpr
+
+ if (bas->isBinaryOperator()) {
+ //fprintf(stderr, "checking binop to see if it resolved to a declrefexpr\n");
+ // cheat for now or just remove the check below
+ return;
+ }
+
+ if (! ( bas->isDeclRefExpr() || bas->isArraySubscriptExpr() )) {
+ fprintf(stderr, "chillAST_MemberExpr::chillAST_MemberExpr(), base is of type %s\n", bas->getTypeString());
+ fprintf(stderr, "chillAST_MemberExpr::chillAST_MemberExpr(), base is not DeclRefExpr\n");
+
+ base->print(); printf(".%s\n", mem); fflush(stdout);
+ segfault();
+ }
+}
+
+
+void chillAST_MemberExpr::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(MemberExpr \n");
+
+ base->dump( indent+1, fp );
+ chillindent(indent+1, fp);
+ if (exptype == CHILL_MEMBER_EXP_ARROW) fprintf(fp, "->");
+ else fprintf(fp, ".");
+
+ fprintf(fp, "%s\n", member);
+
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+}
+
+
+void chillAST_MemberExpr::print( int indent, FILE *fp ) {
+ if (base) base->print( indent, fp );
+ else {
+ chillindent( indent, fp );
+ fprintf(fp, "(NULL)");
+ }
+ if (exptype == CHILL_MEMBER_EXP_ARROW) fprintf(fp, "->");
+ else fprintf(fp, ".");
+ if (member) fprintf(fp, "%s", member);
+ else fprintf(fp, "(NULL)");
+ fflush(fp);
+}
+
+
+void chillAST_MemberExpr::printonly( int indent, FILE *fp ) {
+ base->print( indent, fp );
+ if (exptype == CHILL_MEMBER_EXP_ARROW) fprintf(fp, "->");
+ else fprintf(fp, ".");
+ fprintf(fp, "%s", member);
+ fflush(fp);
+}
+
+char *chillAST_MemberExpr::stringRep( int indent ) { // char pointer to what we'd print
+ fprintf(stderr, "*chillAST_MemberExpr::stringRep()\n");
+ if (base->isDeclRefExpr()) { //
+ chillAST_VarDecl *vd = (chillAST_VarDecl *) ((chillAST_DeclRefExpr *)base)->decl;
+ char *leak = (char *)malloc(128);
+ if (exptype == CHILL_MEMBER_EXP_ARROW) sprintf(leak, "%s->%s", vd->varname, member);
+ else sprintf(leak, "%s.%s", vd->varname, member);
+ printstring = leak;
+ return leak;
+ }
+
+
+ // else
+ // TODO
+ return strdup("chillAST_MemberExpr::getStringRep()hadanerror");
+}
+
+
+class chillAST_node* chillAST_MemberExpr::constantFold() {
+ base = base->constantFold();
+ //member = member->constantFold();
+ return this;
+}
+
+class chillAST_node* chillAST_MemberExpr::clone() {
+ chillAST_node *b = base->clone();
+ char *m = strdup( member ); // ??
+ chillAST_MemberExpr *ME = new chillAST_MemberExpr( b, m, parent, uniquePtr /* ?? */ );
+ ME->isFromSourceFile = isFromSourceFile;
+ if (filename) ME->filename = strdup(filename);
+ return ME;
+}
+
+void chillAST_MemberExpr::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ fprintf(stderr, "chillAST_MemberExpr::gatherArrayRefs() "); print(0,stderr); fprintf(stderr, "\n");
+ fprintf(stderr, "base of of type %s\n", base->getTypeString());
+ base->gatherArrayRefs( refs, writtento ); //
+
+}
+
+void chillAST_MemberExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ base->gatherScalarRefs( refs, writtento );
+}
+
+void chillAST_MemberExpr::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ base->gatherVarDecls( decls );
+}
+
+void chillAST_MemberExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ base->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_MemberExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ base->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_MemberExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ base->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_MemberExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ base->gatherVarUsage( decls );
+}
+
+
+void chillAST_MemberExpr::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ base->replaceVarDecls( olddecl, newdecl );
+}
+
+bool chillAST_MemberExpr::operator!=( const chillAST_MemberExpr &other) {
+ bool opposite = *this == other;
+ return !opposite;
+}
+
+bool chillAST_MemberExpr::operator==( const chillAST_MemberExpr &other) {
+ return this->uniquePtr == other.uniquePtr;
+}
+
+
+void chillAST_MemberExpr::replaceChild( chillAST_node *old, chillAST_node *newchild ) {
+ //printf("\nMemberExpr::replaceChild( )\n");
+ //printf("old: ");
+ //old->print();
+ //printf("\nnew: ");
+ //newchild->print();
+ //printf("\n"); fflush(stdout);
+
+ // will pointers match??
+ if (base == old) {
+ //fprintf(stderr, "old matches base of MemberExpr\n");
+ base = newchild;
+ }
+ else {
+ base->replaceChild( old, newchild );
+ }
+}
+
+chillAST_node *chillAST_MemberExpr::multibase2() { /*fprintf(stderr, "ME MB2\n" );*/ return (chillAST_node *)this; }
+
+chillAST_VarDecl* chillAST_MemberExpr::getUnderlyingVarDecl() {
+ fprintf(stderr, "chillAST_MemberExpr:getUnderlyingVarDecl()\n");
+ print(); printf("\n"); fflush(stdout);
+ exit(-1);
+ // find the member with the correct name
+
+}
+
+
+
+
+chillAST_VarDecl *chillAST_MemberExpr::multibase() {
+ //c.i[c.count] we want i member of c
+ //fprintf(stderr, "ME MB\n" );
+
+ //fprintf(stderr, "chillAST_MemberExpr::multibase()\n");
+ //print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "MemberExpr base is type %s, member %s\n", base->getTypeString(), member);
+
+ //chillAST_VarDecl *vd = base->getUnderlyingVarDecl(); // this is the only thing that ever calls this ???
+ chillAST_VarDecl *vd = base->multibase(); // ??
+
+
+ //fprintf(stderr, "vd "); vd->print(); printf("\n"); fflush(stdout);
+
+ chillAST_RecordDecl *rd = vd->getStructDef();
+ if (!rd) {
+ fprintf(stderr, "chillAST_MemberExpr::multibase() vardecl is not a struct??\n");
+ fprintf(stderr, "vd "); vd->print(); printf("\n"); fflush(stdout);
+ fprintf(stderr, "vd "); vd->dump(); printf("\n"); fflush(stdout);
+ exit(-1);
+ }
+
+ // OK, we have the recorddecl that defines the structure
+ // now find the member with the correct name
+ chillAST_VarDecl *sub = rd->findSubpart( member );
+ //fprintf(stderr, "sub %s:\n", member);
+ if (!sub) {
+ fprintf(stderr, "can't find member %s in \n", member);
+ rd->print();
+ }
+ //sub->print(); printf("\n"); fflush(stdout);
+ //sub->dump() ; printf("\n"); fflush(stdout);
+
+ return sub;
+ //find vardecl of member in def of base
+
+
+}
+
+
+
+
+chillAST_DeclRefExpr::chillAST_DeclRefExpr() {
+ asttype = CHILLAST_NODETYPE_DECLREFEXPR;
+ declarationType = strdup("UNKNOWN");
+ declarationName = strdup("NONE");
+ decl = NULL;
+ parent = NULL;
+ metacomment = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_DeclRefExpr::chillAST_DeclRefExpr( const char *varname, chillAST_node *par ) {
+ asttype = CHILLAST_NODETYPE_DECLREFEXPR;
+ declarationType = strdup("UNKNOWN");
+ declarationName = strdup(varname);
+ decl = NULL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_DeclRefExpr::chillAST_DeclRefExpr( const char *vartype, const char *varname, chillAST_node *par) {
+ //fprintf(stderr, "DRE::DRE 0x%x %s %s\n", this, vartype, varname );
+ asttype = CHILLAST_NODETYPE_DECLREFEXPR;
+ declarationType = strdup(vartype);
+ declarationName = strdup(varname);
+ decl = NULL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_DeclRefExpr::chillAST_DeclRefExpr( const char *vartype, const char *varname, chillAST_node *d, chillAST_node *par ) {
+ //fprintf(stderr, "DRE::DRE2 0x%x %s %s 0x%x\n", this, vartype, varname, d );
+ asttype = CHILLAST_NODETYPE_DECLREFEXPR;
+ declarationType = strdup(vartype);
+ declarationName = strdup(varname);
+ decl = d;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_DeclRefExpr::chillAST_DeclRefExpr( chillAST_VarDecl *vd, chillAST_node *par ){ // variable def
+ //fprintf(stderr, "DRE::DRE3 (VD) 0x%x %s %s 0x%x\n", this, vd->vartype, vd->varname, vd );
+
+ asttype = CHILLAST_NODETYPE_DECLREFEXPR;
+ declarationType = strdup(vd->vartype);
+ declarationName = strdup(vd->varname);
+ decl = vd;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+chillAST_DeclRefExpr::chillAST_DeclRefExpr( chillAST_FunctionDecl *fd, chillAST_node *par ){ // function def
+ asttype = CHILLAST_NODETYPE_DECLREFEXPR;
+ declarationType = strdup(fd->returnType);
+ declarationName = strdup(fd->functionName);
+ decl = fd;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+
+chillAST_DeclRefExpr *buildDeclRefExpr( chillAST_VarDecl *vd) {
+ chillAST_DeclRefExpr *dre = new chillAST_DeclRefExpr( vd, NULL );
+
+}
+
+void chillAST_DeclRefExpr::print( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ //fprintf(fp, "%s %s", declarationType, declarationName); // this is printing float *A
+ fprintf(fp, "%s", declarationName); // this is printing A
+ fflush(fp);
+}
+
+
+char *chillAST_DeclRefExpr::stringRep( int indent ) {
+ return strdup( declarationName );
+}
+
+
+void chillAST_DeclRefExpr::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "(DeclRefExpr '%s' ", declarationType);
+ chillAST_VarDecl *vd = getVarDecl();
+ if (vd) {
+ if (vd->isAParameter) fprintf(fp, "ParmVar ");
+ else fprintf(fp, "Var ");
+ }
+ fprintf(fp, "'%s' ", declarationName); // variable or function name
+
+ if (chillAST_FunctionDecl *fd = getFunctionDecl()) {
+ // print parameter types for functions
+ fd->printParameterTypes( fp );
+ }
+
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+class chillAST_node* chillAST_DeclRefExpr::constantFold() { // can never do anything?
+ return this;
+}
+
+class chillAST_node* chillAST_DeclRefExpr::clone() {
+ //fprintf(stderr, "chillAST_DeclRefExpr::clone()\n");
+ chillAST_DeclRefExpr *DRE = new chillAST_DeclRefExpr( declarationType, declarationName, decl, parent );
+ DRE->isFromSourceFile = isFromSourceFile;
+ if (filename) DRE->filename = strdup(filename);
+ return DRE;
+}
+
+
+void chillAST_DeclRefExpr::gatherVarDeclsMore( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_DeclRefExpr::gatherVarDeclsMore()\n");
+ decl->gatherVarDeclsMore( decls );
+}
+
+
+void chillAST_DeclRefExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_DeclRefExpr::gatherScalarVarDecls()\n");
+ decl->gatherScalarVarDecls(decls);
+ //fprintf(stderr, "now %d scalar vardecls\n", decls.size());
+}
+
+
+void chillAST_DeclRefExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_DeclRefExpr::gatherArrayVarDecls()\n");
+ decl->gatherArrayVarDecls(decls);
+ //fprintf(stderr, "now %d Array vardecls\n", decls.size());
+}
+
+
+void chillAST_DeclRefExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ refs.push_back(this);
+}
+
+void chillAST_DeclRefExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ refs.push_back(this);
+}
+
+void chillAST_DeclRefExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_DeclRefExpr::gatherVarUsage()\n");
+ for (int i=0; i<decls.size(); i++) {
+ if (decls[i] == decl) {
+ //fprintf(stderr, "decl was already there\n");
+ return;
+ }
+ if (streq(declarationName, decls[i]->varname)) {
+ if (streq(declarationType, decls[i]->vartype)) {
+ //fprintf(stderr, "decl was already there\n");
+ return;
+ }
+ }
+ }
+ chillAST_VarDecl *vd = getVarDecl(); // null for functiondecl
+ if (vd) decls.push_back( vd );
+
+}
+
+
+
+
+void chillAST_DeclRefExpr::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ //fprintf(stderr, "chillAST_DeclRefExpr::replaceVarDecls()\n");
+ if (decl == olddecl) {
+ //fprintf(stderr, "replacing old %s with %s\n", olddecl->varname, newdecl->varname);
+ //fprintf(stderr, "DRE was "); print();
+ decl = newdecl;
+ declarationType = strdup(newdecl->vartype);
+ declarationName = strdup(newdecl->varname);
+ //fprintf(stderr, "\nDRE is "); print(); fprintf(stderr, "\n\n");
+ }
+ else {
+ if (!strcmp(olddecl->varname, declarationName)) {
+ //fprintf(stderr, "uhoh, chillAST_DeclRefExpr::replaceVarDecls()\n");
+ decl = newdecl;
+ declarationType = strdup(newdecl->vartype);
+ declarationName = strdup(newdecl->varname);
+ }
+ }
+}
+
+chillAST_VarDecl *chillAST_ImplicitCastExpr::multibase() {
+ return subexpr->multibase();
+}
+
+
+chillAST_VarDecl *chillAST_DeclRefExpr::multibase() {
+ // presumably, this is being called because this DRE is the base of an ArraySubscriptExpr
+ return getVarDecl();
+}
+
+
+
+
+
+
+
+
+
+void chillAST_VarDecl::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_VarDecl::gatherVarDecls()\n");
+ for (int i=0; i<decls.size(); i++) {
+ if (decls[i] == this) {
+ //fprintf(stderr, "decl was already there\n");
+ return;
+ }
+ if (streq(decls[i]->varname, varname)) {
+ if (streq(decls[i]->vartype, vartype)) {
+ //fprintf(stderr, "VarDecl (direct) decl was already there\n");
+ return;
+ }
+ }
+ }
+ decls.push_back( this );
+}
+
+
+void chillAST_VarDecl::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_VarDecl::gatherScalarVarDecls(), %s numdimensions %d\n", varname, numdimensions);
+
+ if (numdimensions != 0) return; // not a scalar
+
+ for (int i=0; i<decls.size(); i++) {
+ if (decls[i] == this) {
+ //fprintf(stderr, "decl was already there\n");
+ return;
+ }
+
+ if (streq(decls[i]->varname, varname)) { // wrong. scoping. TODO
+ if (streq(decls[i]->vartype, vartype)) {
+ //fprintf(stderr, "VarDecl (direct) decl was already there\n");
+ return;
+ }
+ }
+ }
+ //fprintf(stderr, "adding vardecl for %s to decls\n", varname);
+ decls.push_back( this );
+}
+
+
+void chillAST_VarDecl::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_VarDecl::gatherScalarVarDecls(), %s numdimensions %d\n", varname, numdimensions);
+
+ if (numdimensions == 0) return; // not an array
+
+ for (int i=0; i<decls.size(); i++) {
+ if (decls[i] == this) {
+ //fprintf(stderr, "decl was already there\n");
+ return;
+ }
+
+ if (streq(decls[i]->varname, varname)) { // wrong. scoping. TODO
+ if (streq(decls[i]->vartype, vartype)) {
+ //fprintf(stderr, "VarDecl (direct) decl was already there\n");
+ return;
+ }
+ }
+ }
+ //fprintf(stderr, "adding vardecl for %s to decls\n", varname);
+ decls.push_back( this );
+}
+
+
+
+chillAST_node *chillAST_VarDecl::constantFold() { return this; }
+
+chillAST_node* chillAST_VarDecl::clone() {
+ fprintf(stderr, "\nchillAST_VarDecl::clone() cloning vardecl for %s\n", varname);
+ if (isAParameter) fprintf(stderr, "old vardecl IS a parameter\n");
+ //else fprintf(stderr, "old vardecl IS NOT a parameter\n");
+
+ chillAST_VarDecl *vd = new chillAST_VarDecl( vartype, strdup(varname), arraypart, NULL); // NULL so we don't add the variable AGAIN to the (presumably) function
+
+ vd->typedefinition = typedefinition;
+ vd->vardef = vardef; // perhaps should not do this TODO
+ //vd->isStruct = (vardef != NULL); // ??
+
+ vd->underlyingtype = strdup(underlyingtype);
+
+ vd->arraysizes = NULL;
+ vd->knownArraySizes = knownArraySizes;
+ vd->numdimensions = numdimensions;
+ vd->arraypointerpart = NULL;
+
+ if (arraypart != NULL && NULL!=arraysizes) { // !strcmp(arraypart, "")) {
+ //fprintf(stderr, "in chillAST_VarDecl::clone(), cloning the array info\n");
+ //fprintf(stderr, "numdimensions %d arraysizes 0x%x\n", numdimensions, arraysizes) ;
+ vd->numdimensions = numdimensions;
+
+ if (arraysizes) {
+ vd->arraysizes = (int *)malloc( sizeof(int *) * numdimensions );
+ for (int i=0; i< numdimensions; i++) {
+ //fprintf(stderr, "i %d\n", i);
+ vd->arraysizes[i] = arraysizes[i];
+ }
+ }
+ }
+
+ if ( arraypointerpart ) {
+ //fprintf(stderr, "copying arraypointerpart\n");
+ vd->arraypointerpart = strdup( arraypointerpart);
+ }
+
+ vd->isStruct = this->isStruct;
+ //vd->insideAStruct = this->insideAStruct;
+
+ //if (vd->isStruct) fprintf(stderr, "vardecl::clone() %s is a struct\n", varname);
+ //else fprintf(stderr, "vardecl::clone() %s is NOT a struct\n", varname);
+
+
+ vd->knownArraySizes = this->knownArraySizes;
+ vd->isFromSourceFile = isFromSourceFile;
+ if (filename) vd->filename = strdup(filename);
+ return vd;
+}
+
+
+void chillAST_VarDecl::splitarraypart() {
+ fprintf(stderr, "chillAST_VarDecl::splitarraypart() ");
+ //fprintf(stderr, "%p ", arraypart);
+ if (arraypart) fprintf(stderr, "%s", arraypart);
+ fprintf(stderr, "\n");
+
+ // split arraypart into (leading??) asterisks and known sizes [1][2][3]
+ if (!arraypart || // NULL
+ (arraypart && (*arraypart == '\0'))) { // or empty string
+
+ // parts are both empty string
+ if (arraypointerpart) free(arraypointerpart);
+ arraypointerpart = strdup("");
+ if (arraysetpart) free(arraysetpart);
+ arraysetpart = strdup("");
+ return;
+ }
+
+ // arraypart exists and is not empty
+ int asteriskcount = 0;
+ int fixedcount = 0;
+ for ( int i=0; i<strlen(arraypart); i++) {
+ if (arraypart[i] == '*') {
+ if (fixedcount) {
+ fprintf(stderr, "illegal vardecl arraypart: '%s'\n", arraypart);
+ segfault();
+ exit(-1);
+ }
+ asteriskcount++;
+ }
+ else { // remainder is fixed?
+ fixedcount++;
+ // check for brackets and digits only? TODO
+ }
+ }
+ arraypointerpart = (char *) calloc( asteriskcount+1, sizeof(char));
+ arraysetpart = (char *) calloc( fixedcount+1, sizeof(char));
+ char *ptr = arraypart;
+ for ( int i=0; i<asteriskcount; i++) arraypointerpart[i] = *ptr++;
+ for ( int i=0; i<fixedcount; i++) arraysetpart[i] = *ptr++;
+
+ //fprintf(stderr, "%s = %s + %s\n", arraypart, arraypointerpart, arraysetpart);
+}
+
+
+
+
+
+
+chillAST_IntegerLiteral::chillAST_IntegerLiteral(int val, chillAST_node *par){
+ value = val;
+ asttype = CHILLAST_NODETYPE_INTEGERLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_IntegerLiteral::print( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "%d", value);
+ fflush(fp);
+}
+
+void chillAST_IntegerLiteral::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "(IntegerLiteral 'int' %d)\n", value);
+ fflush(fp);
+}
+
+
+
+class chillAST_node* chillAST_IntegerLiteral::constantFold() { return this; } // can never do anything
+
+
+class chillAST_node* chillAST_IntegerLiteral::clone() {
+
+ chillAST_IntegerLiteral *IL = new chillAST_IntegerLiteral( value, parent );
+ IL->isFromSourceFile = isFromSourceFile;
+ if (filename) IL->filename = strdup(filename);
+ return IL;
+
+}
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral(float val, chillAST_node *par){
+ value = val;
+ precision = 1;
+ float0double1 = 0; // which is live!
+ allthedigits = NULL;
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral(double val, chillAST_node *par){
+ doublevalue = val;
+ precision = 2;
+ float0double1 = 1; // which is live!
+ allthedigits = NULL;
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral(float val, int precis, chillAST_node *par){
+ value = val;
+ precision = 1;
+ float0double1 = 0; // which is live!
+ precision = precis; //
+ allthedigits = NULL;
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral(double val, int precis, chillAST_node *par){
+ doublevalue = val;
+ float0double1 = 1; // which is live!
+ precision = precis; //
+ allthedigits = NULL;
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral(float val, const char *printthis, chillAST_node *par){
+ value = val;
+ float0double1 = 0; // which is live!
+ precision = 1;
+ allthedigits = NULL;
+ if (printthis) allthedigits = strdup( printthis );
+ //fprintf(stderr, "\nfloatingliteral allthedigits = '%s'\n", allthedigits);
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral(float val, int precis, const char *printthis, chillAST_node *par){
+ value = val;
+ float0double1 = 0; // which is live!
+ precision = precis; // but value is a float?? TODO
+ allthedigits = NULL;
+ if (printthis) {
+ //fprintf(stderr, "\nchillAST_FloatingLiteral constructor, printthis ");
+ //fprintf(stderr, "%p\n", printthis);
+ allthedigits = strdup( printthis );
+ }
+ //fprintf(stderr, "\nfloatingliteral allthedigits = '%s'\n", allthedigits);
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+chillAST_FloatingLiteral::chillAST_FloatingLiteral( chillAST_FloatingLiteral *old ) {
+ //fprintf(stderr, "chillAST_FloatingLiteral::chillAST_FloatingLiteral( old ) allthedigits %p\n", old->allthedigits);
+
+ asttype = CHILLAST_NODETYPE_FLOATINGLITERAL;
+ value = old->value;
+ doublevalue = old->doublevalue;
+ float0double1 = old->float0double1;
+ allthedigits = NULL;
+ if (old->allthedigits) allthedigits = strdup(old->allthedigits);
+ precision = old->precision;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+
+void chillAST_FloatingLiteral::print( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ //fprintf(fp, "%f", value);
+ // attempt to be more like rose output
+ char output[1024]; // warning, hardcoded
+
+ if (allthedigits != NULL) {
+ strcpy(output, allthedigits ); // if they have specified 100 digits of pi, give 'em 100 digits
+ //fprintf(stderr, "floatingliteral allthedigits = '%s'\n", allthedigits);
+ }
+ else {
+ if (float0double1 == 0) sprintf(output, "%f", value);
+ else sprintf(output, "%f", doublevalue);
+
+ // next part to avoid printing 123.4560000000000000000000000000
+ char *dot = index(output, '.');
+ if (dot) {
+ char *end = output + strlen(output);
+ char *onechar;
+ char *lastnonzero = dot;
+ for (onechar = output; onechar < end; onechar ++) {
+ if (*onechar != '0') lastnonzero = onechar;
+ }
+
+ if (lastnonzero == dot)
+ lastnonzero[2] = '\0'; // may be after end of string, but that should be OK
+ else lastnonzero[1] = '\0'; // may be after end of string, but that should be OK
+ }
+ }
+ if (precision == 1) {
+ int len = strlen(output);
+ output[len] = 'f'; // explicit single precision
+ output[len+1] = '\0';
+ }
+
+ fprintf(fp, "%s", output);
+ fflush(fp);
+}
+
+void chillAST_FloatingLiteral::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ // 2x2 cases ???
+ if (precision == 1)
+ fprintf(fp, "(FloatingLiteral 'float' ");
+ else fprintf(fp, "(FloatingLiteral 'double' ");
+
+ if (float0double1 == 0) fprintf(fp, "%f)\n", value); // %f gives enough digits
+ else fprintf(fp, "%f)\n", doublevalue); // %f gives enough digits
+ fflush(fp);
+}
+
+
+chillAST_node* chillAST_FloatingLiteral::constantFold() { return this; }; // NOOP
+
+chillAST_node* chillAST_FloatingLiteral::clone() {
+ //fprintf(stderr, "chillAST_FloatingLiteral::clone() ");
+ //fprintf(stderr, "allthedigits %p \n", allthedigits);
+ chillAST_FloatingLiteral *newone = new chillAST_FloatingLiteral( this );
+
+ newone->isFromSourceFile = isFromSourceFile;
+ if (filename) newone->filename = strdup(filename);
+ //print(); printf(" "); newone->print(); printf("\n"); fflush(stdout);
+ return newone;
+}
+
+bool chillAST_FloatingLiteral::isSameAs( chillAST_node *other ){
+ if (!other->isFloatingLiteral()) return false;
+ chillAST_FloatingLiteral *o = (chillAST_FloatingLiteral *)other;
+ // should we care about single vs double precision?
+ if (float0double1 != o->float0double1) return false;
+ if (float0double1 == 0) {
+ return value == o->value; // WARNING, comparing floats with ==
+ }
+ return doublevalue == o->doublevalue; // WARNING, comparing doubless with ==
+}
+
+
+
+
+
+chillAST_UnaryOperator::chillAST_UnaryOperator( const char *oper, bool pre, chillAST_node *sub, chillAST_node *par ) {
+ op = strdup(oper);
+ prefix = pre;
+ subexpr = sub;
+ subexpr->setParent( this );
+ asttype = CHILLAST_NODETYPE_UNARYOPERATOR;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_UnaryOperator::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ subexpr->gatherArrayRefs( refs, isAssignmentOp()); //
+}
+
+
+
+void chillAST_UnaryOperator::print( int indent, FILE *fp) {
+ bool needparens = false;
+ if (subexpr->isNotLeaf()) needparens = true; // may get more complicated
+
+ chillindent( indent, fp); // will this ever be invoked?
+ if (prefix) fprintf(fp, "%s", op);
+ if (needparens) fprintf(fp, "(");
+ subexpr->print( 0, fp );
+ if (needparens) fprintf(fp, ")");
+ if (!prefix) fprintf(fp, "%s", op);
+ fflush(fp);
+}
+
+
+void chillAST_UnaryOperator::dump( int indent, FILE *fp) {
+ chillindent( indent, fp);
+ fprintf(fp, "(UnaryOperator ");
+ if (prefix) fprintf(fp, "prefix ");
+ else fprintf(fp, "postfix ");
+ fprintf(fp, "%s\n", op);
+ subexpr->dump(indent+1, fp);
+
+ chillindent( indent, fp);
+ fprintf(fp, ")\n");
+}
+
+
+void chillAST_UnaryOperator::gatherVarLHSUsage( vector<chillAST_VarDecl*> &decls ) {
+ if ((!strcmp("++", op)) || (!strcmp("--", op))) {
+ subexpr->gatherVarUsage( decls ); // do all unary modify the subexpr? (no, - )
+ }
+}
+
+
+
+chillAST_node* chillAST_UnaryOperator::constantFold() {
+ //fprintf(stderr, "chillAST_UnaryOperator::constantFold() ");
+ //print(); fprintf(stderr, "\n");
+
+ subexpr = subexpr->constantFold();
+ chillAST_node *returnval = this;
+ if (subexpr->isConstant()) {
+ //fprintf(stderr, "unary op folding constants\n");
+ //print(0,stderr); fprintf(stderr, "\n");
+
+ if (streq(op, "-")) {
+ if (subexpr->isIntegerLiteral()) {
+ int intval = ((chillAST_IntegerLiteral*)subexpr)->value;
+ chillAST_IntegerLiteral *I = new chillAST_IntegerLiteral( -intval, parent);
+ returnval = I;
+ //fprintf(stderr, "integer -%d becomes %d\n", intval, I->value);
+ }
+ else {
+ chillAST_FloatingLiteral *FL = (chillAST_FloatingLiteral*)subexpr;
+ chillAST_FloatingLiteral *F = new chillAST_FloatingLiteral( FL ); // clone
+ F->parent = FL->parent;
+
+ F->value = -F->value;
+ F->doublevalue = -F->doublevalue;
+
+ F->print(); fprintf(stderr, "\n");
+
+ returnval = F;
+ }
+ }
+ else fprintf(stderr, "can't fold op '%s' yet\n", op);
+ }
+ return returnval;
+}
+
+
+class chillAST_node* chillAST_UnaryOperator::clone() {
+ chillAST_UnaryOperator *UO = new chillAST_UnaryOperator( op, prefix, subexpr->clone(), parent );
+ UO->isFromSourceFile = isFromSourceFile;
+ if (filename) UO->filename = strdup(filename);
+ return UO;
+}
+
+
+void chillAST_UnaryOperator::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarDecls( decls );
+}
+
+
+void chillAST_UnaryOperator::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_UnaryOperator::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_UnaryOperator::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ subexpr->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_UnaryOperator::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarUsage( decls );
+}
+
+ void chillAST_UnaryOperator::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl) {
+ subexpr->replaceVarDecls( olddecl, newdecl );
+ }
+
+
+int chillAST_UnaryOperator::evalAsInt() {
+ if (!strcmp("+", op)) return subexpr->evalAsInt();
+ if (!strcmp("-", op)) return -subexpr->evalAsInt();
+ if (!strcmp("++", op)) return 1 + subexpr->evalAsInt();
+ if (!strcmp("--", op)) return subexpr->evalAsInt() - 1;
+
+ fprintf(stderr, "chillAST_UnaryOperator::evalAsInt() unhandled op '%s'\n", op);
+ segfault();
+
+}
+
+bool chillAST_UnaryOperator::isSameAs( chillAST_node *other ){
+ if (!other->isUnaryOperator()) return false;
+ chillAST_UnaryOperator *o = (chillAST_UnaryOperator *)other;
+ if (strcmp(op, o->op)) return false; // different operators
+ return subexpr->isSameAs( o->subexpr ); // recurse
+}
+
+
+chillAST_ImplicitCastExpr::chillAST_ImplicitCastExpr( chillAST_node *sub, chillAST_node *par ) {
+ subexpr = sub;
+ subexpr->setParent( this );
+ asttype = CHILLAST_NODETYPE_IMPLICITCASTEXPR;
+ parent = par;
+ //fprintf(stderr, "ImplicitCastExpr 0x%x has subexpr 0x%x", this, subexpr);
+ //fprintf(stderr, " of type %s\n", subexpr->getTypeString());
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_ImplicitCastExpr::print( int indent, FILE *fp) {
+ // No need to print anything, simply forward to the sub expression.
+ subexpr->print( indent, fp );
+ fflush(fp);
+};
+
+void chillAST_ImplicitCastExpr::printonly( int indent, FILE *fp) {
+ // No need to print anything, simply forward to the sub expression.
+ subexpr->printonly( indent, fp );
+ fflush(fp);
+};
+
+void chillAST_ImplicitCastExpr::replaceChild( chillAST_node *old, chillAST_node *newchild ){
+ if (subexpr == old) { // should be the case for this to get called
+ subexpr = newchild;
+ subexpr->setParent( this );
+ //old->parent = NULL;
+ return;
+ }
+
+ fprintf(stderr, "chillAST_ImplicitCastExpr::replaceChild() called with bad 'old'\n");
+ exit(-1); // ??
+}
+
+class chillAST_node* chillAST_ImplicitCastExpr::constantFold() {
+ chillAST_node *child = subexpr->constantFold();
+ child->setParent( parent ) ; // remove myself !! probably a bad idea. TODO
+ return child;
+}
+
+
+class chillAST_node* chillAST_ImplicitCastExpr::clone() {
+ chillAST_ImplicitCastExpr *ICE = new chillAST_ImplicitCastExpr( subexpr->clone(), parent);
+ ICE->isFromSourceFile = isFromSourceFile;
+ if (filename) ICE->filename = strdup(filename);
+ return ICE;
+}
+
+
+void chillAST_ImplicitCastExpr::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ subexpr->gatherArrayRefs( refs, w );
+}
+
+void chillAST_ImplicitCastExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ subexpr->gatherScalarRefs( refs, writtento );
+}
+
+void chillAST_ImplicitCastExpr::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarDecls( decls );
+}
+
+
+void chillAST_ImplicitCastExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_ImplicitCastExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_ImplicitCastExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ subexpr->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_ImplicitCastExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarUsage( decls );
+}
+
+
+
+chillAST_CStyleCastExpr::chillAST_CStyleCastExpr( const char *to, chillAST_node *sub, chillAST_node *par ) {
+
+ //fprintf(stderr, "chillAST_CStyleCastExpr::chillAST_CStyleCastExpr( %s, ...)\n", to);
+ towhat = strdup(to);
+ subexpr = sub;
+ if (subexpr) subexpr->setParent( this );
+ asttype = CHILLAST_NODETYPE_CSTYLECASTEXPR;
+ parent = par;
+ //fprintf(stderr, "chillAST_CStyleCastExpr (%s) sub 0x%x\n", towhat, sub );
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_CStyleCastExpr::replaceChild( chillAST_node *old, chillAST_node *newchild ){
+ if (subexpr == old) { // should be the case for this to get called
+ subexpr = newchild;
+ subexpr->setParent( this );
+ //old->parent = NULL;
+ return;
+ }
+
+ fprintf(stderr, "chillAST_CStyleCastExpr::replaceChild() called with bad 'old'\n");
+ exit(-1); // ??
+}
+
+ void chillAST_CStyleCastExpr::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl) {
+ subexpr->replaceVarDecls( olddecl, newdecl);
+ }
+
+void chillAST_CStyleCastExpr::print( int indent, FILE *fp) {
+ //fprintf(stderr, "CStyleCastExpr::print()\n");
+ chillindent(indent, fp);
+
+ // special cases? should probably walk the AST and change the literal itself
+ if ( !strcmp("float", towhat) && subexpr->isIntegerLiteral()) { // (float) 3 => 3.0f
+ subexpr->print( 0, fp ); fprintf(fp, ".0f");
+ }
+ else if ( !strcmp("double", towhat) && subexpr->isIntegerLiteral()) { // (double) 3 => 3.0
+ subexpr->print( 0, fp ); fprintf(fp, ".0");
+ }
+ else if ( !strcmp("float", towhat) && subexpr->isFloatingLiteral()) { // (float) 3.0 => 3.0f
+ subexpr->print( 0, fp ); fprintf(fp, "f");
+ }
+ else { // general case
+ fprintf(fp, "((%s) ", towhat);
+ //fprintf(fp, "\ntowhat '%s'\n", towhat );
+
+ if (subexpr->isVarDecl()) fprintf(fp, "%s", ((chillAST_VarDecl *)subexpr)->varname);
+ else subexpr->print( indent, fp );
+ //fprintf(fp, "subexpr '%s' ", subexpr->getTypeString());
+ fprintf(fp, ")");
+ }
+ fflush(fp);
+};
+
+
+void chillAST_CStyleCastExpr::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CStyleCastExpr (%s) \n", towhat);
+ subexpr->dump( indent+1, fp );
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+class chillAST_node* chillAST_CStyleCastExpr::constantFold() {
+ subexpr = subexpr->constantFold();
+ return this;
+}
+
+
+class chillAST_node* chillAST_CStyleCastExpr::clone() {
+ chillAST_CStyleCastExpr *CSCE = new chillAST_CStyleCastExpr( towhat, subexpr->clone(), parent );
+ CSCE->isFromSourceFile = isFromSourceFile;
+ if (filename) CSCE->filename = strdup(filename);
+ return CSCE;
+}
+
+void chillAST_CStyleCastExpr::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ subexpr->gatherArrayRefs( refs, w );
+}
+
+void chillAST_CStyleCastExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ subexpr->gatherScalarRefs( refs, writtento );
+}
+
+
+void chillAST_CStyleCastExpr::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarDecls( decls );
+}
+
+
+void chillAST_CStyleCastExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_CStyleCastExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_CStyleCastExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ subexpr->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_CStyleCastExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarUsage( decls );
+}
+
+
+
+
+chillAST_CStyleAddressOf::chillAST_CStyleAddressOf( chillAST_node *sub, chillAST_node *par ) {
+ subexpr = sub;
+ subexpr->setParent( this );
+ asttype = CHILLAST_NODETYPE_CSTYLEADDRESSOF;
+ parent = par;
+ //fprintf(stderr, "chillAST_CStyleCastExpr (%s) sub 0x%x\n", towhat, sub );
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_CStyleAddressOf::print( int indent, FILE *fp) {
+ //fprintf(stderr, "CStyleAddressOf::print()\n");
+ chillindent(indent, fp);
+ fprintf(fp, "(&");
+ subexpr->print( 0, fp );
+ fprintf(fp, ")");
+ fflush(fp);
+};
+
+void chillAST_CStyleAddressOf::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CStyleAddressOf \n");
+ subexpr->print( indent+1, fp );
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+}
+
+class chillAST_node* chillAST_CStyleAddressOf::constantFold() {
+ subexpr = subexpr->constantFold();
+ return this;
+}
+
+class chillAST_node* chillAST_CStyleAddressOf::clone() {
+ chillAST_CStyleAddressOf *CSAO = new chillAST_CStyleAddressOf( subexpr->clone(), parent );
+ CSAO->isFromSourceFile = isFromSourceFile;
+ if (filename) CSAO->filename = strdup(filename);
+ return CSAO;
+}
+
+void chillAST_CStyleAddressOf::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ subexpr->gatherArrayRefs( refs, w );
+}
+
+void chillAST_CStyleAddressOf::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ subexpr->gatherScalarRefs( refs, writtento );
+}
+
+void chillAST_CStyleAddressOf::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarDecls( decls );
+}
+
+void chillAST_CStyleAddressOf::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_CStyleAddressOf::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_CStyleAddressOf::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ subexpr->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_CStyleAddressOf::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarUsage( decls );
+}
+
+
+
+
+chillAST_Malloc::chillAST_Malloc(chillAST_node *size, chillAST_node *p) {
+ thing = NULL;
+ sizeexpr = size; // probably a multiply like sizeof(int) * 1024
+ asttype = CHILLAST_NODETYPE_MALLOC;
+ parent = p;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+chillAST_Malloc::chillAST_Malloc(char *thething, chillAST_node *numthings, chillAST_node *p) {
+ thing = strdup(thething); // "int" or "float" or "struct widget"
+ sizeexpr = numthings;
+ asttype = CHILLAST_NODETYPE_MALLOC;
+ parent = p;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+chillAST_node* chillAST_Malloc::constantFold() {
+ sizeexpr->constantFold();
+}
+
+chillAST_node* chillAST_Malloc::clone() {
+ chillAST_Malloc *M = new chillAST_Malloc( thing, sizeexpr, parent); // the general version
+ M->isFromSourceFile = isFromSourceFile;
+ if (filename) M->filename = strdup(filename);
+ return M;
+};
+
+void chillAST_Malloc::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ sizeexpr->gatherArrayRefs( refs, writtento );
+};
+
+
+void chillAST_Malloc::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ sizeexpr->gatherScalarRefs( refs, writtento );
+};
+
+void chillAST_Malloc::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ sizeexpr->gatherVarDecls(decls);
+};
+
+void chillAST_Malloc::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ){
+ sizeexpr->gatherScalarVarDecls(decls);
+};
+
+void chillAST_Malloc::gatherArrayVarDecls ( vector<chillAST_VarDecl*> &decls ) {
+ sizeexpr->gatherArrayVarDecls(decls);
+};
+
+void chillAST_Malloc::gatherVarUsage( vector<chillAST_VarDecl*> &decls ){
+ sizeexpr->gatherVarUsage(decls);
+};
+
+
+
+void chillAST_Malloc::print( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "malloc(");
+
+ if (thing) {
+ fprintf(fp, " sizeof(%s) * ", thing );
+ }
+ sizeexpr->print(0,fp);
+ fprintf(fp, ")");
+ fflush(fp);
+};
+
+
+void chillAST_Malloc::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(Malloc \n");
+ sizeexpr->dump( indent+1, fp );
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+ fflush(fp);
+};
+
+
+
+chillAST_CudaMalloc::chillAST_CudaMalloc(chillAST_node *devmemptr, chillAST_node *size, chillAST_node *p) {
+ devPtr = devmemptr;
+ sizeinbytes = size; // probably a multiply like sizeof(int) * 1024
+ asttype = CHILLAST_NODETYPE_CUDAMALLOC;
+ parent = p;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+void chillAST_CudaMalloc::print( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "cudaMalloc(");
+ devPtr->print( 0, fp );
+ fprintf(fp, ",");
+ sizeinbytes->print( 0, fp );
+ fprintf(fp, ")");
+ fflush(fp);
+};
+
+void chillAST_CudaMalloc::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CudaMalloc \n");
+ devPtr->dump( indent+1, fp );
+ fprintf(fp, "\n");
+ sizeinbytes->dump( indent+1, fp );
+ fprintf(fp, ")\n");
+ fflush(fp);
+};
+
+class chillAST_node* chillAST_CudaMalloc::constantFold() {
+ devPtr = devPtr->constantFold();
+ return this;
+}
+
+class chillAST_node* chillAST_CudaMalloc::clone() {
+ chillAST_CudaMalloc *CM = new chillAST_CudaMalloc( devPtr->clone(), sizeinbytes->clone(), parent );
+ CM->isFromSourceFile = isFromSourceFile;
+ if (filename) CM->filename = strdup(filename);
+ return CM;
+}
+
+void chillAST_CudaMalloc::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ devPtr->gatherArrayRefs( refs, false );
+ sizeinbytes->gatherArrayRefs( refs, false );
+}
+
+void chillAST_CudaMalloc::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ devPtr->gatherScalarRefs( refs, false );
+ sizeinbytes->gatherScalarRefs( refs, false );
+}
+
+void chillAST_CudaMalloc::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ devPtr->gatherVarDecls( decls );
+ sizeinbytes->gatherVarDecls( decls );
+}
+
+
+void chillAST_CudaMalloc::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ devPtr->gatherScalarVarDecls( decls );
+ sizeinbytes->gatherScalarVarDecls( decls );
+}
+
+
+
+void chillAST_CudaMalloc::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ devPtr->gatherArrayVarDecls( decls );
+ sizeinbytes->gatherArrayVarDecls( decls );
+}
+
+
+
+void chillAST_CudaMalloc::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ devPtr->gatherVarUsage( decls );
+ sizeinbytes->gatherVarUsage( decls );
+}
+
+
+
+chillAST_CudaFree::chillAST_CudaFree(chillAST_VarDecl *var, chillAST_node *p) {
+ variable = var;
+ parent = p;
+ asttype = CHILLAST_NODETYPE_CUDAFREE;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+void chillAST_CudaFree::print( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "cudaFree(%s)", variable->varname);
+ fflush(fp);
+};
+
+void chillAST_CudaFree::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CudaFree %s )\n", variable->varname);
+ fflush(fp);
+};
+
+class chillAST_node* chillAST_CudaFree::constantFold() {
+ return this;
+}
+
+class chillAST_node* chillAST_CudaFree::clone() {
+ chillAST_CudaFree *CF = new chillAST_CudaFree( variable, parent );
+ CF->isFromSourceFile = isFromSourceFile;
+ if (filename) CF->filename = strdup(filename);
+ return CF;
+}
+
+void chillAST_CudaFree::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {}
+void chillAST_CudaFree::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {}
+
+void chillAST_CudaFree::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ variable->gatherVarDecls( decls );
+}
+
+
+void chillAST_CudaFree::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ variable->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_CudaFree::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ variable->gatherArrayVarDecls( decls );
+}
+
+
+
+void chillAST_CudaFree::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ variable->gatherVarUsage( decls );
+}
+
+
+
+
+
+
+
+
+
+chillAST_CudaMemcpy::chillAST_CudaMemcpy(chillAST_VarDecl *d, chillAST_VarDecl *s, chillAST_node *siz, char *kind, chillAST_node *par) {
+ dest = d;
+ src = s;
+ //fprintf(stderr, "chillAST_CudaMemcpy::chillAST_CudaMemcpy( dest %s, src %s, ...)\n", d->varname, s->varname );
+ size = siz;
+ cudaMemcpyKind = kind;
+ asttype = CHILLAST_NODETYPE_CUDAMEMCPY;
+ isFromSourceFile = true; // default
+ filename = NULL;
+ parent = par;
+};
+
+void chillAST_CudaMemcpy::print( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "cudaMemcpy(%s,%s,", dest->varname, src->varname);
+ //dest->print( 0, fp );
+ //fprintf(fp, ",");
+ // src->print( 0, fp ); just want the src NAME, not name and array info
+ //fprintf(fp, ",");
+ size->print( 0, fp );
+ fprintf(fp, ",%s)", cudaMemcpyKind);
+ fflush(fp);
+};
+
+void chillAST_CudaMemcpy::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CudaMemcpy \n");
+ dest->dump( indent+1, fp );
+ src->dump( indent+1, fp );
+ size->dump( indent+1, fp );
+ chillindent(indent+1, fp);
+ fprintf(fp, ",%s\n", cudaMemcpyKind);
+ fflush(fp);
+};
+
+class chillAST_node* chillAST_CudaMemcpy::constantFold() {
+ dest = (chillAST_VarDecl *)dest->constantFold();
+ src = (chillAST_VarDecl *)src->constantFold();
+ size = size->constantFold();
+ return this;
+}
+
+class chillAST_node* chillAST_CudaMemcpy::clone() {
+ chillAST_CudaMemcpy *CMCPY = new chillAST_CudaMemcpy((chillAST_VarDecl *)(dest->clone()),(chillAST_VarDecl *)(src->clone()), size->clone(), strdup(cudaMemcpyKind), parent );
+ CMCPY->isFromSourceFile = isFromSourceFile;
+ if (filename) CMCPY->filename = strdup(filename);
+ return CMCPY;
+}
+
+void chillAST_CudaMemcpy::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool w ) {
+ dest->gatherArrayRefs( refs, false );
+ src ->gatherArrayRefs( refs, false );
+ size->gatherArrayRefs( refs, false );
+}
+
+void chillAST_CudaMemcpy::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ dest->gatherScalarRefs( refs, false );
+ src ->gatherScalarRefs( refs, false );
+ size->gatherScalarRefs( refs, false );
+}
+
+void chillAST_CudaMemcpy::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ dest->gatherVarDecls( decls );
+ src ->gatherVarDecls( decls );
+ size->gatherVarDecls( decls );
+}
+
+
+void chillAST_CudaMemcpy::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ dest->gatherScalarVarDecls( decls );
+ src ->gatherScalarVarDecls( decls );
+ size->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_CudaMemcpy::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ dest->gatherArrayVarDecls( decls );
+ src ->gatherArrayVarDecls( decls );
+ size->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_CudaMemcpy::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ dest->gatherVarUsage( decls );
+ src ->gatherVarUsage( decls );
+ size->gatherVarUsage( decls );
+}
+
+
+
+chillAST_CudaSyncthreads::chillAST_CudaSyncthreads( chillAST_node *par) {
+ asttype = CHILLAST_NODETYPE_CUDASYNCTHREADS;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+ void chillAST_CudaSyncthreads::print( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "__syncthreads()");
+ fflush(fp);
+ }
+
+ void chillAST_CudaSyncthreads::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(syncthreads)\n");
+ fflush(fp);
+ }
+
+
+
+
+
+
+
+
+
+
+chillAST_ReturnStmt::chillAST_ReturnStmt( chillAST_node *retval, chillAST_node *par ) {
+ asttype = CHILLAST_NODETYPE_RETURNSTMT;
+ returnvalue = retval;
+ if (returnvalue) returnvalue->setParent( this );
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+void chillAST_ReturnStmt::print( int indent, FILE *fp) {
+ printPreprocBEFORE(indent, fp);
+ chillindent(indent, fp);
+ if (returnvalue != NULL) {
+ fprintf(fp, "return(");
+ returnvalue->print( 0, fp );
+ fprintf(fp, ")" ); // parent will add ";\n" ??
+ }
+ else {
+ fprintf(fp, "return");
+ }
+ fflush(fp);
+}
+
+
+void chillAST_ReturnStmt::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "(ReturnStmt");
+ if (returnvalue) {
+ fprintf(fp, "\n");
+ returnvalue->dump(indent+1,fp);
+ chillindent(indent, fp);
+ }
+ fprintf(fp, ")\n");
+}
+
+
+class chillAST_node* chillAST_ReturnStmt::constantFold() {
+ if (returnvalue) returnvalue = returnvalue->constantFold();
+ return this;
+}
+
+
+
+class chillAST_node* chillAST_ReturnStmt::clone() {
+ chillAST_node *val = NULL;
+ if ( returnvalue ) val = returnvalue->clone();
+ chillAST_ReturnStmt *RS = new chillAST_ReturnStmt( val, parent );
+ RS->isFromSourceFile = isFromSourceFile;
+ if (filename) RS->filename = strdup(filename);
+ return RS;
+}
+
+
+void chillAST_ReturnStmt::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ if (returnvalue) returnvalue->gatherVarDecls( decls );
+}
+
+
+void chillAST_ReturnStmt::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ if (returnvalue) returnvalue->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_ReturnStmt::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ if (returnvalue) returnvalue->gatherArrayVarDecls( decls );
+}
+
+
+
+void chillAST_ReturnStmt::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ if (returnvalue) returnvalue->gatherDeclRefExprs( refs );
+}
+
+
+
+void chillAST_ReturnStmt::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ if (returnvalue) returnvalue->gatherVarUsage( decls );
+}
+
+
+
+
+chillAST_CallExpr::chillAST_CallExpr(chillAST_node *c, chillAST_node *par) { //, int numofargs, chillAST_node **theargs ) {
+
+ //fprintf(stderr, "chillAST_CallExpr::chillAST_CallExpr callee type %s\n", c->getTypeString());
+ asttype = CHILLAST_NODETYPE_CALLEXPR;
+ callee = c;
+ //callee->setParent( this ); // ??
+ numargs = 0;
+ parent = par;
+ grid = block = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+
+void chillAST_CallExpr::addArg( chillAST_node *a ) {
+ args.push_back( a );
+ a->setParent( this );
+ numargs += 1;
+}
+
+
+void chillAST_CallExpr::print( int indent, FILE *fp) {
+ printPreprocBEFORE(indent, fp);
+ chillindent(indent, fp);
+ chillAST_FunctionDecl *FD = NULL;
+ chillAST_MacroDefinition *MD = NULL;
+
+ if (callee->isDeclRefExpr()) {
+ chillAST_DeclRefExpr *DRE = (chillAST_DeclRefExpr *) callee;
+ //fprintf(stderr, "DRE decl is 0x%x\n", DRE->decl);
+ if (!DRE->decl) {
+ // a macro?
+ fprintf(fp, "%s ", DRE->declarationName);
+ return; // ??
+ }
+
+ //fprintf(stderr, "DRE decl of type %s\n", DRE->decl->getTypeString());
+ if ( (DRE->decl)->isFunctionDecl()) FD = (chillAST_FunctionDecl *)DRE->decl;
+ else {
+ fprintf(stderr, "chillAST_CallExpr::print() DRE decl of type %s\n", DRE->decl->getTypeString());
+ exit(-1);
+ }
+ }
+ else if (callee->isFunctionDecl()) FD = (chillAST_FunctionDecl *) callee;
+ else if (callee->isMacroDefinition()) {
+ MD = (chillAST_MacroDefinition *) callee;
+ fprintf(fp, "%s(", MD->macroName);
+ }
+ else {
+ fprintf(stderr, "\nchillAST_CallExpr::print() callee of unhandled type %s\n", callee->getTypeString());
+ callee->dump();
+ exit(-1);
+ }
+
+ if (FD) {
+ fprintf(fp, "%s", FD->functionName ); fflush(fp);
+ if (grid && block) {
+ fprintf(fp, "<<<%s,%s>>>(", grid->varname, block->varname); // a
+ }
+ else fprintf(fp, "(");
+ }
+
+
+ //callee->print( indent, fp);
+ for (int i=0; i<args.size(); i++) {
+ if (i!=0) fprintf(fp, ", ");
+ args[i]->print(0, fp);
+ }
+ fprintf(fp, ")"); //a
+ fflush(fp);
+}
+
+void chillAST_CallExpr::dump( int indent, FILE *fp) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CallExpr ");
+ //fprintf(stderr, "callee type %s\n", callee->getTypeString());
+ chillAST_FunctionDecl *fd = NULL;
+ if (callee->isDeclRefExpr()) { // always?
+ chillAST_DeclRefExpr *dre = (chillAST_DeclRefExpr *)callee;
+ fd = dre->getFunctionDecl(); // if NULL, we've got a Vardecl instead
+ if (fd) {
+ //fd->print();
+ fprintf(fp, "%s\n", fd->returnType);
+ }
+
+ callee->dump(indent+1, fp);
+ if (fd) {
+ int numparams = fd->parameters.size();
+ for (int i=0; i<numparams; i++) fd->parameters[i]->dump(indent+1, fp);
+ }
+ }
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+}
+
+void chillAST_CallExpr::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherArrayRefs( refs, writtento );
+ }
+}
+void chillAST_CallExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherScalarRefs( refs, writtento );
+ }
+}
+
+
+void chillAST_CallExpr::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherVarDecls( decls );
+ }
+}
+
+
+void chillAST_CallExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherScalarVarDecls( decls );
+ }
+}
+
+
+void chillAST_CallExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherArrayVarDecls( decls );
+ }
+}
+
+
+void chillAST_CallExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherDeclRefExprs( refs );
+ }
+}
+
+void chillAST_CallExpr::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ for (int i=0; i<args.size(); i++) args[i]->replaceVarDecls( olddecl, newdecl );
+}
+
+void chillAST_CallExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<args.size(); i++) {
+ args[i]->gatherVarUsage( decls );
+ }
+}
+
+
+chillAST_node* chillAST_CallExpr::constantFold() {
+ numargs = args.size(); // wrong place for this
+ for (int i=0; i<numargs; i++) {
+ args[i] = args[i]->constantFold();
+ }
+ return this;
+}
+
+chillAST_node* chillAST_CallExpr::clone() {
+ //fprintf(stderr, "chillAST_CallExpr::clone()\n");
+ //print(0, stderr); fprintf(stderr, "\n");
+
+ chillAST_CallExpr *CE = new chillAST_CallExpr( callee->clone(), NULL );
+ for (int i=0; i<args.size(); i++) CE->addArg( args[i]->clone() );
+ CE->isFromSourceFile = isFromSourceFile;
+ if (filename) CE->filename = strdup(filename);
+ return CE;
+}
+
+
+
+
+chillAST_VarDecl::chillAST_VarDecl() {
+ //fprintf(stderr, "0chillAST_VarDecl::chillAST_VarDecl() %p\n", this);
+ fprintf(stderr, "0chillAST_VarDecl::chillAST_VarDecl()\n");
+ vartype = underlyingtype = varname = arraypart = arraypointerpart = arraysetpart = NULL;
+ typedefinition = NULL;
+
+ //fprintf(stderr, "setting underlying type NULL\n" );
+ init = NULL;
+ numdimensions=0; arraysizes = NULL;
+ asttype = CHILLAST_NODETYPE_VARDECL; //
+ parent = NULL;
+ metacomment = NULL;
+
+ vardef = NULL;
+ isStruct = false;
+
+ //insideAStruct = false;
+ isAParameter = false;
+ byreference = false;
+ isABuiltin = false;
+ isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n");
+ knownArraySizes = false;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+
+chillAST_VarDecl::chillAST_VarDecl( const char *t, const char *n, const char *a, chillAST_node *par) {
+ //fprintf(stderr, "1chillAST_VarDecl::chillAST_VarDecl( type %s, name %s, arraypart %s, parent %p) %p\n", t, n, a, par, this);
+ fprintf(stderr, "1chillAST_VarDecl::chillAST_VarDecl( type %s, name %s, arraypart %s)\n", t, n, a);
+ vartype = strdup(t);
+ typedefinition = NULL;
+
+ underlyingtype = parseUnderlyingType( vartype );
+ //fprintf(stderr, "setting underlying type %s from %s\n", underlyingtype, vartype );
+ varname = strdup(n);
+ arraypointerpart = arraysetpart = NULL;
+ if (a) arraypart = strdup(a);
+ else arraypart = strdup("");
+ splitarraypart();
+
+ init = NULL;
+ numdimensions=0; arraysizes = NULL;
+ uniquePtr = NULL;
+ asttype = CHILLAST_NODETYPE_VARDECL;
+ parent = par;
+
+
+
+ knownArraySizes = false;
+ //fprintf(stderr, "arraypart len %d\n", strlen(a));
+ for (int i=0; i<strlen(a); i++) {
+ if (a[i] == '[') { numdimensions++; knownArraySizes = true; }
+ if (!knownArraySizes && a[i] == '*') numdimensions++;
+ }
+
+ vardef = NULL;
+ isStruct = false;
+
+ //insideAStruct = false;
+ isAParameter = false;
+ byreference = false;
+ isABuiltin = false;
+ isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n");
+
+ if (parent) {
+ //fprintf(stderr, "chillAST_VarDecl::chillAST_VarDecl( %s ), adding to symbol table???\n", varname);
+ parent->addVariableToSymbolTable( this ); // should percolate up until something has a symbol table
+
+ }
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+
+chillAST_VarDecl::chillAST_VarDecl( chillAST_RecordDecl *astruct, const char *nam, const char *array, chillAST_node *par) {
+ // define a variable whose type is a struct!
+
+ fprintf(stderr, "3chillAST_VarDecl::chillAST_VarDecl( %s %p struct ", nam, this );
+ const char *type = astruct->getName();
+ fprintf (stderr, "%s, name %s, arraypart %s parent ) %p\n", type, nam, array, this); // , par);
+
+ vartype = strdup(type);
+
+ // these always go together ??
+ vardef = astruct;// pointer to the thing that says what is inside the struct
+ isStruct = true; // ?? wrong if it's a union ?? TODO
+
+ //insideAStruct = false;
+ //fprintf(stderr, "setting vardef of %s to %p\n", nam, vardef);
+
+ underlyingtype = parseUnderlyingType( vartype );
+ //fprintf(stderr, "setting underlying type %s from %s\n", underlyingtype, vartype );
+ varname = strdup(nam);
+ arraypart = strdup(array);
+ arraypointerpart = arraysetpart = NULL;
+ splitarraypart();
+
+ init = NULL;
+ numdimensions=0; arraysizes = NULL;
+ uniquePtr = NULL;
+ asttype = CHILLAST_NODETYPE_VARDECL;
+ parent = par;
+
+ knownArraySizes = false;
+ //fprintf(stderr, "arraypart len %d\n", strlen(a));
+ for (int i=0; i<strlen(array); i++) {
+ if (array[i] == '[') { numdimensions++; knownArraySizes = true; }
+ if (!knownArraySizes && array[i] == '*') numdimensions++;
+ }
+
+ isAParameter = false;
+ fprintf(stderr, "%s is NOT a parameter\n", nam);
+ byreference = false;
+ isABuiltin = false;
+ isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n");
+ typedefinition = NULL;
+
+ //fprintf(stderr, "chillAST_VarDecl::chillAST_VarDecl( chillAST_RecordDecl *astruct, ...) MIGHT add struct to some symbol table\n");
+ //if (parent) fprintf(stderr, "yep, adding it\n");
+
+ if (parent) parent->addVariableToSymbolTable( this ); // should percolate up until something has a symbol table
+
+ isFromSourceFile = true; // default
+ filename = NULL;
+
+};
+
+
+
+
+
+chillAST_VarDecl::chillAST_VarDecl( chillAST_TypedefDecl *tdd, const char *n, const char *a, chillAST_node *par) {
+ fprintf(stderr, "4chillAST_VarDecl::chillAST_VarDecl( %s typedef ", n);
+ const char *type = tdd->getStructName();
+ //fprintf (stderr, "%s, name %s, arraypart %s parent ) %p\n", type, n, a,this); // , par);
+ typedefinition = tdd;
+ vartype = strdup(type);
+ underlyingtype = parseUnderlyingType( vartype );
+ //fprintf(stderr, "setting underlying type %s from %s\n", underlyingtype, vartype );
+ varname = strdup(n);
+ arraypart = strdup(a);
+ arraypointerpart = arraysetpart = NULL;
+ splitarraypart();
+
+ init = NULL;
+ numdimensions=0; arraysizes = NULL;
+ uniquePtr = NULL;
+ asttype = CHILLAST_NODETYPE_VARDECL;
+ parent = par;
+
+ knownArraySizes = false;
+ //fprintf(stderr, "arraypart len %d\n", strlen(a));
+ for (int i=0; i<strlen(a); i++) {
+ if (a[i] == '[') { numdimensions++; knownArraySizes = true; }
+ if (!knownArraySizes && a[i] == '*') numdimensions++;
+ }
+
+ isStruct = tdd->isAStruct();
+
+ //insideAStruct = false;
+
+ vardef = NULL;
+
+
+ isAParameter = false;
+ byreference = false;
+ isABuiltin = false;
+ isRestrict = isDevice = isShared = false; // //fprintf(stderr, "RDS = false\n");
+ if (parent) parent->addVariableToSymbolTable( this ); // should percolate up until something has a symbol table
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+
+
+
+chillAST_VarDecl::chillAST_VarDecl( const char *t, const char *n, const char *a, void *ptr, chillAST_node *par) {
+ fprintf(stderr, "2chillAST_VarDecl::chillAST_VarDecl( type %s, name %s, arraypart '%s' ) %p\n", t, n, a, this);
+ //fprintf(stderr, "2chillAST_VarDecl::chillAST_VarDecl( type %s, name %s, arraypart %s, ptr 0x%x, parent 0x%x )\n", t, n, a, ptr, par);
+
+
+ vartype = strdup(t);
+ typedefinition = NULL;
+ underlyingtype = parseUnderlyingType( vartype );
+ //fprintf(stderr, "setting underlying type %s from %s\n", underlyingtype, vartype );
+ varname = strdup(n);
+
+ vardef = NULL; // not a struct
+ isStruct = false;
+ isAParameter = false;
+
+ if (a) arraypart = strdup(a);
+ else arraypart = strdup(""); // should catch this earlier
+ arraypointerpart = arraysetpart = NULL;
+ splitarraypart();
+
+ init = NULL;
+ numdimensions=0; arraysizes = NULL;
+ uniquePtr = ptr;
+ asttype = CHILLAST_NODETYPE_VARDECL;
+ parent = par;
+ knownArraySizes = false;
+
+ if (par) par->addChild(this); // ??
+
+ //fprintf(stderr, "name arraypart len %d\n", strlen(a));
+ //fprintf(stderr, "arraypart '%s'\n", arraypart);
+ for (int i=0; i<strlen(a); i++) {
+ if (a[i] == '[') { numdimensions++; knownArraySizes = true; }
+ if (!knownArraySizes && a[i] == '*') numdimensions++; // fails for a[4000 * 4]
+ }
+ //if (0 == strlen(a) && numdimensions == 0) {
+ // for (int i=0; i<strlen(t); i++) { // handle float * x
+ // if (t[i] == '[') numdimensions++;
+ // if (t[i] == '*') numdimensions++;
+ // }
+ //}
+ //fprintf(stderr, "2name %s numdimensions %d\n", n, numdimensions);
+
+
+
+
+ // this is from ir_clang.cc ConvertVarDecl(), that got executed AFTER the vardecl was constructed. dumb
+ int numdim = 0;
+ //knownArraySizes = true;
+ //if (index(vartype, '*')) knownArraySizes = false; // float *a; for example
+ //if (index(arraypart, '*')) knownArraySizes = false;
+
+ // note: vartype here, arraypart in next code.. is that right?
+ if (index(vartype, '*')) {
+ for (int i = 0; i<strlen(vartype); i++) if (vartype[i] == '*') numdim++;
+ //fprintf(stderr, "numd %d\n", numd);
+ numdimensions = numdim;
+ }
+
+ if (index(arraypart, '[')) { // JUST [12][34][56] no asterisks
+ char *dupe = strdup(arraypart);
+
+ int len = strlen(arraypart);
+ for (int i=0; i<len; i++) if (dupe[i] == '[') numdim++;
+
+ //fprintf(stderr, "numdim %d\n", numdim);
+
+ numdimensions = numdim;
+ int *as = (int *)malloc(sizeof(int *) * numdim );
+ if (!as) {
+ fprintf(stderr, "can't malloc array sizes in ConvertVarDecl()\n");
+ exit(-1);
+ }
+ arraysizes = as; // 'as' changed later!
+
+
+ char *ptr = dupe;
+ //fprintf(stderr, "dupe '%s'\n", ptr);
+ while (ptr = index(ptr, '[')) { // this fails for float a[4000*4]
+ ptr++;
+ char *leak = strdup(ptr);
+ char *close = index(leak, ']');
+ if (close) *close = '\0';
+
+ int l = strlen(leak);
+ bool justdigits = true;
+ bool justmath = true;
+ for (int i=0; i<l; i++) {
+ char c = leak[i];
+ if (!isdigit(c)) justdigits = false;
+ if (!( isdigit(c) ||
+ isblank(c) ||
+ ((c == '+') || (c == '*') || (c == '*') || (c == '*')) || // math
+ ((c == '(') || (c == ')')))
+ ) {
+ //fprintf(stderr, " not justmath because '%c'\n", c);
+ justmath = false;
+ }
+
+ }
+
+ //fprintf(stderr, "tmp '%s'\n", leak);
+ if (justdigits) {
+ int dim;
+ sscanf(ptr, "%d", &dim);
+ //fprintf(stderr, "dim %d\n", dim);
+ *as++ = dim;
+ }
+ else {
+ if (justmath) fprintf(stderr, "JUST MATH\n");
+ fprintf(stderr, "need to evaluate %s, faking with hardcoded 16000\n", leak);
+ *as++ = 16000; // temp TODO DFL
+ }
+ free (leak);
+
+ ptr = index(ptr, ']');
+ //fprintf(stderr, "bottom of loop, ptr = '%s'\n", ptr);
+ }
+ free(dupe);
+ //for (int i=0; i<numdim; i++) {
+ // fprintf(stderr, "dimension %d = %d\n", i, arraysizes[i]);
+ //}
+
+ //fprintf(stderr, "need to handle [] array to determine num dimensions\n");
+ //exit(-1);
+ }
+
+
+ //insideAStruct = false;
+ byreference = false;
+ isABuiltin = false;
+ isRestrict = isDevice = isShared = false; // fprintf(stderr, "RDS = false\n");
+
+ //print(); printf("\n"); fflush(stdout);
+
+ // currently this is bad, because a struct does not have a symbol table, so the
+ // members of a struct are passed up to the func or sourcefile.
+ if (parent) parent->addVariableToSymbolTable( this ); // should percolate up until something has a symbol table
+
+
+ isFromSourceFile = true; // default
+ filename = NULL;
+
+ fprintf(stderr, "2chillAST_VarDecl::chillAST_VarDecl LEAVING\n");
+ //parent->print(); fprintf(stderr, "\n\n");
+
+
+};
+
+
+void chillAST_VarDecl::print( int indent, FILE *fp ) {
+ //fprintf(fp, "chillAST_VarDecl::print()\n");
+
+ printPreprocBEFORE(indent, fp);
+
+ //fprintf(fp, "VarDecl vartype '%s' varname %s ", vartype, varname);
+ //if (isAStruct()) fprintf(fp, "isAStruct()\n");
+ //else fprintf(fp, "NOT A Struct\n");
+
+ // fprintf(fp, "\n"); fflush(fp); dump(0,fp); fflush(fp); // debug
+
+ chillindent(indent, fp);
+ //fprintf(fp, "vardecl->print vartype '%s'\n", vartype);
+ if (isDevice) fprintf(fp, "__device__ ");
+ if (isShared) fprintf(fp, "__shared__ ");
+
+ //if (isAStruct()) fprintf(fp, "/* isAStruct() */ ");
+ //else fprintf(fp, "/* NOT A Struct() */ ");
+ //if (vardef) fprintf(fp, "/* vardef */ ");
+ //else fprintf(fp, "/* NOT vardef */ ");
+
+
+ //fprintf(stderr, "chillAST_VarDecl::print() %s\n", varname );
+ //if (isParmVarDecl()) fprintf(stderr, "%s is a parameter\n", varname);
+ //if (isAStruct()) fprintf(stderr, "%s is a struct\n", varname);
+ //else fprintf(stderr, "%s is NOT a struct\n", varname);
+ //if (!parent) fprintf(stderr, "VARDECL HAS NO PARENT\n");
+ //else fprintf(stderr, "parent of %s is type %s\n", varname, parent->getTypeString());
+
+ // this logic is probably wrong (what about pointer to struct? )
+
+ //fprintf(stderr, "checking for unnamed only used here\n");
+
+ if ((!isAParameter) && isAStruct() && vardef) { // an unnamed struct used only here ??
+
+ //fprintf(fp, "i%s sAStruct() && vardef ?? vardecl of type UNNAMED ONLY USED HERE \n", varname );
+ // print the internals of the struct and then the name
+ vardef->printStructure( 0, fp );
+ fprintf(fp, "%s", varname );
+
+ return;
+ }
+
+ //fprintf(fp, "ugly logic\n");
+ // ugly logic TODO
+
+ if (typedefinition && typedefinition->isAStruct()) fprintf(fp, "struct ");
+
+ if (isAParameter) {
+ //fprintf(fp, "%s isaparameter\n", varname);
+ //if (isAStruct()) fprintf(fp, "struct ");
+ //fprintf(fp, "(param) nd %d", numdimensions );
+ //dump();
+ if (numdimensions > 0) {
+ if (knownArraySizes) { // just [12][34][56]
+ fprintf(fp, "%s ", vartype);
+ if (byreference) fprintf(fp, "&");
+ fprintf(fp, "%s", varname);
+ for (int n=0; n< (numdimensions); n++) fprintf(fp, "[%d]", arraysizes[n]);
+ }
+ else { // some unknown array part float *a; or float **a; or float (*)a[1234]
+
+ //fprintf(fp, "\nsome unknown\n");
+ //fprintf(fp, "arraypointerpart '%s'\n", arraypointerpart);
+ //fprintf(fp, "arraysetpart '%s'\n", arraysetpart);
+
+ if (numdimensions == 1) {
+ //fprintf(fp, "\nnd1, vartype %s\n", vartype);
+
+ // TODO this if means I have probably made a mistake somewhere
+ if (!index(vartype, '*')) fprintf(fp, "%s *%s", vartype, varname ); // float *x
+ else fprintf(fp, "%s%s", vartype, varname); // float *a;
+
+
+ }
+ else { // more than one dimension
+
+ if ( !strcmp("", arraysetpart) ) { // no known dimensions float ***a;
+ fprintf(fp, "%s %s%s", vartype, arraypointerpart, varname);
+ }
+ else if ( !strcmp("", arraypointerpart)) { // ALL known float a[2][7];
+ fprintf(fp, "%s %s", vartype, varname);
+ for (int n=0; n< numdimensions; n++) fprintf(fp, "[%d]", arraysizes[n]);
+ }
+ else { // float (*)a[1234]
+ // this seems really wrong
+ // float (*)a[1234]
+ fprintf(fp, "%s (", vartype);
+ for (int n=0; n< (numdimensions-1); n++) fprintf(fp, "*");
+ fprintf(fp, "%s)", varname);
+ fprintf(fp, "[%d]", arraysizes[numdimensions-1]);
+ }
+
+ }
+ }
+ } // if numdimensions > 0
+ else { // parameter float x
+ fprintf(fp, "%s ", vartype);
+ if (byreference) fprintf(fp, "&");
+ fprintf(fp, "%s", varname);
+ }
+ } // end parameter
+
+ else { // NOT A PARAMETER
+ //fprintf(fp, "NOT A PARAM ... vartype '%s'\n", vartype);
+ //if (isArray()) fprintf(stderr, "an array, numdimensions %d\n", numdimensions);
+ //fprintf(stderr, "arraysizes %p\n", arraysizes);
+
+
+
+ //if (isArray() && arraysizes == NULL) {
+ // // we just know the number of dimensions but no sizes
+ // // int ***something
+ // fprintf(fp, "%s ", vartype); // "int "
+ // for (int i=0; i<numdimensions; i++) fprintf(fp, "*"); // ***
+ // fprintf(fp, "%s", varname); // variable name
+ // }
+ // else
+
+ fprintf(fp, "%s %s", vartype, arraypointerpart);
+ if (isRestrict) fprintf(fp, " __restrict__ "); // wrong place
+ fprintf(fp, "%s%s", varname, arraysetpart );
+ if (init) {
+ fprintf(fp, " = "); fflush(fp);
+ init->print(0, fp);
+ }
+ }
+ fflush(fp);
+ //fprintf(stderr, "numdimensions %d arraysizes address 0x%x\n", numdimensions, arraysizes);
+ //if (!isAParameter) fprintf(fp, ";\n", vartype, varname, arraypart );
+};
+
+
+
+
+void chillAST_VarDecl::printName( int in, FILE *fp ) {
+ chillindent(in, fp);
+ fprintf(fp, "%s", varname);
+};
+
+
+
+
+void chillAST_VarDecl::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(VarDecl \"'%s' '%s' '%s'\" n_dim %d ) ", vartype, varname, arraypart, numdimensions);
+
+ //fprintf(fp, "vardef %p\n", vardef);
+ //if (vardef) fprintf(fp, "(typedef or struct!)\n");
+ //fprintf(fp, "typedefinition %p\n", typedefinition);
+ //if (isStruct) fprintf(fp, "isStruct\n");
+
+ //if (isAParameter) fprintf(fp, "PARAMETER\n");
+ //else fprintf(fp, "NOT PARAMETER\n");
+ fflush(fp);
+
+ //segfault(); // see what called this
+};
+
+
+chillAST_RecordDecl * chillAST_VarDecl::getStructDef() {
+ if (vardef) return vardef;
+ if (typedefinition) return typedefinition->getStructDef();
+ return NULL;
+}
+
+
+
+
+
+chillAST_CompoundStmt::chillAST_CompoundStmt() {
+ //fprintf(stderr, "chillAST_CompoundStmt::chillAST_CompoundStmt() %p\n", this);
+ asttype = CHILLAST_NODETYPE_COMPOUNDSTMT;
+ parent = NULL;
+ symbol_table = new chillAST_SymbolTable;
+ typedef_table = NULL;
+ isFromSourceFile = true; // default
+ filename = NULL;
+};
+
+
+void chillAST_CompoundStmt::print( int indent, FILE *fp ) {
+ printPreprocBEFORE(indent, fp);
+ int numchildren = children.size();
+ //fprintf(stderr, "NUMCHILDREN %d\n", numchildren); sleep(1);
+ for (int i=0; i<numchildren; i++) {
+ children[i]->print(indent, fp);
+ if (children[i]->asttype != CHILLAST_NODETYPE_FORSTMT
+ && children[i]->asttype != CHILLAST_NODETYPE_IFSTMT
+ && children[i]->asttype != CHILLAST_NODETYPE_COMPOUNDSTMT
+ //&& children[i]->asttype != CHILLAST_NODETYPE_VARDECL // vardecl does its own ";\n"
+ )
+ {
+ fprintf(fp, ";\n"); // probably wrong
+ }
+ }
+ fflush(fp);
+}
+
+void chillAST_CompoundStmt::replaceChild( chillAST_node *old, chillAST_node *newchild ){
+ //fprintf(stderr, "chillAST_CompoundStmt::replaceChild( old %s, new %s)\n", old->getTypeString(), newchild->getTypeString() );
+ vector<chillAST_node*> dupe = children;
+ int numdupe = dupe.size();
+ int any = 0;
+
+ for (int i=0; i<numdupe; i++) {
+
+ //fprintf(stderr, "\ni %d\n",i);
+ //for (int j=0; j<numdupe; j++) {
+ // fprintf(stderr, "this 0x%x children[%d/%d] = 0x%x type %s\n", this, j, children.size(), children[j], children[j]->getTypeString());
+ //}
+
+
+ if (dupe[i] == old) {
+ //fprintf(stderr, "replacing child %d of %d\n", i, numdupe);
+ //fprintf(stderr, "was \n"); print();
+ children[i] = newchild;
+ newchild->setParent( this );
+ //fprintf(stderr, "is \n"); print(); fprintf(stderr, "\n\n");
+ // old->parent = NULL;
+ any = 1;
+ }
+ }
+
+ if (!any) {
+ fprintf(stderr, "chillAST_CompoundStmt::replaceChild(), could not find old\n");
+ exit(-1);
+ }
+}
+
+
+void chillAST_CompoundStmt::loseLoopWithLoopVar( char *var ) {
+ //fprintf(stderr, "chillAST_CompoundStmt::loseLoopWithLoopVar( %s )\n", var);
+
+ //fprintf(stderr, "CompoundStmt 0x%x has parent 0x%x ", this, this->parent);
+ //fprintf(stderr, "%s\n", parent->getTypeString());
+
+
+ //fprintf(stderr, "CompoundStmt node has %d children\n", children.size());
+ //fprintf(stderr, "before doing a damned thing, \n");
+ //print();
+ //dump(); fflush(stdout);
+ //fprintf(stderr, "\n\n");
+
+#ifdef DAMNED
+ for (int j=0; j<children.size(); j++) {
+ fprintf(stderr, "j %d/%d ", j, children.size());
+ fprintf(stderr, "subnode %d 0x%x ", j, children[j] );
+ fprintf(stderr, "asttype %d ", children[j]->asttype);
+ fprintf(stderr, "%s ", children[j]->getTypeString());
+ if (children[j]->isForStmt()) {
+ chillAST_ForStmt *FS = ((chillAST_ForStmt *) children[j]);
+ fprintf(stderr, "for (");
+ FS->init->print(0, stderr);
+ fprintf(stderr, "; ");
+ FS->cond->print(0, stderr);
+ fprintf(stderr, "; ");
+ FS->incr->print(0, stderr);
+ fprintf(stderr, ") with %d statements in body 0x%x\n", FS->body->getNumChildren(), FS->body );
+ }
+ else fprintf(stderr, "\n");
+ }
+#endif
+
+
+ vector<chillAST_node*> dupe = children; // simple enough?
+ for (int i=0; i<dupe.size(); i++) {
+ //for (int j=0; j<dupe.size(); j++) {
+ // fprintf(stderr, "j %d/%d\n", j, dupe.size());
+ // fprintf(stderr, "subnode %d %s ", j, children[j]->getTypeString());
+ // if (children[j]->isForStmt()) {
+ // chillAST_ForStmt *FS = ((chillAST_ForStmt *) children[j]);
+ // fprintf(stderr, "for (");
+ // FS->init->print(0, stderr);
+ // fprintf(stderr, "; ");
+ // FS->cond->print(0, stderr);
+ // fprintf(stderr, "; ");
+ // FS->incr->print(0, stderr);
+ // fprintf(stderr, ") with %d statements in body 0x%x\n", FS->body->getNumChildren(), FS->body );
+ //}
+ //else fprintf(stderr, "\n");
+ //}
+
+ //fprintf(stderr, "CompoundStmt 0x%x recursing to child %d/%d\n", this, i, dupe.size());
+ dupe[i]->loseLoopWithLoopVar( var );
+ }
+ //fprintf(stderr, "CompoundStmt node 0x%x done recursing\n", this );
+}
+
+
+
+void chillAST_CompoundStmt::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(CompoundStmt \n" );
+ int numchildren = children.size();
+
+ //for (int i=0; i<numchildren; i++) {
+ // fprintf(fp, "%d %s 0x%x\n", i, children[i]->getTypeString(), children[i]);
+ //}
+ //fprintf(fp, "\n");
+
+ for (int i=0; i<numchildren; i++) {
+ children[i]->dump(indent+1, fp);
+ fprintf(fp, "\n"); // ???
+ fflush(fp);
+ }
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+};
+
+
+
+chillAST_node* chillAST_CompoundStmt::constantFold(){
+ //fprintf(stderr, "chillAST_CompoundStmt::constantFold()\n");
+ for (int i=0; i<children.size(); i++) children[i] = children[i]->constantFold();
+ return this;
+}
+
+
+chillAST_node* chillAST_CompoundStmt::clone(){
+ chillAST_CompoundStmt *cs = new chillAST_CompoundStmt();
+ for (int i=0; i<children.size(); i++) cs->addChild( children[i]->clone() );
+ cs->setParent( parent );
+ cs->isFromSourceFile = isFromSourceFile;
+ if (filename) cs->filename = strdup(filename);
+ return cs;
+}
+
+
+void chillAST_CompoundStmt::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ //fprintf(stderr, "chillAST_CompoundStmt::gatherVarDecls()\n");
+ for (int i=0; i<children.size(); i++) children[i]->gatherVarDecls( decls );
+}
+
+
+void chillAST_CompoundStmt::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_CompoundStmt::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_CompoundStmt::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_CompoundStmt::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherVarUsage( decls );
+}
+
+
+void chillAST_CompoundStmt::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherArrayRefs( refs, 0);
+}
+
+void chillAST_CompoundStmt::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ for (int i=0; i<children.size(); i++) children[i]->gatherScalarRefs( refs, 0);
+}
+
+void chillAST_CompoundStmt::gatherStatements(std::vector<chillAST_node*> &statements ){
+ for (int i=0; i<children.size(); i++) children[i]->gatherStatements( statements );
+}
+
+
+
+void chillAST_CompoundStmt::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ for (int i=0; i<children.size(); i++) children[i]->replaceVarDecls( olddecl, newdecl );
+}
+
+
+bool chillAST_CompoundStmt::findLoopIndexesToReplace( chillAST_SymbolTable *symtab, bool forcesync ) {
+
+ // see how many elements we currently have
+ int sofar = children.size();
+
+ // make big enough to add a sync after each statement. wasteful. TODO
+ // this prevents inserts happening at the forstmt::addSync() from causing a
+ // reallocation, which screwsup the loop below here
+ children.reserve( 2 * sofar );
+ //fprintf(stderr, "sofar %d reserved %d\n", sofar, 2*sofar);
+
+ bool force = false;
+ for (int i=0; i<children.size(); i++) { // children.size() to see it gain each time
+ if (children.size() > sofar ) {
+ //fprintf(stderr, "HEY! CompoundStmt::findLoopIndexesToReplace() noticed that children increased from %d to %d\n", sofar, children.size());
+ sofar = children.size();
+ }
+
+ //fprintf(stderr, "compound child %d of type %s force %d\n", i, children[i]->getTypeString(), force );
+ bool thisforces = children[i]->findLoopIndexesToReplace( symtab, force );
+ force = force || thisforces; // once set, always
+ }
+
+ return false;
+
+/*
+ vector<chillAST_node*> childrencopy;
+ for (int i=0; i<children.size(); i++) childrencopy.push_back( children[i] );
+ bool force = false;
+
+ char *origtypes[64];
+ int origsize = children.size();
+ for (int i=0; i<children.size(); i++) {
+ fprintf(stderr, "ORIGINAL compound child %d of type %s\n", i, children[i]->getTypeString() );
+ origtypes[i] = strdup( children[i]->getTypeString() );
+ fprintf(stderr, "ORIGINAL compound child %d of type %s\n", i, children[i]->getTypeString() );
+ }
+
+ for (int i=0; i<childrencopy.size(); i++) {
+ fprintf(stderr, "compound child %d of type %s force %d\n", i, childrencopy[i]->getTypeString(), force );
+ force = force || childrencopy[i]->findLoopIndexesToReplace( symtab, force ); // once set, always
+ }
+
+ fprintf(stderr, "\n");
+ for (int i=0; i<origsize; i++) {
+ fprintf(stderr, "BEFORE compound child %d/%d of type %s\n", i, origsize, origtypes[i]);
+ }
+ for (int i=0; i<children.size(); i++) {
+ fprintf(stderr, "AFTER compound child %d/%d of type %s\n", i, children.size(), children[i]->getTypeString() );
+ }
+
+ return false;
+*/
+}
+
+
+
+
+
+chillAST_ParenExpr::chillAST_ParenExpr( chillAST_node *sub, chillAST_node *par ){
+ subexpr = sub;
+ subexpr->setParent( this );
+ asttype = CHILLAST_NODETYPE_PARENEXPR;
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_ParenExpr::print( int indent, FILE *fp ) {
+ //fprintf(stderr, "chillAST_ParenExpr::print()\n");
+ chillindent(indent, fp); // hard to believe this will ever do anything
+ fprintf(fp, "(" );
+ subexpr->print( 0, fp );
+ fprintf(fp, ")" );
+ fflush(fp);
+}
+
+void chillAST_ParenExpr::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(ParenExpr \n");
+ subexpr->dump( indent+1, fp );
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+}
+
+
+void chillAST_ParenExpr::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ subexpr->gatherArrayRefs( refs, writtento );
+}
+
+void chillAST_ParenExpr::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ subexpr->gatherScalarRefs( refs, writtento );
+}
+
+
+
+chillAST_node* chillAST_ParenExpr::constantFold() {
+ subexpr = subexpr->constantFold();
+ return this;
+}
+
+
+chillAST_node* chillAST_ParenExpr::clone() {
+ chillAST_ParenExpr *PE = new chillAST_ParenExpr( subexpr->clone(), NULL );
+ PE->isFromSourceFile = isFromSourceFile;
+ if (filename) PE->filename = strdup(filename);
+ return PE;
+}
+
+void chillAST_ParenExpr::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarDecls( decls );
+}
+
+
+void chillAST_ParenExpr::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_ParenExpr::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_ParenExpr::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ subexpr->gatherDeclRefExprs( refs );
+}
+
+void chillAST_ParenExpr::replaceVarDecls( chillAST_VarDecl *olddecl, chillAST_VarDecl *newdecl){
+ subexpr->replaceVarDecls( olddecl, newdecl );
+}
+
+void chillAST_ParenExpr::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ subexpr->gatherVarUsage( decls );
+}
+
+
+
+chillAST_Sizeof::chillAST_Sizeof( char *athing, chillAST_node *par ){
+ thing = strdup( athing ); // memory leak
+ parent = par;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_Sizeof::print( int indent, FILE *fp ) {
+ //fprintf(stderr, "chillAST_Sizeof::print()\n");
+ chillindent(indent, fp); // hard to believe this will ever do anything
+ fprintf(fp, "sizeof(" );
+ fprintf(fp, "%s)", thing );
+ fflush(fp);
+}
+
+
+void chillAST_Sizeof::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(Sizeof %s )\n", thing);
+}
+
+void chillAST_Sizeof::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {}
+void chillAST_Sizeof::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {}
+
+chillAST_node* chillAST_Sizeof::constantFold() {
+ return this;
+}
+
+chillAST_node* chillAST_Sizeof::clone() {
+ chillAST_Sizeof *SO = new chillAST_Sizeof( thing, NULL );
+ SO->isFromSourceFile = isFromSourceFile;
+ if (filename) SO->filename = strdup(filename);
+ return SO;
+}
+
+void chillAST_Sizeof::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) { // TODO
+}
+
+
+void chillAST_Sizeof::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) { // TODO
+}
+
+
+void chillAST_Sizeof::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) { // TODO
+}
+
+
+void chillAST_Sizeof::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ // TODO
+}
+
+
+void chillAST_Sizeof::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+}
+
+
+void insertNewDeclAtLocationOfOldIfNeeded( chillAST_VarDecl *newdecl, chillAST_VarDecl *olddecl) {
+ //fprintf(stderr, "insertNewDeclAtLocationOfOldIfNeeded( new 0x%x old 0x%x\n", newdecl, olddecl );
+
+ if (newdecl == NULL || olddecl == NULL) {
+ fprintf(stderr, "chill_ast.cc insertNewDeclAtLocationOfOldIfNeeded() NULL decl\n");
+ exit(-1);
+ }
+
+ if (newdecl == olddecl) return;
+
+ newdecl->vartype = strdup(olddecl->vartype);
+
+ chillAST_node *newparent = newdecl->parent;
+ chillAST_node *oldparent = olddecl->parent;
+ //fprintf(stderr, "newparent 0x%x oldparent 0x%x\n", newparent, oldparent );
+ if (newparent == oldparent) return;
+
+ if (newparent != NULL)
+ //fprintf(stderr, "chill_ast.cc insertNewDeclAtLocationOfOldIfNeeded() new decl already has parent?? probably wrong\n");
+ newdecl->parent = oldparent; // will be true soon
+
+ // find actual location of old decl and insert new one there
+ //fprintf(stderr, "oldparent is of type %s\n", oldparent->getTypeString()); // better be compoundstmt ??
+ vector<chillAST_node*> children = oldparent->getChildren();
+
+ int numchildren = children.size();
+ //fprintf(stderr, "oldparent has %d children\n", numchildren);
+
+ if (numchildren == 0) {
+ fprintf(stderr, "chill_ast.cc insertNewDeclAtLocationOfOldIfNeeded() impossible number of oldparent children (%d)\n", numchildren);
+ exit(-1);
+ }
+
+ bool newalreadythere = false;
+ int index = -1;
+ //fprintf(stderr, "olddecl is 0x%x\n", olddecl);
+ //fprintf(stderr, "I know of %d variables\n", numchildren);
+ for (int i=0; i<numchildren; i++) {
+ chillAST_node *child = oldparent->getChild(i);
+ //fprintf(stderr, "child %d @ 0x%x is of type %s\n", i, child, child->getTypeString());
+ if (children[i] == olddecl) {
+ index = i;
+ //fprintf(stderr, "found old decl at index %d\n", index);
+ }
+ if (children[i] == newdecl) {
+ newalreadythere = true;
+ //fprintf(stderr, "new already there @ index %d\n", i);
+ }
+ }
+ if (index == -1) {
+ fprintf(stderr, "chill_ast.cc insertNewDeclAtLocationOfOldIfNeeded() can't find old decl for %s\n", olddecl->varname);
+ exit(-1);
+ }
+
+ if (!newalreadythere) oldparent->insertChild( index, newdecl );
+
+}
+
+
+void gatherVarDecls( vector<chillAST_node*> &code, vector<chillAST_VarDecl*> &decls) {
+ //fprintf(stderr, "gatherVarDecls()\n");
+
+ int numcode = code.size();
+ //fprintf(stderr, "%d top level statements\n", numcode);
+ for (int i=0; i<numcode; i++) {
+ chillAST_node *statement = code[i];
+ statement->gatherVarDecls( decls );
+ }
+
+}
+
+
+void gatherVarUsage( vector<chillAST_node*> &code, vector<chillAST_VarDecl*> &decls) {
+ //fprintf(stderr, "gatherVarUsage()\n");
+
+ int numcode = code.size();
+ //fprintf(stderr, "%d top level statements\n", numcode);
+ for (int i=0; i<numcode; i++) {
+ chillAST_node *statement = code[i];
+ statement->gatherVarUsage( decls );
+ }
+
+}
+
+
+
+
+chillAST_IfStmt::chillAST_IfStmt() {
+ cond = thenpart = elsepart = NULL;
+ asttype = CHILLAST_NODETYPE_IFSTMT;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+chillAST_IfStmt::chillAST_IfStmt(chillAST_node *c, chillAST_node *t, chillAST_node *e, chillAST_node *p){
+ cond = c;
+ if (cond) cond->setParent( this );
+ thenpart = t;
+ if (thenpart) thenpart->setParent( this );
+ elsepart = e;
+ if (elsepart) elsepart->setParent( this );
+ parent = p;
+ asttype = CHILLAST_NODETYPE_IFSTMT;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}
+
+void chillAST_IfStmt::gatherVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ if (cond) cond->gatherVarDecls( decls );
+ if (thenpart) thenpart->gatherVarDecls( decls );
+ if (elsepart) elsepart->gatherVarDecls( decls );
+}
+
+
+void chillAST_IfStmt::gatherScalarVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ if (cond) cond->gatherScalarVarDecls( decls );
+ if (thenpart) thenpart->gatherScalarVarDecls( decls );
+ if (elsepart) elsepart->gatherScalarVarDecls( decls );
+}
+
+
+void chillAST_IfStmt::gatherArrayVarDecls( vector<chillAST_VarDecl*> &decls ) {
+ if (cond) cond->gatherArrayVarDecls( decls );
+ if (thenpart) thenpart->gatherArrayVarDecls( decls );
+ if (elsepart) elsepart->gatherArrayVarDecls( decls );
+}
+
+
+void chillAST_IfStmt::gatherDeclRefExprs( vector<chillAST_DeclRefExpr *>&refs ) {
+ if (cond) cond->gatherDeclRefExprs( refs );
+ if (thenpart) thenpart->gatherDeclRefExprs( refs );
+ if (elsepart) elsepart->gatherDeclRefExprs( refs );
+}
+
+
+void chillAST_IfStmt::gatherVarUsage( vector<chillAST_VarDecl*> &decls ) {
+ if (cond) cond->gatherVarUsage( decls );
+ if (thenpart) thenpart->gatherVarUsage( decls );
+ if (elsepart) elsepart->gatherVarUsage( decls );
+}
+
+
+void chillAST_IfStmt::gatherArrayRefs( std::vector<chillAST_ArraySubscriptExpr*> &refs, bool writtento ) {
+ cond->gatherArrayRefs( refs, 0 ); // 0 ??
+ thenpart->gatherArrayRefs( refs, 0 ); // 0 ??
+ if (elsepart) elsepart->gatherArrayRefs( refs, 0 ); // 0 ??
+}
+
+void chillAST_IfStmt::gatherScalarRefs( std::vector<chillAST_DeclRefExpr*> &refs, bool writtento ) {
+ cond->gatherScalarRefs( refs, 0 ); // 0 ??
+ thenpart->gatherScalarRefs( refs, 0 ); // 0 ??
+ if (elsepart) elsepart->gatherScalarRefs( refs, 0 ); // 0 ??
+}
+
+
+chillAST_node *chillAST_IfStmt::constantFold() {
+ if (cond) cond = cond->constantFold();
+ if (thenpart) thenpart = thenpart->constantFold();
+ if (elsepart) elsepart = elsepart->constantFold();
+ return this;
+}
+
+void chillAST_IfStmt::gatherStatements(std::vector<chillAST_node*> &statements ){
+
+ //print(); printf("\n"); fflush(stdout);
+ thenpart->gatherStatements( statements );
+ //fprintf(stderr, "ifstmt, after then, %d statements\n", statements.size());
+ if (elsepart){
+ //fprintf(stderr, "there is an elsepart of type %s\n", elsepart->getTypeString());
+ elsepart->gatherStatements( statements );
+ }
+ //fprintf(stderr, "ifstmt, after else, %d statements\n", statements.size());
+}
+
+
+
+chillAST_node *chillAST_IfStmt::clone() {
+ chillAST_node *c, *t, *e;
+ c = t = e = NULL;
+ if (cond) c = cond->clone(); // has to be one, right?
+ if (thenpart) t = thenpart->clone();
+ if (elsepart) e = elsepart->clone();
+
+ chillAST_IfStmt *IS = new chillAST_IfStmt( c, t, e, parent);
+ IS->isFromSourceFile = isFromSourceFile;
+ if (filename) IS->filename = strdup(filename);
+ return IS;
+}
+
+
+
+void chillAST_IfStmt::dump( int indent, FILE *fp ) {
+ chillindent(indent, fp);
+ fprintf(fp, "(if ");
+ fprintf(fp, "\n");
+
+ cond->dump(indent+1, fp);
+ fprintf(fp, "\n");
+
+ thenpart->dump(indent+1, fp);
+ fprintf(fp, "\n");
+
+ if (elsepart) {
+ elsepart->dump(indent+1, fp);
+ fprintf(fp, "\n");
+ }
+ chillindent(indent, fp);
+ fprintf(fp, ")\n");
+}
+
+
+
+void chillAST_IfStmt::print(int indent, FILE *fp ) {
+ printPreprocBEFORE(indent, fp);
+ chillindent(indent, fp);
+ fprintf(fp, "if (");
+ if (cond) cond->print(0, fp);
+ else fprintf(fp, "(NULL cond)");
+
+ bool needbracket = true;
+ if (thenpart) {
+ if (thenpart->isBinaryOperator()) needbracket = false;
+ if (thenpart->isCompoundStmt()) { // almost always true
+ chillAST_CompoundStmt *CS = (chillAST_CompoundStmt*) thenpart;
+ if (CS->children.size() == 1 && CS->children[0]->isBinaryOperator()) needbracket = false;
+ }
+
+ if(needbracket) fprintf(fp, ") {\n");
+ else fprintf(fp, ")\n");
+
+ thenpart->print(indent+1, fp); // end of line
+
+ if(needbracket) {
+ //fprintf(fp, "\n");
+ chillindent(indent, fp);
+ fprintf(fp, "}\n");
+ }
+ }
+ else fprintf(fp, "(NULL thenpart)");
+
+
+ needbracket = true;
+ if (elsepart) {
+ if (elsepart->isBinaryOperator()) needbracket = false;
+ if (elsepart->isCompoundStmt()) { // almost always true
+ chillAST_CompoundStmt *CS = (chillAST_CompoundStmt*) elsepart;
+
+ if (CS->children.size() == 1 && CS->children[0]->isBinaryOperator()) needbracket = false;
+
+ }
+
+ fprintf(fp, "\n");
+ chillindent(indent, fp);
+
+ if (needbracket) fprintf(fp, "else {\n");
+ else fprintf(fp, "else\n");
+
+ elsepart->print(indent+1, fp);
+
+ if(needbracket) {
+ fprintf(fp, "\n");
+ chillindent(indent, fp);
+ fprintf(fp, "}\n");
+ }
+ }
+ //else fprintf(fp, "else { /* NOTHING */ }");
+}
+
+
+
+bool chillAST_IfStmt::findLoopIndexesToReplace( chillAST_SymbolTable *symtab, bool forcesync ) {
+ thenpart->findLoopIndexesToReplace( symtab );
+ elsepart->findLoopIndexesToReplace( symtab );
+ return false; // ??
+}
+
+
+
+chillAST_node *lessthanmacro( chillAST_node *left, chillAST_node *right) {
+
+ chillAST_ParenExpr *lp1 = new chillAST_ParenExpr( left );
+ chillAST_ParenExpr *rp1 = new chillAST_ParenExpr( right );
+ chillAST_BinaryOperator *cond = new chillAST_BinaryOperator( lp1, "<", rp1 );
+
+ chillAST_ParenExpr *lp2 = new chillAST_ParenExpr( left );
+ chillAST_ParenExpr *rp2 = new chillAST_ParenExpr( right );
+
+ chillAST_TernaryOperator *t = new chillAST_TernaryOperator("?", cond, lp2, rp2);
+
+ return t;
+}
+
+
+
+
+// look for function declaration with a given name, in the tree with root "node"
+void findFunctionDeclRecursive( chillAST_node *node, const char *procname, vector<chillAST_FunctionDecl*>& funcs )
+{
+ //fprintf(stderr, "findmanually() CHILL AST node of type %s\n", node->getTypeString());
+
+ if (node->isFunctionDecl()) {
+ char *name = ((chillAST_FunctionDecl *) node)->functionName; // compare name with desired name
+ //fprintf(stderr, "node name 0x%x ", name);
+ //fprintf(stderr, "%s procname ", name);
+ //fprintf(stderr, "0x%x ", procname);
+ //fprintf(stderr, "%s\n", procname);
+ if (!strcmp( name, procname)) {
+ //fprintf(stderr, "found procedure %s\n", procname );
+ funcs.push_back( (chillAST_FunctionDecl*) node ); // this is it
+ // quit recursing. probably not correct in some horrible case
+ return;
+ }
+ //else fprintf(stderr, "this is not the function we're looking for\n");
+ }
+
+
+ // this is where the children can be used effectively.
+ // we don't really care what kind of node we're at. We just check the node itself
+ // and then its children is needed.
+
+ int numc = node->children.size();
+ fprintf(stderr, "(top)node has %d children\n", numc);
+
+ for (int i=0; i<numc; i++) {
+ if (node->isSourceFile()) {
+ fprintf(stderr, "node of type %s is recursing to child %d of type %s\n", node->getTypeString(), i, node->children[i]->getTypeString());
+ if (node->children[i]->isFunctionDecl()) {
+ chillAST_FunctionDecl *fd = (chillAST_FunctionDecl*) node->children[i];
+ fprintf(stderr, "child %d is functiondecl %s\n", i, fd->functionName);
+ }
+ }
+ findFunctionDeclRecursive( node->children[i], procname, funcs );
+
+ }
+ return;
+}
+
+
+chillAST_FunctionDecl *findFunctionDecl( chillAST_node *node, const char *procname)
+{
+ vector<chillAST_FunctionDecl*> functions;
+ findFunctionDeclRecursive( node, procname, functions );
+
+ if ( functions.size() == 0 ) {
+ fprintf(stderr, "could not find function named '%s'\n", procname);
+ exit(-1);
+ }
+
+ if ( functions.size() > 1 ) {
+ fprintf(stderr, "oddly, found %d functions named '%s'\n", functions.size(), procname);
+ fprintf(stderr, "I am unsure what to do\n");
+
+ for (int f = 0; f < functions.size(); f++) {
+ fprintf(stderr, "function %d %p %s\n", f, functions[f], functions[f]->functionName);
+ }
+ exit(-1);
+ }
+
+ //fprintf(stderr, "found the procedure named %s\n", procname);
+ return functions[0];
+}
+
+
+chillAST_SymbolTable *addSymbolToTable( chillAST_SymbolTable *st, chillAST_VarDecl *vd ) // definition
+{
+ chillAST_SymbolTable *s = st;
+ if (!s) s = new chillAST_SymbolTable;
+
+ int tablesize = s->size();
+
+ for (int i=0; i<tablesize; i++) {
+ if ((*s)[i] == vd) {
+ //fprintf(stderr, "the exact same symbol, not just the same name, was already there\n");
+ return s; // already there
+ }
+ }
+
+ for (int i=0; i<tablesize; i++) {
+ //fprintf(stderr, "name %s vs name %s\n", (*s)[i]->varname, vd->varname);
+ if (!strcmp( (*s)[i]->varname, vd->varname)) {
+ //fprintf(stderr, "symbol with the same name was already there\n");
+ return s; // already there
+ }
+ }
+
+ //fprintf(stderr, "adding %s %s to a symbol table that didn't already have it\n", vd->vartype, vd->varname);
+
+ //printf("before:\n");
+ //printSymbolTable( s ); fflush(stdout);
+
+ s->push_back(vd); // add it
+
+ //printf("after:\n");
+ //printSymbolTable( s ); fflush(stdout);
+ return s;
+}
+
+
+chillAST_TypedefTable *addTypedefToTable( chillAST_TypedefTable *tdt, chillAST_TypedefDecl *td )
+{
+
+ chillAST_TypedefTable *t = tdt;
+ if (!t) t = new chillAST_TypedefTable;
+
+ int tablesize = t->size();
+
+ for (int i=0; i<tablesize; i++) {
+ if ((*t)[i] == td) return t; // already there
+ }
+ t->push_back(td); // add it
+ return t;
+}
+
+
+chillAST_NoOp::chillAST_NoOp( chillAST_node *p ) {
+ parent = p;
+ isFromSourceFile = true; // default
+ filename = NULL;
+}; // so we have SOMETHING for NoOp in the cc file ???
+
+
+chillAST_Preprocessing::chillAST_Preprocessing() {
+ position = CHILL_PREPROCESSING_POSITIONUNKNOWN;
+ pptype = CHILL_PREPROCESSING_TYPEUNKNOWN;
+ blurb = strdup(""); // never use null. ignore the leak ??
+}
+
+
+ chillAST_Preprocessing::chillAST_Preprocessing(CHILL_PREPROCESSING_POSITION pos,
+ CHILL_PREPROCESSING_TYPE t,
+ char *text )
+ {
+ position = pos;
+ pptype = t;
+ blurb = strdup( text );
+ }
+
+void chillAST_Preprocessing::print( int indent, FILE *fp ) { // probably very wrong
+ if (position == CHILL_PREPROCESSING_LINEAFTER ) {
+ fprintf(fp, "\n");
+ chillindent(indent, fp);
+ }
+ if (position == CHILL_PREPROCESSING_LINEBEFORE) { // ???
+ //fprintf(fp, "\n");
+ chillindent(indent, fp);
+ }
+
+ fprintf(fp, "%s", blurb);
+
+ if (position == CHILL_PREPROCESSING_TOTHERIGHT) {
+ fprintf(fp, "\n");
+ }
+
+
+ if (position == CHILL_PREPROCESSING_LINEBEFORE) {
+ //fprintf(fp, "\n"); // comment seems to have \n at the end already
+ //chillindent(indent, fp);
+ }
+
+
+ //if (pptype != CHILL_PREPROCESSING_IMMEDIATELYBEFORE && pptype != CHILL_PREPROCESSING_UNKNOWN) fprint(fp, "\n");
+
+ }
diff --git a/src/chillmodule.cc b/src/chillmodule.cc
index b347570..291cb51 100644
--- a/src/chillmodule.cc
+++ b/src/chillmodule.cc
@@ -10,7 +10,6 @@
#include <omega.h>
#include "loop.hh"
#include "ir_code.hh"
-#include "ir_rose.hh"
#include "chillmodule.hh"
@@ -81,11 +80,6 @@ static void init_loop(int loop_num_start, int loop_num_end) {
}
else {
if (ir_code == NULL) {
- if (procedure_name.empty())
- procedure_name = "main";
-
- ir_code = new IR_roseCode(source_filename.c_str(), procedure_name.c_str());
-
IR_Block *block = ir_code->GetCode();
ir_controls = ir_code->FindOneLevelControlStructure(block);
for (int i = 0; i < ir_controls.size(); i++) {
diff --git a/src/dep.cc b/src/dep.cc
index 39f2d17..e47d7aa 100644
--- a/src/dep.cc
+++ b/src/dep.cc
@@ -37,15 +37,22 @@ std::ostream& operator<<(std::ostream &os, const DependenceVector &d) {
switch (d.type) {
case DEP_W2R:
- os << "true";
+ os << "flow";
+ // Check for reduction implemetation correctness
if (d.is_reduction)
os << "_reduction";
break;
case DEP_R2W:
os << "anti";
+ // TODO: Remove Check for reduction implemetation correctness
+ if (d.is_reduction)
+ os << "_reduction";
break;
case DEP_W2W:
os << "output";
+ // TODO: Remove Check for reduction implemetation correctness
+ if (d.is_reduction)
+ os << "_reduction";
break;
case DEP_R2R:
os << "input";
@@ -94,6 +101,13 @@ std::ostream& operator<<(std::ostream &os, const DependenceVector &d) {
return os;
}
+// DependenceVector::DependenceVector(int size):
+// lbounds(std::vector<coef_t>(size, 0)),
+// ubounds(std::vector<coef_t>(size, 0)) {
+// src = NULL;
+// dst = NULL;
+// }
+
DependenceVector::DependenceVector(const DependenceVector &that) {
if (that.sym != NULL)
this->sym = that.sym->clone();
@@ -105,6 +119,7 @@ DependenceVector::DependenceVector(const DependenceVector &that) {
quasi = that.quasi;
is_scalar_dependence = that.is_scalar_dependence;
is_reduction = that.is_reduction;
+ is_reduction_cand = that.is_reduction_cand; // Manu
}
DependenceVector &DependenceVector::operator=(const DependenceVector &that) {
@@ -120,6 +135,7 @@ DependenceVector &DependenceVector::operator=(const DependenceVector &that) {
quasi = that.quasi;
is_scalar_dependence = that.is_scalar_dependence;
is_reduction = that.is_reduction;
+ is_reduction_cand = that.is_reduction_cand;
}
return *this;
}
@@ -128,12 +144,18 @@ DependenceType DependenceVector::getType() const {
}
bool DependenceVector::is_data_dependence() const {
- return (type == DEP_W2R || type == DEP_R2W || type == DEP_W2W
- || type == DEP_R2R);
+ if (type == DEP_W2R || type == DEP_R2W || type == DEP_W2W
+ || type == DEP_R2R)
+ return true;
+ else
+ return false;
}
bool DependenceVector::is_control_dependence() const {
- return type == DEP_CONTROL;
+ if (type == DEP_CONTROL)
+ return true;
+ else
+ return false;
}
bool DependenceVector::has_negative_been_carried_at(int dim) const {
@@ -147,7 +169,10 @@ bool DependenceVector::has_negative_been_carried_at(int dim) const {
if (lbounds[i] > 0 || ubounds[i] < 0)
return false;
- return lbounds[dim] < 0;
+ if (lbounds[dim] < 0)
+ return true;
+ else
+ return false;
}
@@ -162,7 +187,10 @@ bool DependenceVector::has_been_carried_at(int dim) const {
if (lbounds[i] > 0 || ubounds[i] < 0)
return false;
- return (lbounds[dim] != 0) || (ubounds[dim] !=0);
+ if ((lbounds[dim] != 0) || (ubounds[dim] !=0))
+ return true;
+
+ return false;
}
bool DependenceVector::has_been_carried_before(int dim) const {
@@ -243,14 +271,22 @@ bool DependenceVector::hasPositive(int dim) const {
if (dim >= lbounds.size())
throw std::invalid_argument("invalid dependence dimension");
- return lbounds[dim] > 0;
+ if (lbounds[dim] > 0)
+ //av: changed from ubounds to lbounds may have side effects
+ return true;
+ else
+ return false;
}
bool DependenceVector::hasNegative(int dim) const {
if (dim >= lbounds.size())
throw std::invalid_argument("invalid dependence dimension");
- return ubounds[dim] < 0;
+ if (ubounds[dim] < 0)
+ //av: changed from lbounds to ubounds may have side effects
+ return true;
+ else
+ return false;
}
bool DependenceVector::isCarried(int dim, omega::coef_t distance) const {
@@ -269,13 +305,18 @@ bool DependenceVector::isCarried(int dim, omega::coef_t distance) const {
if (dim >= lbounds.size())
return true;
- return lbounds[dim] >= -distance && ubounds[dim] <= distance;
+ if (lbounds[dim] > distance)
+ return false;
+ else if (ubounds[dim] < -distance)
+ return false;
+
+ return true;
}
bool DependenceVector::canPermute(const std::vector<int> &pi) const {
if (pi.size() != lbounds.size())
throw std::invalid_argument(
- "permute dimensionality do not match dependence space");
+ "permute dimensionality do not match dependence space");
for (int i = 0; i < pi.size(); i++) {
if (lbounds[pi[i]] > 0)
@@ -316,10 +357,10 @@ std::vector<DependenceVector> DependenceVector::normalize() const {
}
std::vector<DependenceVector> DependenceVector::permute(
- const std::vector<int> &pi) const {
+ const std::vector<int> &pi) const {
if (pi.size() != lbounds.size())
throw std::invalid_argument(
- "permute dimensionality do not match dependence space");
+ "permute dimensionality do not match dependence space");
const int n = lbounds.size();
@@ -370,6 +411,60 @@ DependenceVector DependenceVector::reverse() const {
return dv;
}
+// std::vector<DependenceVector> DependenceVector::matrix(const std::vector<std::vector<int> > &M) const {
+// if (M.size() != lbounds.size())
+// throw std::invalid_argument("(non)unimodular transformation dimensionality does not match dependence space");
+
+// const int n = lbounds.size();
+// DependenceVector dv;
+// if (sym != NULL)
+// dv.sym = sym->clone();
+// else
+// dv.sym = NULL;
+// dv.type = type;
+
+// for (int i = 0; i < n; i++) {
+// assert(M[i].size() == n+1 || M[i].size() == n);
+
+// omega::coef_t lb, ub;
+// if (M[i].size() == n+1)
+// lb = ub = M[i][n];
+// else
+// lb = ub = 0;
+
+// for (int j = 0; j < n; j++) {
+// int c = M[i][j];
+// if (c == 0)
+// continue;
+
+// if (c > 0) {
+// if (lbounds[j] == -posInfinity)
+// lb = -posInfinity;
+// else if (lb != -posInfinity)
+// lb += c * lbounds[j];
+// if (ubounds[j] == posInfinity)
+// ub = posInfinity;
+// else if (ub != posInfinity)
+// ub += c * ubounds[j];
+// }
+// else {
+// if (ubounds[j] == posInfinity)
+// lb = -posInfinity;
+// else if (lb != -posInfinity)
+// lb += c * ubounds[j];
+// if (lbounds[j] == -posInfinity)
+// ub = posInfinity;
+// else if (ub != posInfinity)
+// ub += c * lbounds[j];
+// }
+// }
+// dv.lbounds.push_back(lb);
+// dv.ubounds.push_back(ub);
+// }
+// dv.is_reduction = is_reduction;
+
+// return dv.normalize();
+// }
//-----------------------------------------------------------------------------
// Class: DependenceGraph
@@ -411,6 +506,20 @@ DependenceGraph DependenceGraph::permute(const std::vector<int> &pi,
return g;
}
+// DependenceGraph DependenceGraph::matrix(const std::vector<std::vector<int> > &M) const {
+// DependenceGraph g;
+
+// for (int i = 0; i < vertex.size(); i++)
+// g.insert(vertex[i].first);
+
+// for (int i = 0; i < vertex.size(); i++)
+// for (EdgeList::const_iterator j = vertex[i].second.begin(); j != vertex[i].second.end(); j++)
+// for (int k = 0; k < j->second.size(); k++)
+// g.connect(i, j->first, j->second[k].matrix(M));
+
+// return g;
+// }
+
DependenceGraph DependenceGraph::subspace(int dim) const {
DependenceGraph g;
diff --git a/src/ir_clang.cc b/src/ir_clang.cc
new file mode 100755
index 0000000..ba11ac5
--- /dev/null
+++ b/src/ir_clang.cc
@@ -0,0 +1,3239 @@
+
+
+/*****************************************************************************
+ Copyright (C) 2009-2010 University of Utah
+ All Rights Reserved.
+
+Purpose:
+CHiLL's CLANG interface.
+convert from CLANG AST to chill AST
+
+Notes:
+Array supports mixed pointer and array type in a single declaration.
+
+History:
+12/10/2010 LLVM/CLANG Interface created by Saurav Muralidharan.
+ *****************************************************************************/
+
+#include <typeinfo>
+#include <sstream>
+#include "ir_clang.hh"
+#include "loop.hh"
+#include "chill_error.hh"
+
+#define DUMPFUNC(x, y) std::cerr << "In function " << x << "\n"; y->dump();
+
+#include "clang/Frontend/FrontendActions.h"
+#include <clang/CodeGen/CodeGenAction.h>
+#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Frontend/CompilerInvocation.h>
+#include <clang/Basic/DiagnosticOptions.h>
+#include <clang/Frontend/TextDiagnosticPrinter.h>
+#include <clang/AST/ASTContext.h>
+#include <clang/AST/RecordLayout.h>
+#include <clang/AST/Decl.h>
+#include <clang/Parse/ParseAST.h>
+#include <clang/Basic/TargetInfo.h>
+
+#include <llvm/ADT/IntrusiveRefCntPtr.h>
+#include <llvm/Support/Host.h>
+
+#include "code_gen/CG_chillRepr.h"
+#include "code_gen/CG_chillBuilder.h"
+#include <vector>
+
+#include "chill_ast.hh"
+
+// TODO move to ir_clang.hh
+// fwd declarations
+chillAST_node * ConvertVarDecl( clang::VarDecl *D, chillAST_node * );
+chillAST_node * ConvertTypeDefDecl( clang::TypedefDecl *TDD, chillAST_node * );
+chillAST_node * ConvertRecordDecl( clang::RecordDecl *D, chillAST_node * );
+chillAST_node * ConvertDeclStmt( clang::DeclStmt *clangDS, chillAST_node * );
+chillAST_node * ConvertCompoundStmt( clang::CompoundStmt *clangCS, chillAST_node * );
+chillAST_node * ConvertFunctionDecl( clang::FunctionDecl *D , chillAST_node *);
+chillAST_node * ConvertForStmt( clang::ForStmt *clangFS, chillAST_node * );
+chillAST_node * ConvertUnaryOperator( clang::UnaryOperator * clangU, chillAST_node *O );
+chillAST_node * ConvertBinaryOperator( clang::BinaryOperator * clangBO, chillAST_node *B );
+chillAST_node * ConvertArraySubscriptExpr( clang::ArraySubscriptExpr *clangASE, chillAST_node * );
+chillAST_node * ConvertDeclRefExpr( clang::DeclRefExpr * clangDRE, chillAST_node * );
+chillAST_node * ConvertIntegerLiteral( clang::IntegerLiteral *clangIL, chillAST_node * );
+chillAST_node * ConvertFloatingLiteral( clang::FloatingLiteral *clangFL, chillAST_node * );
+chillAST_node * ConvertImplicitCastExpr( clang::ImplicitCastExpr *clangICE, chillAST_node * );
+chillAST_node * ConvertCStyleCastExpr( clang::CStyleCastExpr *clangICE, chillAST_node * );
+chillAST_node * ConvertReturnStmt( clang::ReturnStmt *clangRS, chillAST_node * );
+chillAST_node * ConvertCallExpr( clang::CallExpr *clangCE , chillAST_node *);
+chillAST_node * ConvertIfStmt( clang::IfStmt *clangIS , chillAST_node *);
+chillAST_node * ConvertMemberExpr( clang::MemberExpr *clangME , chillAST_node *);
+
+
+chillAST_node * ConvertTranslationUnit( clang::TranslationUnitDecl *TUD, char *filename );
+chillAST_node * ConvertGenericClangAST( clang::Stmt *s, chillAST_node * );
+
+
+std::vector<chillAST_VarDecl *> VariableDeclarations;
+std::vector<chillAST_FunctionDecl *> FunctionDeclarations;
+
+using namespace clang;
+using namespace clang::driver;
+using namespace omega;
+using namespace std;
+
+
+static string binops[] = {
+ " ", " ", // BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators.
+ "*", "/", "%", // BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators.
+ "+", "-", // BO_Add, BO_Sub, // [C99 6.5.6] Additive operators.
+ "<<", ">>", // BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators.
+ "<", ">", "<=", ">=", // BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators.
+ "==", "!=", // BO_EQ, BO_NE, // [C99 6.5.9] Equality operators.
+ "&", // BO_And, // [C99 6.5.10] Bitwise AND operator.
+ "??", // BO_Xor, // [C99 6.5.11] Bitwise XOR operator.
+ "|", // BO_Or, // [C99 6.5.12] Bitwise OR operator.
+ "&&", // BO_LAnd, // [C99 6.5.13] Logical AND operator.
+ "||", // BO_LOr, // [C99 6.5.14] Logical OR operator.
+ "=", "*=", // BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators.
+ "/=", "%=", // BO_DivAssign, BO_RemAssign,
+ "+=", "-=", // BO_AddAssign, BO_SubAssign,
+ "???", "???", // BO_ShlAssign, BO_ShrAssign,
+ "&&=", "???", // BO_AndAssign, BO_XorAssign,
+ "||=", // BO_OrAssign,
+ ","}; // BO_Comma // [C99 6.5.17] Comma operator.
+
+
+static string unops[] = {
+ "++", "--", // [C99 6.5.2.4] Postfix increment and decrement
+ "++", "--", // [C99 6.5.3.1] Prefix increment and decrement
+ "@", "*", // [C99 6.5.3.2] Address and indirection
+ "+", "-", // [C99 6.5.3.3] Unary arithmetic
+ "~", "!", // [C99 6.5.3.3] Unary arithmetic
+ "__real", "__imag", // "__real expr"/"__imag expr" Extension.
+ "__extension" // __extension__ marker.
+};
+
+// forward defs
+SourceManager * globalSRCMAN; // ugly. shame.
+
+char *splitTypeInfo( char *underlyingtype );
+void printsourceline( const char *filename, int line );
+void printlines( SourceLocation &S, SourceLocation &E, SourceManager *SRCMAN );
+
+void PrintBinaryOperator( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintDeclStmt( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintALoop( Stmt *L, SourceManager *SRCMAN, int level );
+void PrintAUnaryOperator( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintAnIfStmt( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintCompoundStmt( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintDeclRefExpr( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintImplicitCastExpr( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintReturnStmt( Stmt *s, SourceManager *SRCMAN, int level );
+void PrintStmt( Stmt *s, SourceManager *SRCMAN, int level );
+
+void PrintAnIntegerLiteral( Stmt *I );
+void PrintAFloatingLiteral( Stmt *s );
+
+void PrintFunctionDecl( FunctionDecl *D, SourceManager *SRCMAN, int level );
+void PrintTypeDefDecl( TypedefDecl *D, SourceManager *SRCMAN, int level );
+void PrintVarDecl( VarDecl *D, SourceManager *SRCMAN, int level );
+
+
+
+
+
+void printlines( SourceLocation &S, SourceLocation &E, SourceManager *SRCMAN ) {
+ unsigned int startlineno = SRCMAN->getPresumedLineNumber( S );
+ unsigned int endlineno = SRCMAN->getPresumedLineNumber( E );
+ const char *filename = SRCMAN->getBufferName( S );
+ fprintf(stderr, "\n");
+ for (int l=startlineno; l<= endlineno; l++) printsourceline( filename, l);
+}
+
+
+void Indent( int level ) {
+ for (int i=0; i<level; i++) fprintf(stderr, " ");
+}
+
+
+// really slow and bad. but I'm debugging
+void printsourceline( const char *filename, int line )
+{
+ FILE *fp = fopen (filename, "r");
+
+ // Now read lines up to and including the line we want.
+ char buf[10240];
+ int l = 0;
+ while (l < line) {
+ if (fgets (buf, sizeof(buf), fp))
+ ++l;
+ else
+ break;
+ }
+ fclose(fp);
+
+ fprintf(stderr, "* %s", buf);
+}
+
+
+
+void PrintBinaryOperator( Stmt *s, SourceManager *SRCMAN, int level ) { // SOMETIMES SHOULD HAVE ; + return
+ //rintf(stderr, "\nBinaryOperator(%d) ", level);
+ BinaryOperator *b = cast<BinaryOperator>(s);
+
+ BinaryOperator::Opcode op = b->getOpcode();
+ Expr *lhs = b->getLHS();
+ Expr *rhs = b->getRHS();
+
+ //fprintf(stderr, "binaryoperator lhs has type %s\n", lhs->getStmtClassName());
+ //fprintf(stderr, "binaryoperator rhs has type %s\n\n", rhs->getStmtClassName());
+
+ PrintStmt( lhs, SRCMAN, level+1 );
+ fprintf(stderr, " %s ", binops[op].c_str());
+ PrintStmt( rhs, SRCMAN, level+1);
+ if (level == 1) fprintf(stderr, ";\n");
+}
+
+
+
+void PrintDeclStmt( Stmt *s, SourceManager *SRCMAN, int level ) {
+ fprintf(stderr, "\nDeclaration Statement(%d)", level);
+ DeclStmt *D = cast<DeclStmt>(s);
+
+ //QualType QT = D->getType();
+ //string TypeStr = QT.getAsString();
+ //fprintf(stderr, "type %s\n", TypeStr,c_str());
+
+ //SourceLocation S = D->getStartLoc();
+ //SourceLocation E = D->getEndLoc();
+ //printlines(S, E, SRCMAN);
+
+ if (D->isSingleDecl()) {
+ fprintf(stderr, "this is a single definition\n");
+ Decl *d = D->getSingleDecl();
+ }
+ else {
+ fprintf(stderr, "this is NOT a single definition\n");
+ DeclGroupRef dg = D->getDeclGroup();
+ }
+
+ for (DeclStmt::decl_iterator DI = D->decl_begin(), DE = D->decl_end(); DI != DE; ++DI) {
+ //fprintf(stderr, "a def\n");
+ Decl *d = *DI;
+ //fprintf(stderr, "\nstatement of type %s\n", d->getStmtClassName());
+ //std::cout << (void *) d << "?";
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(d)) {
+ if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
+ if (V->getStorageClass() != SC_None) {
+ fprintf(stderr, "%s ", VarDecl::getStorageClassSpecifierString(V->getStorageClass()));
+ }
+ // else fprintf(stderr, "no storage class? ");
+
+ QualType T = V->getType();
+ string TypeStr = T.getAsString();
+ std::string Name = VD->getNameAsString();
+ //VD->getType().getAsStringInternal(Name,
+ // PrintingPolicy(VD->getASTContext().getLangOpts()));
+ fprintf(stderr,"%s %s ", TypeStr.c_str(), Name.c_str());
+ // If this is a vardecl with an initializer, emit it.
+ if (Expr *E = V->getInit()) {
+ fprintf(stderr, " = ");
+
+ Stmt *s = dyn_cast<Stmt>(E);
+ PrintStmt(s, SRCMAN, level+1);
+ //fprintf(stderr, ";\n");
+
+ }
+
+ }
+
+ }
+ if (level <= 1) fprintf(stderr, ";\n"); // TODO wrong
+
+ } // for each actual declaration
+}
+
+
+
+
+
+
+void PrintAFloatingLiteral( Stmt *s ) {
+ FloatingLiteral *F = dyn_cast<FloatingLiteral>(s);
+ fprintf(stderr, "%f", F->getValueAsApproximateDouble()); // TODO approximate?
+}
+
+
+
+
+void PrintALoop( Stmt *L, SourceManager *SRCMAN, int level ) {
+ //fprintf(stderr, "\nA LOOP L=0x%x SRCMAN 0x%x", L, &SRCMAN);
+ ForStmt *ForStatement = cast<ForStmt>(L);
+
+ SourceLocation srcloc = ForStatement->getForLoc();
+ unsigned int lineno = SRCMAN->getPresumedLineNumber( srcloc );
+ const char *filename = SRCMAN->getBufferName( srcloc );
+ //fprintf(stderr, " in file %s at line %d ", filename, lineno);
+ //printsourceline( filename, lineno);
+
+ Stmt *init = ForStatement->getInit();
+ Expr *cond = ForStatement->getCond();
+ Expr *incr = ForStatement->getInc();
+ Stmt *body = ForStatement->getBody();
+
+ fprintf(stderr, "for (");
+ PrintStmt(init, SRCMAN, 0);
+ fprintf(stderr, "; ");
+ PrintStmt(cond, SRCMAN, 0);
+ fprintf(stderr, "; ");
+ PrintStmt(incr, SRCMAN, 0);
+ fprintf(stderr, " )\n");
+ Indent(level);
+ fprintf(stderr, "{\n");
+ PrintStmt(body, SRCMAN, level+1);
+ fprintf(stderr, "}\n\n");
+
+}
+
+
+void PrintAUnaryOperator( Stmt *s, SourceManager *SRCMAN, int level ) {
+ //fprintf(stderr, "UnaryOperator ");
+ UnaryOperator *u = cast<UnaryOperator>(s);
+
+ const char *op = unops[u->getOpcode()].c_str();
+
+ if (u->isPrefix()) {
+ fprintf(stderr, "%s", op );
+ }
+
+ PrintStmt( u->getSubExpr(), SRCMAN, level+1 );
+
+ if (u->isPostfix()) {
+ fprintf(stderr, "%s", op );
+ }
+}
+
+
+
+void PrintAnIfStmt( Stmt *s, SourceManager *SRCMAN, int level ) {
+ //fprintf(stderr, "an IF statement\n");
+ // SourceLocation S = s->getLocStart();
+ // SourceLocation E = s->getLocEnd();
+ // printlines( S, E, SRCMAN);
+
+ IfStmt *IfStatement = cast<IfStmt>(s);
+
+ Stmt *Cond = IfStatement->getCond();
+ Stmt *Then = IfStatement->getThen();
+ Stmt *Else = IfStatement->getElse();
+
+ fprintf(stderr, "if (");
+ PrintStmt(Cond, SRCMAN, level+1);
+ fprintf(stderr, ") {\n");
+ PrintStmt(Then, SRCMAN, level+1);
+ fprintf(stderr, "\n}\nelse\n{\n");
+ PrintStmt(Else, SRCMAN, level+1);
+ fprintf(stderr, "\n}\n\n");
+}
+
+
+
+void PrintAnIntegerLiteral( Stmt *s ) {
+ IntegerLiteral *I = dyn_cast<IntegerLiteral>(s);
+ bool isSigned = I->getType()->isSignedIntegerType();
+ fprintf(stderr, "%s", I->getValue().toString(10, isSigned).c_str());
+}
+
+
+
+void PrintArraySubscriptExpr( Stmt *s, SourceManager *SRCMAN, int level ) {
+ ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(s);
+
+ Expr *Base = ASE->getBase();
+ Expr *Index = ASE->getIdx();
+
+ PrintStmt(Base, SRCMAN, level+1);
+ fprintf(stderr, "[");
+ PrintStmt(Index, SRCMAN, level+1);
+ fprintf(stderr, "]");
+}
+
+
+void PrintCompoundStmt( Stmt *s, SourceManager *SRCMAN, int level ) {
+ //fprintf(stderr, "\nCompoundStmt(%d)", level);
+ CompoundStmt *cs = dyn_cast<CompoundStmt>(s);
+ int numchildren=cs->size();
+ //fprintf(stderr, "CompoundStmt has %d children\n", numchildren);
+
+
+#ifdef DEBUGGING
+BUH
+ for (Stmt::child_range I = cs->children(); I; ++I) {
+ const char *classname = I->getStmtClassName();
+ if (!strcmp(classname, "BinaryOperator")) {
+ BinaryOperator *b = cast<BinaryOperator>(*I);
+ BinaryOperator::Opcode op = b->getOpcode();
+ if (op == BO_Assign) {
+ fprintf(stderr, "compound statement has child of type ASSIGNMENT STATEMENT ");
+ SourceLocation S = I->getLocStart();
+ SourceLocation E = I->getLocEnd();
+ unsigned int startlineno = SRCMAN->getPresumedLineNumber( S );
+ unsigned int endlineno = SRCMAN->getPresumedLineNumber( E );
+ fprintf(stderr, "(%d-%d)\n", startlineno, endlineno );
+ }
+ else
+ fprintf(stderr, "compound statement has child of type %s\n", I->getStmtClassName());
+ }
+ else
+ fprintf(stderr, "compound statement has child of type %s\n", I->getStmtClassName());
+ }
+#endif // debugging
+
+
+
+ for (auto I = cs->child_begin(); I!=cs->child_end(); ++I) {
+ Stmt *child = *I;
+ PrintStmt( child, SRCMAN, level ); // NOTE not level + 1
+
+ fprintf(stderr, "\n"); // ***\n\n");
+ }
+
+}
+
+
+
+
+void PrintDeclRefExpr( Stmt *s, SourceManager *SRCMAN, int level ) {
+ DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(s);
+
+ //if (NestedNameSpecifier *Qualifier = DRE->getQualifier())
+ // Qualifier->print( raw_ostream nonstandard of course );
+ DeclarationNameInfo DNI = DRE->getNameInfo();
+ DeclarationName DN = DNI.getName();
+ fprintf(stderr, "%s", DN.getAsString().c_str());
+
+}
+
+
+
+void PrintFunctionDecl( FunctionDecl *D, SourceManager *SRCMAN, int level ) {
+ //rintf(stderr, "\nFunctionDecl(%d) %s\n", level, D->getNameInfo().getAsString().c_str());
+ // Type name as string
+ QualType QT = D->getReturnType();
+ string TypeStr = QT.getAsString();
+
+ // Function name
+ DeclarationName DeclName = D->getNameInfo().getName();
+ string FuncName = DeclName.getAsString();
+ //fprintf(stderr, "function %s has type %s ", FuncName.c_str(), TypeStr.c_str());
+
+
+ fprintf(stderr, "\n%s %s(",TypeStr.c_str(), FuncName.c_str());
+
+ int numparams = D->getNumParams();
+ //fprintf(stderr, "and %d parameters\n", numparams);
+ for (int i=0; i<numparams; i++) {
+ if (i) fprintf(stderr, ", ");
+ ParmVarDecl *clangVardecl = D->getParamDecl(i);
+
+ // from DeclPrinter::VisitVarDecl(VarDecl *D)
+ StorageClass SCAsWritten = clangVardecl->getStorageClass();
+ if (SCAsWritten != SC_None) {
+ fprintf(stderr, "%s ", VarDecl::getStorageClassSpecifierString(SCAsWritten));
+ }
+ //else fprintf(stderr, "(no storage class?) ");
+
+ QualType T = clangVardecl->getType();
+ if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(clangVardecl))
+ T = Parm->getOriginalType();
+
+ string Name = clangVardecl->getName();
+ char *td = strdup(T.getAsString().c_str());
+ fprintf(stderr, "td = '%s'\n", td);
+ char *arraypart = splitTypeInfo(td);
+ fprintf(stderr, "%s %s%s ", td, Name.c_str(), arraypart);
+
+ }
+
+ fprintf(stderr, ")\n{\n"); // beginning of function body
+
+ Stmt *body = D->getBody();
+ PrintStmt( body, SRCMAN, level+1);
+ fprintf(stderr, "}\n\n"); // end of function body
+}
+
+
+void PrintImplicitCastExpr( Stmt *s, SourceManager *SRCMAN, int level ) {
+ ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(s);
+ PrintStmt( ICE->getSubExpr(), SRCMAN, level+1);
+}
+
+
+
+void PrintReturnStmt( Stmt *s, SourceManager *SRCMAN, int level ) {
+ ReturnStmt *r = dyn_cast<ReturnStmt>(s);
+
+ fprintf(stderr, "return");
+ if (r->getRetValue()) {
+ fprintf(stderr, " ");
+ PrintStmt( r->getRetValue(), SRCMAN, level+1);
+ }
+ fprintf(stderr, ";\n");
+}
+
+
+void PrintStmt( Stmt *s, SourceManager *SRCMAN, int level ) {
+ //fprintf(stderr, "\nprint statement 0x%x of type %s\n", s, s->getStmtClassName());
+
+
+ //fprintf(stderr, "*");
+ //SourceLocation srcloc = s->getStartLoc();
+ //unsigned int lineno = SRCMAN->getPresumedLineNumber( srcloc );
+ //const char *filename = SRCMAN->getBufferName( srcloc );
+
+ //StmtClass getStmtClass()
+ if (isa<DeclStmt>(s)) { PrintDeclStmt(s, SRCMAN, level);
+ } else if (isa<FloatingLiteral>(s)) { PrintAFloatingLiteral(s );
+ } else if (isa<IntegerLiteral>(s)) { PrintAnIntegerLiteral(s );
+ } else if (isa<UnaryOperator>(s)) { PrintAUnaryOperator(s, SRCMAN, level);
+ } else if (isa<BinaryOperator>(s)) { PrintBinaryOperator(s, SRCMAN, level);
+ } else if (isa<ForStmt>(s)) { PrintALoop(s, SRCMAN, level);
+ } else if (isa<IfStmt>(s)) { PrintAnIfStmt(s, SRCMAN, level);
+ } else if (isa<CompoundStmt>(s)) { PrintCompoundStmt(s, SRCMAN, level);
+ } else if (isa<ImplicitCastExpr>(s)) { PrintImplicitCastExpr(s, SRCMAN, level);
+ } else if (isa<DeclRefExpr>(s)) { PrintDeclRefExpr(s, SRCMAN, level);
+ } else if (isa<ArraySubscriptExpr>(s)) {PrintArraySubscriptExpr(s, SRCMAN, level);
+ } else if (isa<ReturnStmt>(s)) { PrintReturnStmt(s, SRCMAN, level);
+ } else {
+ fprintf(stderr, "\nPrintStmt() UNHANDLED statement of type %s\n", s->getStmtClassName());
+ exit(-1);
+ }
+ //int numchildren=0;
+ //for (Stmt::child_range I = s->children(); I; ++I, numchildren++) ;
+ //if (numchildren) fprintf(stderr, "has %d children\n", numchildren);
+ //if (numchildren) {
+ // for (Stmt::child_range I = s->children(); I; ++I
+ //}
+}
+
+
+void PrintTranslationUnit( TranslationUnitDecl *TUD, ASTContext &CTX ) {
+ // TUD derived from Decl and DeclContext
+ static DeclContext *DC = TUD->castToDeclContext( TUD );
+ //SourceManager SM = CTX.getSourceManager();
+
+ for (DeclContext::decl_iterator DI = DC->decls_begin(), DE = DC->decls_end(); DI != DE; ++DI) {
+ Decl *D = *DI;
+
+ if (isa<FunctionDecl>(D)) { //fprintf(stderr, "FunctionDecl\n");
+ PrintFunctionDecl( dyn_cast<FunctionDecl>(D), &CTX.getSourceManager(), 0);
+ }
+ else if (isa<VarDecl>(D)) { //fprintf(stderr, "VarDecl\n");
+ PrintVarDecl( dyn_cast<VarDecl>(D), &CTX.getSourceManager(), 0 );
+ }
+ else if (isa<TypedefDecl>(D)) { //fprintf(stderr, "TypedefDecl\n");
+ PrintTypeDefDecl( dyn_cast<TypedefDecl>(D), &CTX.getSourceManager(), 0 );
+ }
+ else if (isa<TypeAliasDecl>(D)) { fprintf(stderr, "TypeAliasDecl\n");
+ }
+ else {
+ fprintf(stderr, "\na declaration of type %s (%d) which I have no idea how to handle\n", D->getDeclKindName(), D->getKind());
+ exit(-1);
+ }
+
+ //else if (isa<TypedefNameDecl>(D)) { fprintf(stderr, "TypedefNameDecl\n");}
+ }
+}
+
+
+void PrintTypeDefDecl( TypedefDecl *D, SourceManager *SRCMAN, int level ) {
+
+ /* internal typedefs do not have a source file and this will die!
+ SourceLocation S = D->getLocStart(); // NOT getStartLoc(), that's class DeclStmt
+ SourceLocation E = D->getLocEnd();
+ unsigned int startlineno = SRCMAN->getPresumedLineNumber( S );
+ unsigned int endlineno = SRCMAN->getPresumedLineNumber( E );
+ const char *filename = SRCMAN-> etBufferName( S );
+ fprintf(stderr, " in file %s at lines %d-%d", filename, startlineno, endlineno);
+ for (int l=startlineno; l<= endlineno; l++) printsourceline( filename, l);
+ */
+
+ // arrays suck
+ char *td = strdup( D->getUnderlyingType().getAsString().c_str());
+ //fprintf(stderr, "td = '%s'\n", td);
+ char *arraypart = splitTypeInfo(td);
+ fprintf(stderr, "typedef %s %s%s;\n", td, D->getName().str().c_str(), arraypart);
+
+ free(td);
+ free(arraypart);
+}
+
+
+
+void PrintVarDecl( VarDecl *D, SourceManager *SRCMAN, int level ) {
+ // arrays suck
+ char *td = strdup( D->getType().getAsString().c_str()); // leak
+ //fprintf(stderr, "td = '%s'\n", td);
+ char *arraypart = splitTypeInfo(td);
+ fprintf(stderr, "%s %s%s", td, D->getName().str().c_str(), arraypart);
+
+ Expr *Init = D->getInit();
+ if (Init) {
+ //fprintf(stderr," = (TODO)");
+ PrintStmt( Init, SRCMAN, level+1);
+ }
+ fprintf(stderr, ";\n");
+
+ free(td);
+ free(arraypart);
+} //PrintVarDecl
+
+
+
+
+
+
+
+
+chillAST_node * ConvertVarDecl( VarDecl *D, chillAST_node *p ) {
+ //fprintf(stderr, "\nConvertVarDecl()\n");
+ //fprintf(stderr, "Decl has type %s\n", D->getDeclKindName());
+ //PrintVarDecl( D, globalSRCMAN, 0 );
+
+ bool isParm = false;
+
+ QualType T0 = D->getType();
+ QualType T = T0;
+ if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) { // My GOD clang stinks
+ T = Parm->getOriginalType();
+ isParm = true;
+ }
+
+ // arrays suck
+ char *vartype = strdup( T.getAsString().c_str());
+ //fprintf(stderr, "vartype = '%s' T0 '%s\n", vartype, T0.getAsString().c_str() );
+ char *arraypart = splitTypeInfo(vartype);
+ //fprintf(stderr, "arraypart = '%s'\n", arraypart);
+
+
+ char *varname = strdup(D->getName().str().c_str());
+ //fprintf(stderr, "VarDecl (clang 0x%x) for %s %s%s\n", D, vartype, varname, arraypart);
+
+ chillAST_VarDecl * chillVD = new chillAST_VarDecl( vartype, varname, arraypart, (void *)D, p /* , initializer */ );
+
+ chillVD->isAParameter = isParm;
+ //fprintf(stderr, "\nthis is the vardecl\n");
+ //chillVD->print(); printf("\n\n"); fflush(stdout);
+
+ //clang::QualType qtyp = D->getType();
+ //clang::Expr *e = D->getInit();
+ //fprintf(stderr, "e 0x%x\n", e);
+
+ //if (qtyp->isPointerType()) {
+ // fprintf(stderr, "pointer type\n");
+ // clang::QualType ptyp = qtyp->getPointeeType();
+ // fprintf(stderr, "%s\n", ptyp.getAsString().c_str());
+ //}
+
+ //if (qtyp->isArrayType()) fprintf(stderr, "Array type\n");
+ //if (qtyp->isConstantArrayType()) fprintf(stderr, "constant array type\n");
+
+ //const clang::Type *typ = qtyp.getTypePtr();
+ //clang::Expr *e = ((clang::VariableArrayType *)typ)->getSizeExpr();
+ //e->dump();
+
+
+ int numdim = 0;
+ chillVD-> knownArraySizes = true;
+ if (index(vartype, '*')) chillVD->knownArraySizes = false; // float *a; for example
+ if (index(arraypart, '*')) chillVD->knownArraySizes = false;
+
+ // note: vartype here, arraypart in next code.. is that right?
+ if (index(vartype, '*')) {
+ for (int i = 0; i<strlen(vartype); i++) if (vartype[i] == '*') numdim++;
+ //fprintf(stderr, "numd %d\n", numd);
+ chillVD->numdimensions = numdim;
+ }
+
+ if (index(arraypart, '[')) { // JUST [12][34][56] no asterisks
+ char *dupe = strdup(arraypart);
+
+ int len = strlen(arraypart);
+ for (int i=0; i<len; i++) if (dupe[i] == '[') numdim++;
+
+ //fprintf(stderr, "numdim %d\n", numdim);
+
+ chillVD->numdimensions = numdim;
+ int *as = (int *)malloc(sizeof(int *) * numdim );
+ if (!as) {
+ fprintf(stderr, "can't malloc array sizes in ConvertVarDecl()\n");
+ exit(-1);
+ }
+ chillVD->arraysizes = as; // 'as' changed later!
+
+
+ char *ptr = dupe;
+ //fprintf(stderr, "dupe '%s'\n", ptr);
+ while (ptr = index(ptr, '[')) {
+ ptr++;
+ //fprintf(stderr, "tmp '%s'\n", ptr);
+ int dim;
+ sscanf(ptr, "%d", &dim);
+ //fprintf(stderr, "dim %d\n", dim);
+ *as++ = dim;
+
+ ptr = index(ptr, ']');
+ //fprintf(stderr, "bottom of loop, ptr = '%s'\n", ptr);
+ }
+ free(dupe);
+ //for (int i=0; i<numdim; i++) {
+ // fprintf(stderr, "dimension %d = %d\n", i, chillVD->arraysizes[i]);
+ //}
+
+ //fprintf(stderr, "need to handle [] array to determine num dimensions\n");
+ //exit(-1);
+ }
+
+ Expr *Init = D->getInit();
+ if (Init) {
+ fprintf(stderr," = VARDECL HAS INIT. (TODO) (RIGHT NOW)"); exit(-1);
+ }
+ //fprintf(stderr, ";\n");
+
+
+ //fprintf(stderr, "calling chillVD->print()\n");
+ //chillVD->print(); // debugging only
+
+ free (vartype);
+ free (varname);
+
+ // store this away for declrefexpr that references it!
+ VariableDeclarations.push_back(chillVD);
+ return chillVD;
+}
+
+
+
+chillAST_node * ConvertRecordDecl( clang::RecordDecl *RD, chillAST_node *p ) { // for structs and unions
+
+ //fprintf(stderr, "ConvertRecordDecl( )\n\nclang sees\n");
+ //RD->dump();
+ //fflush(stdout);
+ //fprintf(stderr, "\n");
+
+ //fprintf(stderr, "%s with name %s\n", ((clang::Decl *)RD)->getDeclKindName(), RD->getNameAsString().c_str());
+ //const clang::ASTRecordLayout RL = RD->getASTContext().getASTRecordLayout( RD );
+ //RD->getASTContext().DumpRecordLayout( RD , cout );
+
+ int count = 0;
+ for (clang::RecordDecl::field_iterator fi = RD->field_begin(); fi != RD->field_end(); fi++) count++;
+ //fprintf(stderr, "%d fields in this struct/union\n", count);
+
+ char blurb[128];
+ sprintf(blurb, "struct %s", RD->getNameAsString().c_str());
+ fprintf(stderr, "blurb is '%s'\n", blurb);
+
+ chillAST_TypedefDecl *astruct = new chillAST_TypedefDecl( blurb, "", p);
+ astruct->setStruct( true );
+ astruct->setStructName( RD->getNameAsString().c_str() );
+
+ for (clang::RecordDecl::field_iterator fi = RD->field_begin(); fi != RD->field_end(); fi++) {
+ clang::FieldDecl *FD = (*fi);
+ FD->dump(); printf(";\n"); fflush(stdout);
+ string TypeStr = FD->getType().getAsString();
+
+ const char *typ = TypeStr.c_str();
+ const char *name = FD->getNameAsString().c_str();
+ fprintf(stderr, "(typ) %s (name) %s\n", typ, name);
+
+ chillAST_VarDecl *VD = NULL;
+ // very clunky and incomplete
+ VD = new chillAST_VarDecl( typ, name, "", astruct ); // can't handle arrays yet
+
+ astruct->subparts.push_back(VD);
+ }
+
+
+ fprintf(stderr, "I just defined a struct\n");
+ astruct->print(0, stderr);
+
+ return astruct;
+}
+
+
+
+
+
+
+
+chillAST_node * ConvertTypeDefDecl( TypedefDecl *TDD, chillAST_node *p ) {
+ //fprintf(stderr, "ConvertTypedefDecl( ) \n");
+ //fprintf(stderr, "TDD has type %s\n", TDD->getDeclKindName());
+ //TDD->dump(); fprintf(stderr, "\n");
+
+ char *under = strdup( TDD->getUnderlyingType().getAsString().c_str());
+ //fprintf(stderr, "under = '%s'\n", under);
+ char *arraypart = splitTypeInfo(under);
+ //fprintf(stderr, "typedef %s %s%s;\n", under, TDD->getName().str().c_str(), arraypart);
+ // fprintf(stderr, "len arraypart = %d\n", strlen(arraypart));
+ char *alias = strdup(TDD->getName().str().c_str());
+
+ //fprintf(stderr, "underlying type %s arraypart '%s' name %s\n", under, arraypart, TDD->getName().str().c_str() );
+ chillAST_TypedefDecl *CTDD = new chillAST_TypedefDecl( under, alias, arraypart, p );
+
+ free(under);
+ free(arraypart);
+
+ return CTDD;
+}
+
+
+
+chillAST_node * ConvertDeclStmt( DeclStmt *clangDS, chillAST_node *p ) {
+ //fprintf(stderr, "ConvertDeclStmt()\n");
+
+ chillAST_VarDecl *chillvardecl; // the thing we'll return if this is a single declaration
+
+ bool multiples = !clangDS->isSingleDecl();
+ if ( multiples) {
+ //fprintf(stderr, "ir_clang.cc multiple declarations in a single CLANG DeclStmt not really handled! (??)\n");
+ // for now, try to make the multiple decls into a compoundstmt with them inside.
+ // if we don't get scoping problems, this might work
+ }
+
+ DeclGroupRef dgr = clangDS->getDeclGroup();
+ clang::DeclGroupRef::iterator DI = dgr.begin();
+ clang::DeclGroupRef::iterator DE = dgr.end();
+
+ for ( ; DI != DE; ++DI) {
+ Decl *D = *DI;
+ const char *declty = D->getDeclKindName();
+ //fprintf(stderr, "a decl of type %s\n", D->getDeclKindName());
+
+ if (!strcmp("Var", declty)) {
+ VarDecl *V = dyn_cast<VarDecl>(D);
+ // ValueDecl *VD = dyn_cast<ValueDecl>(D); // not needed?
+ std::string Name = V->getNameAsString();
+ char *varname = strdup( Name.c_str());
+
+ //fprintf(stderr, "variable named %s\n", Name.c_str());
+ QualType T = V->getType();
+ string TypeStr = T.getAsString();
+ char *vartype = strdup( TypeStr.c_str());
+
+ //fprintf(stderr, "%s %s\n", td, varname);
+ char *arraypart = splitTypeInfo( vartype );
+
+ chillvardecl = new chillAST_VarDecl(vartype, varname, arraypart, (void *)D, p );
+ //fprintf(stderr, "DeclStmt (clang 0x%x) for %s %s%s\n", D, vartype, varname, arraypart);
+
+ // store this away for declrefexpr that references it!
+ VariableDeclarations.push_back(chillvardecl);
+
+ if (multiples) p->addChild( chillvardecl );
+
+ // TODO
+ if (V->hasInit()) {
+ fprintf(stderr, " ConvertDeclStmt() UNHANDLED initialization\n");
+ exit(-1);
+ }
+ }
+ } // for each of possibly multiple decls
+
+ if (multiples) return NULL; // multiple decls added themselves already
+ return chillvardecl; // OR a single decl
+}
+
+
+
+chillAST_node * ConvertCompoundStmt( CompoundStmt *clangCS, chillAST_node *p ) {
+ //fprintf(stderr, "ConvertCompoundStmt( )\n");
+ int numchildren= clangCS->size();
+ //fprintf(stderr, "clang CompoundStmt has %d children\n", numchildren);
+
+ // make an empty CHILL compound statement
+ chillAST_CompoundStmt *chillCS = new chillAST_CompoundStmt;
+ chillCS->setParent( p );
+
+ // for each clang child
+ for (auto I = clangCS->child_begin(); I!=clangCS->child_end(); ++I) { // ?? loop looks WRONG
+ // create the chill ast for each child
+ Stmt *child = *I;
+ chillAST_node *n = ConvertGenericClangAST( child, chillCS );
+ // usually n will be a statement. We just add it as a child.
+ // SOME DeclStmts have multiple declarations. They will add themselves and return NULL
+ if (n) chillCS->addChild( n );
+ }
+
+ return chillCS;
+}
+
+
+
+
+chillAST_node * ConvertFunctionDecl( FunctionDecl *D, chillAST_node *p ) {
+ //fprintf(stderr, "\nConvertFunctionDecl( )\n");
+ QualType QT = D->getReturnType();
+ string ReturnTypeStr = QT.getAsString();
+
+ // Function name
+ DeclarationName DeclName = D->getNameInfo().getName();
+ string FuncName = DeclName.getAsString();
+ //fprintf(stderr, "function %s has type %s ", FuncName.c_str(), ReturnTypeStr.c_str());
+ //fprintf(stderr, "\n%s %s()\n", ReturnTypeStr.c_str(), FuncName.c_str());
+
+ chillAST_FunctionDecl *chillFD = new chillAST_FunctionDecl( ReturnTypeStr.c_str(), FuncName.c_str(), p, D);
+
+
+ int numparams = D->getNumParams();
+
+ //fprintf(stderr, "\nand %d parameters\n", numparams);
+ for (int i=0; i<numparams; i++) {
+ if (i) fprintf(stderr, ", ");
+ VarDecl *clangvardecl = D->getParamDecl(i); // the ith parameter (CLANG)
+ ParmVarDecl *pvd = D->getParamDecl(i);
+ QualType T = pvd->getOriginalType();
+ fprintf(stderr, "OTYPE %s\n", T.getAsString().c_str());
+
+ chillAST_VarDecl *chillPVD = (chillAST_VarDecl *)ConvertVarDecl( clangvardecl, chillFD ) ;
+ //chillPVD->print(); fflush(stdout);
+
+ //chillPVD->isAParameter = 1;
+ VariableDeclarations.push_back(chillPVD);
+
+ chillFD->addParameter(chillPVD);
+ fprintf(stderr, "chillAST ParmVarDecl for %s from chill location 0x%x\n",chillPVD->varname, clangvardecl);
+ } // for each parameter
+
+
+
+ //fprintf(stderr, ")\n{\n"); // beginning of function body
+ //if (D->isExternC()) { chillFD->setExtern(); fprintf(stderr, "%s is extern\n", FuncName.c_str()); };
+ if (D->getBuiltinID()) { chillFD->setExtern(); fprintf(stderr, "%s is builtin (extern)\n", FuncName.c_str()); };
+
+ Stmt *clangbody = D->getBody();
+ if (clangbody) { // may just be fwd decl or external, without an actual body
+ //fprintf(stderr, "body of type %s\n", clangbody->getStmtClassName());
+ //chillAST_node *CB = ConvertCompoundStmt( dyn_cast<CompoundStmt>(clangbody) ); // always a compound statement?
+ chillAST_node *CB = ConvertGenericClangAST( clangbody, chillFD );
+ //fprintf(stderr, "FunctionDecl body = 0x%x of type %s\n", CB, CB->getTypeString());
+ chillFD->setBody ( CB );
+ }
+
+ //fprintf(stderr, "adding function %s 0x%x to FunctionDeclarations\n", chillFD->functionName, chillFD);
+ FunctionDeclarations.push_back(chillFD);
+ return chillFD;
+}
+
+
+chillAST_node * ConvertForStmt( ForStmt *clangFS, chillAST_node *p ) {
+
+ Stmt *init = clangFS->getInit();
+ Expr *cond = clangFS->getCond();
+ Expr *incr = clangFS->getInc();
+ Stmt *body = clangFS->getBody();
+
+ chillAST_node *ini = ConvertGenericClangAST( init, NULL );
+ chillAST_node *con = ConvertGenericClangAST( cond, NULL);
+ chillAST_node *inc = ConvertGenericClangAST( incr, NULL);
+ chillAST_node *bod = ConvertGenericClangAST( body, NULL);
+ if (bod->asttype != CHILLAST_NODETYPE_COMPOUNDSTMT) {
+ //fprintf(stderr, "ForStmt body of type %s\n", bod->getTypeString());
+ // make single statement loop bodies loop like other loops
+ chillAST_CompoundStmt *cs = new chillAST_CompoundStmt( );
+ cs->addChild( bod );
+ bod = cs;
+ }
+
+
+ chillAST_ForStmt *chill_loop = new chillAST_ForStmt( ini, con, inc, bod, p );
+ ini->setParent( chill_loop );
+ con->setParent( chill_loop );
+ inc->setParent( chill_loop );
+ bod->setParent( chill_loop );
+
+ return chill_loop;
+}
+
+
+chillAST_node * ConvertIfStmt( IfStmt *clangIS, chillAST_node *p ) {
+ Expr *cond = clangIS->getCond();
+ Stmt *thenpart = clangIS->getThen();
+ Stmt *elsepart = clangIS->getElse();
+
+ chillAST_node *con = ConvertGenericClangAST( cond, NULL);
+ chillAST_node *thn = NULL;
+ if (thenpart) thn = ConvertGenericClangAST( thenpart, NULL);
+ chillAST_node *els = NULL;
+ if (elsepart) els = ConvertGenericClangAST( elsepart, NULL);
+
+ chillAST_IfStmt *ifstmt = new chillAST_IfStmt( con, thn, els, NULL);
+ return ifstmt;
+}
+
+
+
+chillAST_node * ConvertUnaryOperator( UnaryOperator * clangUO, chillAST_node *p ) {
+ const char *op = unops[clangUO->getOpcode()].c_str();
+ bool pre = clangUO->isPrefix();
+ chillAST_node *sub = ConvertGenericClangAST( clangUO->getSubExpr(), NULL );
+
+ chillAST_UnaryOperator *chillUO = new chillAST_UnaryOperator( op, pre, sub, p );
+ sub->setParent( chillUO );
+ return chillUO;
+}
+
+
+chillAST_node * ConvertBinaryOperator( BinaryOperator * clangBO, chillAST_node *p ) {
+
+ // get the clang parts
+ Expr *lhs = clangBO->getLHS();
+ Expr *rhs = clangBO->getRHS();
+ BinaryOperator::Opcode op = clangBO->getOpcode(); // this is CLANG op, not CHILL op
+
+
+ // convert to chill equivalents
+ chillAST_node *l = ConvertGenericClangAST( lhs, NULL );
+ const char *opstring = binops[op].c_str();
+ chillAST_node *r = ConvertGenericClangAST( rhs, NULL );
+ // TODO chill equivalent for numeric op.
+
+ // build up the chill Binary Op AST node
+ chillAST_BinaryOperator * binop = new chillAST_BinaryOperator( l, opstring, r, p );
+ l->setParent( binop );
+ r->setParent( binop );
+
+ return binop;
+}
+
+
+
+
+chillAST_node * ConvertArraySubscriptExpr( ArraySubscriptExpr *clangASE, chillAST_node *p ) {
+
+ Expr *clangbase = clangASE->getBase();
+ Expr *clangindex = clangASE->getIdx();
+ //fprintf(stderr, "clang base: "); clangbase->dump(); fprintf(stderr, "\n");
+
+ chillAST_node *bas = ConvertGenericClangAST( clangbase, NULL );
+ chillAST_node *indx = ConvertGenericClangAST( clangindex, NULL );
+
+ chillAST_ArraySubscriptExpr * chillASE = new chillAST_ArraySubscriptExpr( bas, indx, p, clangASE);
+ bas->setParent( chillASE );
+ indx->setParent( chillASE );
+ return chillASE;
+}
+
+
+
+chillAST_node * ConvertDeclRefExpr( DeclRefExpr * clangDRE, chillAST_node *p ) {
+ DeclarationNameInfo DNI = clangDRE->getNameInfo();
+
+ ValueDecl *vd = static_cast<ValueDecl *>(clangDRE->getDecl()); // ValueDecl ?? VarDecl ??
+
+ QualType QT = vd->getType();
+ string TypeStr = QT.getAsString();
+ //fprintf(stderr, "\n\n*** type %s ***\n\n", TypeStr.c_str());
+ //fprintf(stderr, "kind %s\n", vd->getDeclKindName());
+
+ DeclarationName DN = DNI.getName();
+ const char *varname = DN.getAsString().c_str() ;
+ chillAST_DeclRefExpr * chillDRE = new chillAST_DeclRefExpr(TypeStr.c_str(), varname, p );
+
+ //fprintf(stderr, "clang DeclRefExpr refers to declaration of %s @ 0x%x\n", varname, vd);
+ //fprintf(stderr, "clang DeclRefExpr refers to declaration of %s of kind %s\n", varname, vd->getDeclKindName());
+
+ // find the definition (we hope)
+ if ( (!strcmp("Var", vd->getDeclKindName())) || (!strcmp("ParmVar", vd->getDeclKindName()))) {
+ // it's a variable reference
+ int numvars = VariableDeclarations.size();
+ chillAST_VarDecl *chillvd = NULL;
+ for (int i=0; i<numvars; i++) {
+ if (VariableDeclarations[i]->uniquePtr == vd) {
+ chillvd = VariableDeclarations[i];
+ //fprintf(stderr, "found it at variabledeclaration %d of %d\n", i, numvars);
+ }
+ }
+ if (!chillvd) {
+ fprintf(stderr, "\nWARNING, ir_clang.cc clang DeclRefExpr %s refers to a declaration I can't find! at ox%x\n", varname, vd);
+ fprintf(stderr, "variables I know of are:\n");
+ for (int i=0; i<numvars; i++) {
+ chillAST_VarDecl *adecl = VariableDeclarations[i];
+ if (adecl->isParmVarDecl()) fprintf(stderr, "(parameter) ");
+ fprintf(stderr, "%s %s at location 0x%x\n", adecl->vartype, adecl->varname, adecl->uniquePtr);
+ }
+ fprintf(stderr, "\n");
+ }
+
+ if (chillvd == NULL) { fprintf(stderr, "chillDRE->decl = 0x%x\n", chillvd); exit(-1); }
+
+ chillDRE->decl = (chillAST_node *)chillvd; // start of spaghetti pointers ...
+ }
+ else if (!strcmp("Function", vd->getDeclKindName())) {
+ //fprintf(stderr, "declrefexpr of type Function\n");
+ int numfuncs = FunctionDeclarations.size();
+ chillAST_FunctionDecl *chillfd = NULL;
+ for (int i=0; i<numfuncs; i++) {
+ if (FunctionDeclarations[i]->uniquePtr == vd) {
+ chillfd = FunctionDeclarations[i];
+ //fprintf(stderr, "found it at functiondeclaration %d of %d\n", i, numfuncs);
+ }
+ }
+ if (chillfd == NULL) { fprintf(stderr, "chillDRE->decl = 0x%x\n", chillfd); exit(-1); }
+
+ chillDRE->decl = (chillAST_node *)chillfd; // start of spaghetti pointers ...
+
+ }
+ else {
+ fprintf(stderr, "clang DeclRefExpr refers to declaration of %s of kind %s\n", varname, vd->getDeclKindName());
+ fprintf(stderr, "chillDRE->decl = UNDEFINED\n");
+ exit(-1);
+ }
+
+ //fprintf(stderr, "%s\n", DN.getAsString().c_str());
+ return chillDRE;
+}
+
+
+
+chillAST_node * ConvertIntegerLiteral( IntegerLiteral *clangIL, chillAST_node *p ) {
+ bool isSigned = clangIL->getType()->isSignedIntegerType();
+ //int val = clangIL->getIntValue();
+ const char *printable = clangIL->getValue().toString(10, isSigned).c_str();
+ int val = atoi( printable );
+ //fprintf(stderr, "int value %s (%d)\n", printable, val);
+ chillAST_IntegerLiteral *chillIL = new chillAST_IntegerLiteral( val, p );
+ return chillIL;
+}
+
+
+chillAST_node * ConvertFloatingLiteral( FloatingLiteral *clangFL, chillAST_node *p ) {
+ //fprintf(stderr, "\nConvertFloatingLiteral()\n");
+ float val = clangFL->getValueAsApproximateDouble(); // TODO approx is a bad idea!
+ string WHAT;
+ SmallString<16> Str;
+ clangFL->getValue().toString( Str );
+ const char *printable = Str.c_str();
+ //fprintf(stderr, "literal %s\n", printable);
+
+ SourceLocation sloc = clangFL->getLocStart();
+ SourceLocation eloc = clangFL->getLocEnd();
+
+ std::string start = sloc.printToString( *globalSRCMAN );
+ std::string end = eloc.printToString( *globalSRCMAN );
+ //fprintf(stderr, "literal try2 start %s end %s\n", start.c_str(), end.c_str());
+ //printlines( sloc, eloc, globalSRCMAN );
+ unsigned int startlineno = globalSRCMAN->getPresumedLineNumber( sloc );
+ unsigned int endlineno = globalSRCMAN->getPresumedLineNumber( eloc ); ;
+ const char *filename = globalSRCMAN->getBufferName( sloc );
+
+ std::string fname = globalSRCMAN->getFilename( sloc );
+ //fprintf(stderr, "fname %s\n", fname.c_str());
+
+ if (filename && strlen(filename) > 0) {} // fprintf(stderr, "literal file '%s'\n", filename);
+ else {
+ fprintf(stderr, "\nConvertFloatingLiteral() filename is NULL?\n");
+
+ //sloc = globalSRCMAN->getFileLoc( sloc ); // should get spelling loc?
+ sloc = globalSRCMAN->getSpellingLoc( sloc ); // should get spelling loc?
+ //eloc = globalSRCMAN->getFileLoc( eloc );
+
+ start = sloc.printToString( *globalSRCMAN );
+ //end = eloc.printToString( *globalSRCMAN );
+ //fprintf(stderr, "literal try3 start %s end %s\n", start.c_str(), end.c_str());
+
+ startlineno = globalSRCMAN->getPresumedLineNumber( sloc );
+ //endlineno = globalSRCMAN->getPresumedLineNumber( eloc ); ;
+ //fprintf(stderr, "start, end line numbers %d %d\n", startlineno, endlineno);
+
+ filename = globalSRCMAN->getBufferName( sloc );
+
+ //if (globalSRCMAN->isMacroBodyExpansion( sloc )) {
+ // fprintf(stderr, "IS MACRO\n");
+ //}
+ }
+
+ unsigned int offset = globalSRCMAN->getFileOffset( sloc );
+ //fprintf(stderr, "literal file offset %d\n", offset);
+
+ FILE *fp = fopen (filename, "r");
+ fseek(fp, offset, SEEK_SET); // go to the part of the file where the float is defined
+
+ char buf[10240];
+ fgets (buf, sizeof(buf), fp); // read a line starting where the float starts
+ fclose(fp);
+
+ // buf has the line we want grab the float constant out of it
+ //fprintf(stderr, "\nbuf '%s'\n", buf);
+ char *ptr = buf;
+ if (*ptr == '-') ptr++; // ignore possible minus sign
+ int len = strspn(ptr, ".-0123456789f");
+ buf[len] = '\0';
+ //fprintf(stderr, "'%s'\n", buf);
+
+ chillAST_FloatingLiteral *chillFL = new chillAST_FloatingLiteral( val, buf, p );
+
+ //chillFL->print(); printf("\n"); fflush(stdout);
+ return chillFL;
+}
+
+
+chillAST_node * ConvertImplicitCastExpr( ImplicitCastExpr *clangICE, chillAST_node *p ) {
+ //fprintf(stderr, "ConvertImplicitCastExpr()\n");
+ CastExpr *CE = dyn_cast<ImplicitCastExpr>(clangICE);
+ //fprintf(stderr, "implicit cast of type %s\n", CE->getCastKindName());
+ chillAST_node * sub = ConvertGenericClangAST( clangICE->getSubExpr(), p );
+ chillAST_ImplicitCastExpr *chillICE = new chillAST_ImplicitCastExpr( sub, p );
+
+ //sub->setParent( chillICE ); // these 2 lines work
+ //return chillICE;
+
+ //sub->setParent(p); // ignore the ImplicitCastExpr !! TODO (probably a bad idea)
+ return sub;
+
+}
+
+
+
+
+chillAST_node * ConvertCStyleCastExpr( CStyleCastExpr *clangCSCE, chillAST_node *p ) {
+ //fprintf(stderr, "ConvertCStyleCastExpr()\n");
+ //fprintf(stderr, "C Style cast of kind ");
+ CastExpr *CE = dyn_cast<CastExpr>(clangCSCE);
+ //fprintf(stderr, "%s\n", CE->getCastKindName());
+
+ //clangCSCE->getTypeAsWritten().getAsString(Policy)
+ const char * towhat = strdup( clangCSCE->getTypeAsWritten().getAsString().c_str() );
+ //fprintf(stderr, "before sub towhat (%s)\n", towhat);
+
+ chillAST_node * sub = ConvertGenericClangAST( clangCSCE->getSubExprAsWritten(), NULL );
+ //fprintf(stderr, "after sub towhat (%s)\n", towhat);
+ chillAST_CStyleCastExpr *chillCSCE = new chillAST_CStyleCastExpr( towhat, sub, p );
+ //fprintf(stderr, "after CSCE towhat (%s)\n", towhat);
+ sub->setParent( chillCSCE );
+ return chillCSCE;
+}
+
+
+
+
+chillAST_node * ConvertReturnStmt( ReturnStmt *clangRS, chillAST_node *p ) {
+ chillAST_node * retval = ConvertGenericClangAST( clangRS->getRetValue(), NULL ); // NULL is handled
+ //if (retval == NULL) fprintf(stderr, "return stmt returns nothing\n");
+
+ chillAST_ReturnStmt * chillRS = new chillAST_ReturnStmt( retval, p );
+ if (retval) retval->setParent( chillRS );
+ return chillRS;
+}
+
+
+chillAST_node * ConvertCallExpr( CallExpr *clangCE, chillAST_node *p ) {
+ //fprintf(stderr, "ConvertCallExpr()\n");
+
+ chillAST_node *callee = ConvertGenericClangAST( clangCE->getCallee(), NULL );
+ //fprintf(stderr, "callee is of type %s\n", callee->getTypeString());
+
+ //chillAST_node *next = ((chillAST_ImplicitCastExpr *)callee)->subexpr;
+ //fprintf(stderr, "callee is of type %s\n", next->getTypeString());
+
+ chillAST_CallExpr *chillCE = new chillAST_CallExpr( callee, p );
+ callee->setParent( chillCE );
+
+ int numargs = clangCE->getNumArgs();
+ //fprintf(stderr, "CallExpr has %d args\n", numargs);
+ Expr **clangargs = clangCE->getArgs();
+ for (int i=0; i<numargs; i++) {
+ chillCE->addArg( ConvertGenericClangAST( clangargs[i], chillCE ) );
+ }
+
+ return chillCE;
+}
+
+
+chillAST_node * ConvertParenExpr( ParenExpr *clangPE, chillAST_node *p ) {
+ chillAST_node *sub = ConvertGenericClangAST( clangPE->getSubExpr(), NULL);
+ chillAST_ParenExpr *chillPE = new chillAST_ParenExpr( sub, p);
+ sub->setParent( chillPE );
+
+ return chillPE;
+}
+
+
+chillAST_node * ConvertTranslationUnit( TranslationUnitDecl *TUD, char *filename ) {
+ //fprintf(stderr, "ConvertTranslationUnit( filename %s )\n\n", filename);
+ // TUD derived from Decl and DeclContext
+ static DeclContext *DC = TUD->castToDeclContext( TUD );
+
+
+ // TODO this was to get the filename without having to pass it in
+ //ASTContext CTX = TUD->getASTContext ();
+ //SourceManager SM = CTX.getSourceManager();
+ //SourceLocation srcloc = ForStatement->getForLoc();
+ //unsigned int lineno = SRCMAN->getPresumedLineNumber( srcloc );
+ //const char *filename = SRCMAN->getBufferName( srcloc );
+
+
+ chillAST_SourceFile * topnode = new chillAST_SourceFile( filename );
+ topnode->setFrontend("clang");
+ topnode->chill_array_counter = 1;
+ topnode->chill_scalar_counter = 0;
+
+ // now recursively build clang AST from the children of TUD
+ //for (DeclContext::decl_iterator DI = DC->decls_begin(), DE = DC->decls_end(); DI != DE; ++DI)
+ DeclContext::decl_iterator start = DC->decls_begin();
+ DeclContext::decl_iterator end = DC->decls_end();
+ for (DeclContext::decl_iterator DI=start; DI != end; ++DI) {
+ Decl *D = *DI;
+
+ if (isa<FunctionDecl>(D)) { //fprintf(stderr, "\nTUD FunctionDecl\n");
+ topnode->addChild( ConvertFunctionDecl( dyn_cast<FunctionDecl>(D), topnode ));
+ }
+ else if (isa<VarDecl>(D)) { //fprintf(stderr, "\nTUD VarDecl\n");
+ topnode->addChild( ConvertVarDecl( dyn_cast<VarDecl>(D), topnode ));
+ //fflush(stdout); fprintf(stderr, "\nTUD VarDecl DONE\n");
+ }
+ else if (isa<TypedefDecl>(D)) { //fprintf(stderr, "\nTUD TypedefDecl\n");
+ topnode->addChild( ConvertTypeDefDecl( dyn_cast<TypedefDecl>(D), topnode ));
+ }
+ else if (isa<RecordDecl>(D)) { fprintf(stderr, "\nTUD RecordDecl\n");
+ topnode->addChild( ConvertRecordDecl( dyn_cast<RecordDecl>(D), topnode ));
+ }
+ else if (isa<TypeAliasDecl>(D)) { fprintf(stderr, "TUD TypeAliasDecl TODO \n"); exit(-1);
+ }
+ else {
+ fprintf(stderr, "\nTUD a declaration of type %s (%d) which I can't handle\n", D->getDeclKindName(), D->getKind());
+ exit(-1);
+ }
+ }
+ //fflush(stdout); fprintf(stderr, "leaving ConvertTranslationUnit()\n\n");
+
+ //fprintf(stderr, "in ConvertTranslationUnit(), dumping the file\n");
+ //topnode->dump();
+ return ( chillAST_node *) topnode;
+}
+
+
+
+ chillAST_node * ConvertGenericClangAST( Stmt *s, chillAST_node *p ) {
+
+ if (s == NULL) return NULL;
+ //fprintf(stderr, "\nConvertGenericClangAST() Stmt of type %d (%s)\n", s->getStmtClass(),s->getStmtClassName());
+ Decl *D = (Decl *) s;
+ //if (isa<Decl>(D)) fprintf(stderr, "Decl of kind %d (%s)\n", D->getKind(),D->getDeclKindName() );
+
+
+ chillAST_node *ret = NULL;
+
+ if (isa<CompoundStmt>(s)) {ret = ConvertCompoundStmt( dyn_cast<CompoundStmt>(s),p);
+ } else if (isa<DeclStmt>(s)) {ret = ConvertDeclStmt(dyn_cast<DeclStmt>(s),p);
+ } else if (isa<ForStmt>(s)) {ret = ConvertForStmt(dyn_cast<ForStmt>(s),p);
+ } else if (isa<BinaryOperator>(s)) {ret = ConvertBinaryOperator(dyn_cast<BinaryOperator>(s),p);
+ } else if (isa<ArraySubscriptExpr>(s)) {ret = ConvertArraySubscriptExpr(dyn_cast<ArraySubscriptExpr>(s),p);
+ } else if (isa<DeclRefExpr>(s)) {ret = ConvertDeclRefExpr(dyn_cast<DeclRefExpr>(s),p);
+ } else if (isa<FloatingLiteral>(s)) {ret = ConvertFloatingLiteral(dyn_cast<FloatingLiteral>(s),p);
+ } else if (isa<IntegerLiteral>(s)) {ret = ConvertIntegerLiteral(dyn_cast<IntegerLiteral>(s),p);
+ } else if (isa<UnaryOperator>(s)) {ret = ConvertUnaryOperator(dyn_cast<UnaryOperator>(s),p);
+ } else if (isa<ImplicitCastExpr>(s)) {ret = ConvertImplicitCastExpr(dyn_cast<ImplicitCastExpr>(s),p);
+ } else if (isa<CStyleCastExpr>(s)) {ret = ConvertCStyleCastExpr(dyn_cast<CStyleCastExpr>(s),p);
+ } else if (isa<ReturnStmt>(s)) {ret = ConvertReturnStmt(dyn_cast<ReturnStmt>(s),p);
+ } else if (isa<CallExpr>(s)) {ret = ConvertCallExpr(dyn_cast<CallExpr>(s),p);
+ } else if (isa<ParenExpr>(s)) {ret = ConvertParenExpr(dyn_cast<ParenExpr>(s),p);
+ } else if (isa<IfStmt>(s)) {ret = ConvertIfStmt(dyn_cast<IfStmt>(s),p);
+ } else if (isa<MemberExpr>(s)) {ret = ConvertMemberExpr(dyn_cast<MemberExpr>(s),p);
+
+
+ // these can only happen at the top level?
+ // } else if (isa<FunctionDecl>(D)) { ret = ConvertFunctionDecl( dyn_cast<FunctionDecl>(D));
+ //} else if (isa<VarDecl>(D)) { ret = ConvertVarDecl( dyn_cast<VarDecl>(D) );
+ //} else if (isa<TypedefDecl>(D)) { ret = ConvertTypeDefDecl( dyn_cast<TypedefDecl>(D));
+ // else if (isa<TranslationUnitDecl>(s)) // need filename
+
+
+
+
+ // } else if (isa<>(s)) { Convert ( dyn_cast<>(s));
+
+ /*
+ */
+
+ } else {
+ // more work to do
+ fprintf(stderr, "ir_clang.cc ConvertGenericClangAST() UNHANDLED ");
+ //if (isa<Decl>(D)) fprintf(stderr, "Decl of kind %s\n", D->getDeclKindName() );
+ if (isa<Stmt>(s))fprintf(stderr, "Stmt of type %s\n", s->getStmtClassName());
+ exit(-1);
+ }
+
+ return ret;
+ }
+
+
+
+
+
+
+
+
+
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillScalarSymbol
+// ----------------------------------------------------------------------------
+
+std::string IR_chillScalarSymbol::name() const {
+ //return vd_->getNameAsString(); CLANG
+ //fprintf(stderr, "IR_chillScalarSymbol::name() %s\n", chillvd->varname);
+ return std::string(chillvd->varname); // CHILL
+}
+
+
+// Return size in bytes
+int IR_chillScalarSymbol::size() const {
+ //return (vd_->getASTContext().getTypeSize(vd_->getType())) / 8; // ??
+ fprintf(stderr, "IR_chillScalarSymbol::size() probably WRONG\n");
+ return (8); // bytes??
+}
+
+
+bool IR_chillScalarSymbol::operator==(const IR_Symbol &that) const {
+ //fprintf(stderr, "IR_xxxxScalarSymbol::operator== probably WRONG\n");
+ if (typeid(*this) != typeid(that))
+ return false;
+
+ const IR_chillScalarSymbol *l_that = static_cast<const IR_chillScalarSymbol *>(&that);
+ return this->chillvd == l_that->chillvd;
+}
+
+IR_Symbol *IR_chillScalarSymbol::clone() const {
+ return new IR_chillScalarSymbol(ir_, chillvd ); // clone
+}
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillArraySymbol
+// ----------------------------------------------------------------------------
+
+std::string IR_chillArraySymbol::name() const {
+ return std::string( strdup( chillvd ->varname));
+}
+
+
+int IR_chillArraySymbol::elem_size() const {
+ fprintf(stderr, "IR_chillArraySymbol::elem_size() TODO\n"); exit(-1);
+ return 8; // TODO
+ //const ArrayType *at = dyn_cast<ArrayType>(vd_->getType());
+ //if(at) {
+ // return (vd_->getASTContext().getTypeSize(at->getElementType())) / 8;
+ //} else
+ // throw ir_error("Symbol is not an array!");
+ //return 0;
+}
+
+
+int IR_chillArraySymbol::n_dim() const {
+ //fprintf(stderr, "IR_chillArraySymbol::n_dim()\n");
+ //fprintf(stderr, "variable %s %s %s\n", chillvd->vartype, chillvd->varname, chillvd->arraypart);
+ //fprintf(stderr, "IR_chillArraySymbol::n_dim() %d\n", chillvd->numdimensions);
+ //fprintf(stderr, "IR_chillArraySymbol::n_dim() TODO \n"); exit(-1);
+ return chillvd->numdimensions;
+}
+
+
+// TODO
+omega::CG_outputRepr *IR_chillArraySymbol::size(int dim) const {
+ fprintf(stderr, "IR_chillArraySymbol::n_size() TODO \n"); exit(-1);
+ return NULL;
+}
+
+
+bool IR_chillArraySymbol::operator!=(const IR_Symbol &that) const {
+ //fprintf(stderr, "IR_xxxxArraySymbol::operator!= NOT EQUAL\n");
+ //chillAST_VarDecl *chillvd;
+ return chillvd != ((IR_chillArraySymbol*)&that)->chillvd ;
+}
+
+bool IR_chillArraySymbol::operator==(const IR_Symbol &that) const {
+ //fprintf(stderr, "IR_xxxxArraySymbol::operator== EQUAL\n");
+ //chillAST_VarDecl *chillvd;
+ return chillvd == ((IR_chillArraySymbol*)&that)->chillvd ;
+ /*
+ if (typeid(*this) != typeid(that))
+ return false;
+
+ const IR_chillArraySymbol *l_that = static_cast<const IR_chillArraySymbol *>(&that);
+ return this->vd_ == l_that->vd_ && this->offset_ == l_that->offset_;
+ */
+}
+
+
+IR_Symbol *IR_chillArraySymbol::clone() const {
+ return new IR_chillArraySymbol(ir_, chillvd, offset_);
+}
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillConstantRef
+// ----------------------------------------------------------------------------
+
+bool IR_chillConstantRef::operator==(const IR_Ref &that) const {
+ if (typeid(*this) != typeid(that))
+ return false;
+
+ const IR_chillConstantRef *l_that = static_cast<const IR_chillConstantRef *>(&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_chillConstantRef::convert() {
+ //assert(astContext_ != NULL);
+ if (type_ == IR_CONSTANT_INT) {
+
+ fprintf(stderr, "IR_chillConstantRef::convert() unimplemented\n"); exit(-1);
+
+ // TODO
+ /*
+ BuiltinType *bint = new BuiltinType(BuiltinType::Int);
+ IntegerLiteral *ilit = new (astContext_)IntegerLiteral(*astContext_, llvm::APInt(32, i_), bint->desugar(), SourceLocation());
+ omega::CG_chillRepr *result = new omega::CG_chillRepr(ilit);
+ delete this;
+ return result;
+ */
+ }
+ else
+ throw ir_error("constant type not supported");
+}
+
+
+IR_Ref *IR_chillConstantRef::clone() const {
+ if (type_ == IR_CONSTANT_INT)
+ return new IR_chillConstantRef(ir_, i_);
+ else if (type_ == IR_CONSTANT_FLOAT)
+ return new IR_chillConstantRef(ir_, f_);
+ else
+ throw ir_error("constant type not supported");
+}
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillScalarRef
+// ----------------------------------------------------------------------------
+
+bool IR_chillScalarRef::is_write() const {
+ return op_pos_ == OP_DEST; // 2 other alternatives: OP_UNKNOWN, OP_SRC
+}
+
+
+IR_ScalarSymbol *IR_chillScalarRef::symbol() const {
+ //VarDecl *vd = static_cast<VarDecl *>(vs_->getDecl());
+ //fprintf(stderr, "ir_clang.cc IR_chillScalarRef::symbol()\n"); //exit(-1);
+ chillAST_VarDecl *vd = NULL;
+ if (chillvd) vd = chillvd;
+ return new IR_chillScalarSymbol(ir_, vd); // IR_chillScalarRef::symbol()
+}
+
+
+bool IR_chillScalarRef::operator==(const IR_Ref &that) const {
+ if (typeid(*this) != typeid(that))
+ return false;
+
+ const IR_chillScalarRef *l_that = static_cast<const IR_chillScalarRef *>(&that);
+
+ return this->chillvd == l_that->chillvd;
+}
+
+
+omega::CG_outputRepr *IR_chillScalarRef::convert() {
+ //fprintf(stderr, "IR_chillScalarRef::convert() unimplemented\n"); exit(-1);
+ if (!dre) fprintf(stderr, "IR_chillScalarRef::convert() CLANG SCALAR REF has no dre\n");
+ omega::CG_chillRepr *result = new omega::CG_chillRepr(dre);
+ delete this;
+ return result;
+}
+
+IR_Ref * IR_chillScalarRef::clone() const {
+ if (dre) return new IR_chillScalarRef(ir_, dre); // use declrefexpr if it exists
+ return new IR_chillScalarRef(ir_, chillvd); // uses vardecl
+}
+
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillArrayRef
+// ----------------------------------------------------------------------------
+
+bool IR_chillArrayRef::is_write() const {
+
+ return (iswrite); // TODO
+}
+
+
+// TODO
+omega::CG_outputRepr *IR_chillArrayRef::index(int dim) const {
+ fprintf(stderr, "IR_xxxxArrayRef::index( %d ) \n", dim);
+ //chillASE->print(); printf("\n"); fflush(stdout);
+ //chillASE->getIndex(dim)->print(); printf("\n"); fflush(stdout);
+ return new omega::CG_chillRepr( chillASE->getIndex(dim) );
+}
+
+
+IR_ArraySymbol *IR_chillArrayRef::symbol() const {
+ //fprintf(stderr, "IR_chillArrayRef::symbol()\n");
+ //chillASE->print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "base: "); chillASE->base->print(); printf("\n"); fflush(stdout);
+
+
+ chillAST_node *mb = chillASE->multibase();
+ chillAST_VarDecl *vd = (chillAST_VarDecl*)mb;
+ //fprintf(stderr, "symbol: '%s'\n", vd->varname);
+
+ //fprintf(stderr, "IR_chillArrayRef symbol: '%s%s'\n", vd->varname, vd->arraypart);
+ //fprintf(stderr, "numdimensions %d\n", vd->numdimensions);
+ IR_ArraySymbol *AS = new IR_chillArraySymbol(ir_, vd);
+ //fprintf(stderr, "ir_clang.cc returning IR_chillArraySymbol 0x%x\n", AS);
+ return AS;
+/*
+ chillAST_node *b = chillASE->base;
+ fprintf(stderr, "base of type %s\n", b->getTypeString());
+ //b->print(); printf("\n"); fflush(stdout);
+ if (b->asttype == CHILLAST_NODETYPE_IMPLICITCASTEXPR) {
+ b = ((chillAST_ImplicitCastExpr*)b)->subexpr;
+ fprintf(stderr, "base of type %s\n", b->getTypeString());
+ }
+
+ if (b->asttype == CHILLAST_NODETYPE_DECLREFEXPR) {
+ if (NULL == ((chillAST_DeclRefExpr*)b)->decl) {
+ fprintf(stderr, "IR_chillArrayRef::symbol() var decl = 0x%x\n", ((chillAST_DeclRefExpr*)b)->decl);
+ exit(-1);
+ }
+ return new IR_chillArraySymbol(ir_, ((chillAST_DeclRefExpr*)b)->decl); // -> decl?
+ }
+ if (b->asttype == CHILLAST_NODETYPE_ARRAYSUBSCRIPTEXPR) { // multidimensional array
+ return (
+ }
+ fprintf(stderr, "IR_chillArrayRef::symbol() can't handle\n");
+ fprintf(stderr, "base of type %s\n", b->getTypeString());
+ exit(-1);
+ return NULL;
+*/
+}
+
+
+bool IR_chillArrayRef::operator!=(const IR_Ref &that) const {
+ //fprintf(stderr, "IR_xxxxArrayRef::operator!=\n");
+ bool op = (*this) == that; // opposite
+ return !op;
+}
+
+void IR_chillArrayRef::Dump() const {
+ //fprintf(stderr, "IR_chillArrayRef::Dump() this 0x%x chillASE 0x%x\n", this, chillASE);
+ chillASE->print(); printf("\n");fflush(stdout);
+}
+
+
+bool IR_chillArrayRef::operator==(const IR_Ref &that) const {
+ //fprintf(stderr, "IR_xxxxArrayRef::operator==\n");
+ //printf("I am\n"); chillASE->print(); printf("\n");
+ const IR_chillArrayRef *l_that = static_cast<const IR_chillArrayRef *>(&that);
+ const chillAST_ArraySubscriptExpr* thatASE = l_that->chillASE;
+ //printf("other is:\n"); thatASE->print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "addresses are 0x%x 0x%x\n", chillASE, thatASE );
+ return (*chillASE) == (*thatASE);
+ /*
+
+ if (typeid(*this) != typeid(that))
+ return false;
+
+ const IR_chillArrayRef *l_that = static_cast<const IR_chillArrayRef *>(&that);
+
+ return this->as_ == l_that->as_;
+ */
+}
+
+
+omega::CG_outputRepr *IR_chillArrayRef::convert() {
+ //fprintf(stderr, "IR_chillArrayRef::convert()\n");
+ CG_chillRepr *result = new CG_chillRepr( chillASE->clone() );
+// omega::CG_chillRepr *temp = new omega::CG_chillRepr(static_cast<Expr*>(this->as_));
+// omega::CG_outputRepr *result = temp->clone();
+ delete this;
+ return result;
+}
+
+
+IR_Ref *IR_chillArrayRef::clone() const {
+ return new IR_chillArrayRef(ir_, chillASE, iswrite);
+}
+
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillLoop
+// ----------------------------------------------------------------------------
+IR_chillLoop::IR_chillLoop(const IR_Code *ir, clang::ForStmt *tf) { fprintf(stderr, "IR_chillLoop::IR_chillLoop() you lose\n"); exit(-1); };
+
+IR_chillLoop::IR_chillLoop(const IR_Code *ir, chillAST_ForStmt *achillforstmt) {
+ fprintf(stderr, "IR_xxxxLoop::IR_xxxxLoop()\n");
+ fprintf(stderr, "loop is:\n");
+ achillforstmt->print();
+
+ ir_ = ir;
+ chillforstmt = achillforstmt;
+
+ chillAST_BinaryOperator *init = (chillAST_BinaryOperator *)chillforstmt->getInit();
+ chillAST_BinaryOperator *cond = (chillAST_BinaryOperator *)chillforstmt->getCond();
+ // check to be sure (assert)
+ if (!init->isAssignmentOp() || !cond->isComparisonOp() ) {
+ fprintf(stderr, "ir_clang.cc, malformed loop init or cond:\n");
+ achillforstmt->print();
+ exit(-1);
+ }
+
+ chilllowerbound = init->getRHS();
+ chillupperbound = cond->getRHS();
+ conditionoperator = achillforstmt->conditionoperator;
+
+ chillAST_node *inc = chillforstmt->getInc();
+ // check the increment
+ //fprintf(stderr, "increment is of type %s\n", inc->getTypeString());
+ //inc->print(); printf("\n"); fflush(stdout);
+
+ if (inc->asttype == CHILLAST_NODETYPE_UNARYOPERATOR) {
+ if (!strcmp(((chillAST_UnaryOperator *) inc)->op, "++")) step_size_ = 1;
+ else step_size_ = -1;
+ }
+ else if (inc->asttype == CHILLAST_NODETYPE_BINARYOPERATOR) {
+ int beets = false; // slang
+ chillAST_BinaryOperator *bop = (chillAST_BinaryOperator *) inc;
+ if (bop->isAssignmentOp()) { // I=I+1 or similar
+ chillAST_node *rhs = bop->getRHS(); // (I+1)
+ // TODO looks like this will fail for I=1+I or I=J+1 etc. do more checking
+
+ char *assop = bop->getOp();
+ //fprintf(stderr, "'%s' is an assignment op\n", bop->getOp());
+ if (streq(assop, "+=") || streq(assop, "-=")) {
+ chillAST_node *stride = rhs;
+ //fprintf(stderr, "stride is of type %s\n", stride->getTypeString());
+ if (stride->isIntegerLiteral()) {
+ int val = ((chillAST_IntegerLiteral *)stride)->value;
+ if (streq( assop, "+=")) step_size_ = val;
+ else if (streq( assop, "-=")) step_size_ = -val;
+ else beets = true;
+ }
+ else beets = true; // += or -= but not constant stride
+ }
+ else if (rhs->isBinaryOperator()) {
+ chillAST_BinaryOperator *binoprhs = (chillAST_BinaryOperator *)rhs;
+ chillAST_node *intlit = binoprhs->getRHS();
+ if (intlit->isIntegerLiteral()) {
+ int val = ((chillAST_IntegerLiteral *)intlit)->value;
+ if (!strcmp( binoprhs->getOp(), "+")) step_size_ = val;
+ else if (!strcmp( binoprhs->getOp(), "-")) step_size_ = -val;
+ else beets = true;
+ }
+ else beets = true;
+ }
+ else beets = true;
+ }
+ else beets = true;
+
+ if (beets) {
+ fprintf(stderr, "malformed loop increment (or more likely unhandled case)\n");
+ inc->print();
+ exit(-1);
+ }
+ } // binary operator
+ else {
+ fprintf(stderr, "IR_chillLoop constructor, unhandled loop increment\n");
+ inc->print();
+ exit(-1);
+ }
+ //inc->print(0, stderr);fprintf(stderr, "\n");
+
+ chillAST_DeclRefExpr *dre = (chillAST_DeclRefExpr *)init->getLHS();
+ if (!dre->isDeclRefExpr()) {
+ fprintf(stderr, "malformed loop init.\n");
+ init->print();
+ }
+
+ chillindex = dre; // the loop index variable
+
+ //fprintf(stderr, "\n\nindex is "); dre->print(0, stderr); fprintf(stderr, "\n");
+ //fprintf(stderr, "init is ");
+ //chilllowerbound->print(0, stderr); fprintf(stderr, "\n");
+ //fprintf(stderr, "condition is %s ", "<");
+ //chillupperbound->print(0, stderr); fprintf(stderr, "\n");
+ //fprintf(stderr, "step size is %d\n\n", step_size_) ;
+
+ chillbody = achillforstmt->getBody();
+
+ fprintf(stderr, "IR_xxxxLoop::IR_xxxxLoop() DONE\n");
+}
+
+
+omega::CG_outputRepr *IR_chillLoop::lower_bound() const {
+ fprintf(stderr, "IR_xxxxLoop::lower_bound()\n");
+ return new omega::CG_chillRepr(chilllowerbound);
+}
+
+omega::CG_outputRepr *IR_chillLoop::upper_bound() const {
+ fprintf(stderr, "IR_xxxxLoop::upper_bound()\n");
+ return new omega::CG_chillRepr(chillupperbound);
+}
+
+IR_Block *IR_chillLoop::body() const {
+ fprintf(stderr, "IR_xxxxLoop::body()\n");
+ //assert(isa<CompoundStmt>(tf_->getBody()));
+ //fprintf(stderr, "returning a clangBLOCK corresponding to the body of the loop\n");
+ //fprintf(stderr, "body type %s\n", chillbody->getTypeString());
+ return new IR_chillBlock(ir_, chillbody ) ; // static_cast<CompoundStmt *>(tf_->getBody()));
+}
+
+IR_Control *IR_chillLoop::clone() const {
+ fprintf(stderr, "IR_xxxxLoop::clone()\n");
+ //chillforstmt->print(); fflush(stdout);
+ return new IR_chillLoop(ir_, chillforstmt);
+}
+
+IR_CONDITION_TYPE IR_chillLoop::stop_cond() const {
+ chillAST_BinaryOperator *loopcondition = (chillAST_BinaryOperator*) chillupperbound;
+ fprintf(stderr, "IR_xxxxLoop::stop_cond()\n");
+ return conditionoperator;
+}
+
+IR_Block *IR_chillLoop::convert() { // convert the loop to a block
+ fprintf(stderr, "IR_xxxxLoop::convert() maybe \n");
+ return new IR_chillBlock( ir_, chillbody ); // ??
+ return NULL;
+}
+
+void IR_chillLoop::dump() const {
+ fprintf(stderr, "TODO: IR_chillLoop::dump()\n"); exit(-1);
+}
+
+
+// ----------------------------------------------------------------------------
+// Class: IR_chillBlock
+// ----------------------------------------------------------------------------
+omega::CG_outputRepr *IR_chillBlock::original() const {
+ fprintf(stderr, "IR_xxxxBlock::original() TODO \n");
+ exit(-1);
+ return NULL;
+}
+
+
+
+omega::CG_outputRepr *IR_chillBlock::extract() const {
+ fflush(stdout);
+ fprintf(stderr, "IR_xxxxBlock::extract()\n");
+ //omega::CG_chillRepr *tnl = new omega::CG_chillRepr(getStmtList());
+
+ // if the block refers to a compound statement, return the next level
+ // of statements ; otherwise just return a repr of the statements
+
+ chillAST_node *code = chillAST;
+ //if (chillAST != NULL) fprintf(stderr, "block has chillAST of type %s\n",code->getTypeString());
+ //fprintf(stderr, "block has %d exploded statements\n", statements.size());
+
+ omega::CG_chillRepr *OR;
+ if (0 == statements.size()) {
+ OR = new omega::CG_chillRepr(code); // presumably a compound statement ??
+ }
+ else {
+ fprintf(stderr, "adding a statement from IR_chillBlock::extract()\n");
+ OR = new omega::CG_chillRepr(); // empty of statements
+ for (int i=0; i<statements.size(); i++) OR->addStatement( statements[i] );
+ }
+
+ fflush(stdout);
+ fprintf(stderr, "IR_xxxxBlock::extract() LEAVING\n");
+ return OR;
+}
+
+IR_Control *IR_chillBlock::clone() const {
+ fprintf(stderr, "IR_xxxxBlock::clone()\n");
+ //fprintf(stderr, "IR_xxxxBlock::clone() %d statements\n", statements.size());
+ return new IR_chillBlock( this ); // shallow copy ?
+}
+
+void IR_chillBlock::dump() const {
+ fprintf(stderr, "IR_chillBlock::dump() TODO\n"); return;
+}
+
+//StmtList
+vector<chillAST_node*> IR_chillBlock::getStmtList() const {
+ fprintf(stderr, "IR_xxxxBlock::getStmtList()\n");
+ return statements; // ??
+}
+
+
+void IR_chillBlock::addStatement( chillAST_node* s ) {
+ statements.push_back( s );
+}
+
+
+
+void PrintTranslationUnit( TranslationUnitDecl *TUD) { // , ASTContext &CTX ) {
+ fprintf(stderr, "MY PrintTranslationUnit()\n");
+ // TUD derived from Decl and DeclContext
+ static DeclContext *DC = TUD->castToDeclContext( TUD );
+ //SourceManager SM = CTX.getSourceManager();
+
+ for (DeclContext::decl_iterator DI = DC->decls_begin(), DE = DC->decls_end(); DI != DE; ++DI) {
+ Decl *D = *DI;
+ fprintf(stderr, "D\n");
+ if (isa<FunctionDecl>(D)) { fprintf(stderr, "FunctionDecl\n");
+ //PrintFunctionDecl( dyn_cast<FunctionDecl>(D), CTX.getSourceManager(), 0);
+ }
+ else if (isa<VarDecl>(D)) { fprintf(stderr, "VarDecl\n");
+ //PrintVarDecl( dyn_cast<VarDecl>(D), CTX.getSourceManager(), 0 );
+ }
+ else if (isa<TypedefDecl>(D)) { fprintf(stderr, "TypedefDecl\n");
+ //PrintTypeDefDecl( dyn_cast<TypedefDecl>(D), CTX.getSourceManager(), 0 );
+ }
+ else if (isa<TypeAliasDecl>(D)) { fprintf(stderr, "TypeAliasDecl\n");
+ }
+ else fprintf(stderr, "\na declaration of type %s (%d)\n", D->getDeclKindName(), D->getKind());
+ //else if (isa<TypedefNameDecl>(D)) { fprintf(stderr, "TypedefNameDecl\n");}
+ }
+}
+
+class NULLASTConsumer : public ASTConsumer
+{
+};
+
+
+
+void findmanually( chillAST_node *node, char *procname, std::vector<chillAST_node*>& procs ) {
+ //fprintf(stderr, "findmanually() CHILL AST node of type %s\n", node->getTypeString());
+
+ if (node->asttype == CHILLAST_NODETYPE_FUNCTIONDECL ) {
+ char *name = ((chillAST_FunctionDecl *) node)->functionName;
+ //fprintf(stderr, "node name 0x%x ", name);
+ //fprintf(stderr, "%s procname ", name);
+ //fprintf(stderr, "0x%x ", procname);
+ //fprintf(stderr, "%s\n", procname);
+ if (!strcmp( name, procname)) {
+ //fprintf(stderr, "found procedure %s\n", procname );
+ procs.push_back( node );
+ // quit recursing. probably not correct in some horrible case
+ return;
+ }
+ //else fprintf(stderr, "this is not the function we're looking for\n");
+ }
+
+
+ // this is where the children can be used effectively.
+ // we don't really care what kind of node we're at. We just check the node itself
+ // and then its children is needed.
+
+ int numc = node->children.size();
+ //fprintf(stderr, "%d children\n", numc);
+
+ for (int i=0; i<numc; i++) {
+ //fprintf(stderr, "node of type %s is recursing to child %d\n", node->getTypeString(), i);
+ findmanually( node->children[i], procname, procs );
+ }
+ return;
+}
+
+// ----------------------------------------------------------------------------
+// Class: IR_clangCode_Global_Init
+// ----------------------------------------------------------------------------
+
+IR_clangCode_Global_Init *IR_clangCode_Global_Init::pinstance = 0;
+
+
+IR_clangCode_Global_Init *IR_clangCode_Global_Init::Instance(char **argv) {
+ fprintf(stderr, "in IR_clangCode_Global_Init::Instance(), ");
+ if (pinstance == 0) {
+ //fprintf(stderr, "\n\n*** making the one and only instance ***\n\n\n");
+ // this is the only way to create an IR_clangCode_Global_Init
+ pinstance = new IR_clangCode_Global_Init;
+ pinstance->ClangCompiler = new aClangCompiler( argv[1] );
+
+ }
+ //fprintf(stderr, "leaving IR_clangCode_Global_Init::Instance()\n");
+ return pinstance;
+}
+
+
+aClangCompiler::aClangCompiler( char *filename ) {
+
+ //fprintf(stderr, "making a clang compiler for file %s\n", filename);
+ SourceFileName = strdup( filename );
+
+ // Arguments to pass to the clang frontend
+ std::vector<const char *> args;
+ args.push_back(strdup(filename));
+
+ // The compiler invocation needs a DiagnosticsEngine so it can report problems
+ //IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); // temp
+ diagnosticOptions = new DiagnosticOptions(); // private member of aClangCompiler
+
+ pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::errs(), diagnosticOptions); // private member of aClangCompiler
+
+ //llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
+ diagID = new clang::DiagnosticIDs(); // private member of IR_clangCode_Global_Init
+
+ //clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
+ diagnosticsEngine = new clang::DiagnosticsEngine(diagID, diagnosticOptions, pTextDiagnosticPrinter);
+
+ // Create the compiler invocation
+ // This class is designed to represent an abstract "invocation" of the compiler,
+ // including data such as the include paths, the code generation options,
+ // the warning flags, and so on.
+ std::unique_ptr<clang::CompilerInvocation> CI(new clang::CompilerInvocation());
+ //CI = new clang::CompilerInvocation;
+ clang::CompilerInvocation::CreateFromArgs(*CI, &args[0], &args[0] + args.size(), *diagnosticsEngine);
+
+
+ // Create the compiler instance
+ Clang = new clang::CompilerInstance(); // TODO should have a better name ClangCompilerInstance
+
+
+ // Get ready to report problems
+ Clang->createDiagnostics(nullptr, true);
+ //Clang.createDiagnostics(0, 0);
+
+
+//#ifdef KIDDINGME
+ //fprintf(stderr, "target\n");
+ // Initialize target info with the default triple for our platform.
+ //TargetOptions TO;
+ //TO.Triple = llvm::sys::getDefaultTargetTriple();
+ //TargetInfo *TI = TargetInfo::CreateTargetInfo( Clang->getDiagnostics(), TO);
+
+ // the above causes core dumps, because clang is stupid and frees the target multiple times, corrupting memory
+ const std::shared_ptr<clang::TargetOptions> to = std::make_shared<clang::TargetOptions>();
+ targetOptions->Triple = llvm::sys::getDefaultTargetTriple();
+
+ TargetInfo *pti = TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),to);
+
+ Clang->setTarget(pti);
+
+//#endif
+
+
+ // ??
+ //fprintf(stderr, "filemgr\n");
+ Clang->createFileManager();
+ FileManager &FileMgr = Clang->getFileManager();
+ fileManager = &FileMgr;
+
+ //fprintf(stderr, "sourcemgr\n");
+ Clang->createSourceManager(FileMgr);
+ SourceManager &SourceMgr = Clang->getSourceManager();
+ sourceManager = &SourceMgr; // ?? aclangcompiler copy
+ globalSRCMAN = &SourceMgr; // TODO global bad
+
+ Clang->setInvocation(CI.get()); // Replace the current invocation
+
+
+
+ //fprintf(stderr, "PP\n");
+ Clang->createPreprocessor(TU_Complete);
+
+
+
+ //clang::Preprocessor Pre = Clang->getPreprocessor();
+ //preprocessor = &Pre;
+
+ //fprintf(stderr, "CONTEXT\n");
+ Clang->createASTContext(); // needs preprocessor
+ astContext_ = &Clang->getASTContext();
+
+
+ //fprintf(stderr, "filein\n");
+ const FileEntry *FileIn = FileMgr.getFile(filename); // needs preprocessor
+ SourceMgr.setMainFileID(SourceMgr.createFileID(FileIn,clang::SourceLocation(),clang::SrcMgr::C_User));
+ //DiagnosticConsumer DiagConsumer = Clang->getDiagnosticClient();
+ Clang->getDiagnosticClient().BeginSourceFile( Clang->getLangOpts(), &Clang->getPreprocessor());
+
+
+ NULLASTConsumer TheConsumer; // must pass a consumer in to ParseAST(). This one does nothing
+
+ //fprintf(stderr, "ready? Parse.\n");
+ fprintf(stderr, "actually parsing file %s using clang\n", filename);
+
+ ParseAST( Clang->getPreprocessor(), &TheConsumer, Clang->getASTContext());
+
+ // Translation Unit is contents of a file
+ TranslationUnitDecl* TUD = astContext_->getTranslationUnitDecl();
+ // TUD->dump(); // print it out
+
+ // create another AST, very similar to the clang AST but not written by idiots
+ fprintf(stderr, "converting entire clang AST into chill AST (ir_clang.cc)\n");
+ chillAST_node * wholefile = ConvertTranslationUnit( TUD, filename);
+
+ fflush(stdout);
+ //fprintf(stderr, "printing whole file\n");
+ //fprintf(stdout, "\n\n" ); fflush(stdout);
+ //wholefile->print();
+ //wholefile->dump();
+ //fflush(stdout);
+
+ entire_file_AST = (chillAST_SourceFile *)wholefile;
+
+
+ astContext_ = &Clang->getASTContext();
+
+ //#define DOUBLE
+#ifdef DOUBLE
+ fprintf(stderr, "DOUBLE\n");
+
+ fprintf(stderr, "\n\nCLANG dump of the file I parsed:\n");
+ llvm::OwningPtr<clang::FrontendAction> Act2(new clang::ASTDumpAction());
+ // here it actually does the FrontEndAction ??
+ if (!Clang->ExecuteAction(*Act2)) { // ast dump using builtin function
+ exit(3);
+ }
+#endif
+ fflush(stdout); fflush(stderr);
+ fflush(stdout); fflush(stderr);
+ fflush(stdout); fflush(stderr);
+ fflush(stdout); fflush(stderr);
+
+
+
+
+
+
+
+
+
+#ifdef DONTDOTHIS
+
+ // calling this Action seems to overwrite the astcontext and the AST. (!)
+ // don't ever do this, or you lose contact with the original AST (?)
+
+ // Create an action and make the compiler instance carry it out
+ //llvm::OwningPtr<clang::CodeGenAction> Act(new clang::EmitLLVMOnlyAction());
+ llvm::OwningPtr<clang::FrontendAction> Act(new clang::ASTDumpAction());
+
+ fprintf(stderr, "\n\ndump of the file I parsed:\n");
+ // here it actually does the FrontEndAction ??
+ if (!Clang->ExecuteAction(*Act)) { // ast dump using builtin function
+ exit(3);
+ }
+ fflush(stdout);
+#endif
+
+
+ //fprintf(stderr, "leaving aClangCompiler::aClangCompiler( filename )\n");
+}
+
+
+
+
+chillAST_FunctionDecl* aClangCompiler::findprocedurebyname( char *procname ) {
+
+ //fprintf(stderr, "searching through files in the clang AST\n\n");
+ //fprintf(stderr, "astContext_ 0x%x\n", astContext_);
+
+ std::vector<chillAST_node*> procs;
+ findmanually( entire_file_AST, procname, procs );
+
+ //fprintf(stderr, "procs has %d members\n", procs.size());
+
+ if ( procs.size() == 0 ) {
+ fprintf(stderr, "could not find function named '%s' in AST from file %s\n", procname, SourceFileName);
+ exit(-1);
+ }
+
+ if ( procs.size() > 1 ) {
+ fprintf(stderr, "oddly, found %d functions named '%s' in AST from file %s\n", procs.size(), procname, SourceFileName);
+ fprintf(stderr, "I am unsure what to do\n");
+ exit(-1);
+ }
+
+ fprintf(stderr, "found the procedure named %s\n", procname);
+ return (chillAST_FunctionDecl *)procs[0];
+
+}
+
+
+
+#ifdef NOPE
+IR_clangCode_Global_Init::IR_clangCode_Global_Init(char *filename , clang::FileSystemOptions fso ) :
+ fileManager(fso) // , headerSearch( headerSearchOptions, fileManager, diagengine, languageOptions, pTargetInfo )
+{
+ /* CLANG Initialization */
+ diagnosticsEngine = new clang::DiagnosticsEngine( const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
+ diagnosticOptionsnsa utah
+ ) ; // DiagnosticConsumer *client = 0, bool ShouldOwnClient = true)
+ pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter(llvm::outs(), diagnosticOptions);
+ diagnostic = new clang::Diagnostic(pTextDiagnosticPrinter);
+ sourceManager = new clang::SourceManager(*diagnostic);
+
+ // FIXME
+
+ // <Warning!!> -- Platform Specific Code lives here
+ // This depends on A) that you're running linux and
+ // B) that you have the same GCC LIBs installed that
+ // I do.
+ // Search through Clang itself for something like this,
+ // go on, you won't find it. The reason why is Clang
+ // has its own versions of std* which are installed under
+ // /usr/local/lib/clang/<version>/include/
+ // See somewhere around Driver.cpp:77 to see Clang adding
+ // its version of the headers to its include path.
+ /*headerSearchOptions.AddPath("/usr/include/linux", clang::frontend::Angled, false, false, false);
+ headerSearchOptions.AddPath("/usr/include/c++/4.3/tr1", clang::frontend::Angled, false, false, false);
+ headerSearchOptions.AddPath("/usr/include/c++/4.3", clang::frontend::Angled, false, false, false);*/
+ // </Warning!!> -- End of Platform Specific Code
+
+ targetOptions.Triple = llvm::sys::getHostTriple();
+ pTargetInfo = clang::TargetInfo::CreateTargetInfo(*diagnostic, targetOptions);
+ clang::ApplyHeaderSearchOptions( headerSearch, headerSearchOptions, languageOptions, pTargetInfo->getTriple());
+ preprocessor = new clang::Preprocessor(*diagnostic, languageOptions, *pTargetInfo, *sourceManager, headerSearch);
+ clang::InitializePreprocessor(*preprocessor, preprocessorOptions, headerSearchOptions, frontendOptions);
+ const clang::FileEntry *pFile = fileManager.getFile(filename);
+ sourceManager->createMainFileID(pFile);
+ //preprocessor.EnterMainSourceFile();
+
+ clang::TargetInfo &targetInfo = *pTargetInfo;
+
+ idTable = new clang::IdentifierTable(languageOptions);
+
+ builtinContext = new clang::Builtin::Context(targetInfo);
+ astContext_ = new clang::ASTContext(languageOptions, *sourceManager, targetInfo, *idTable, selTable, *builtinContext, 0);
+ astConsumer_ = new Chill_ASTConsumer();
+ clang::Sema sema(*preprocessor, *astContext_, *astConsumer_);
+ sema.Initialize();
+ clang::ParseAST(*preprocessor, astConsumer_, *astContext_);
+}
+#endif
+
+
+IR_clangCode_Global_Init::~IR_clangCode_Global_Init()
+{
+ /*
+ delete pTextDiagnosticPrinter;
+ delete diagnostic;
+ delete sourceManager;
+ delete preprocessor;
+ delete idTable;
+ delete builtinContext;
+ delete astContext_;
+ delete astConsumer_;
+ */
+}
+
+
+
+// ----------------------------------------------------------------------------
+// Class: IR_clangCode
+// ----------------------------------------------------------------------------
+
+IR_clangCode::IR_clangCode(const char *fname, char *proc_name): IR_Code() {
+ fprintf(stderr, "\nIR_xxxxCode::IR_xxxxCode()\n\n");
+ //fprintf(stderr, "IR_clangCode::IR_clangCode( filename %s, procedure %s )\n", filename, proc_name);
+
+ filename = strdup(fname); // filename is internal to IR_clangCode
+ procedurename = strdup(proc_name);
+
+ int argc = 2;
+ char *argv[2];
+ argv[0] = "chill";
+ argv[1] = strdup(filename);
+
+ // use clang to parse the input file ? (or is that already done?)
+ //fprintf(stderr, "IR_clangCode::IR_clangCode(), parsing input file %s\n", argv[1]);
+
+ // this causes opening and parsing of the file.
+ // this is the only call to Instance that has an argument list or file name
+ IR_clangCode_Global_Init *pInstance = IR_clangCode_Global_Init::Instance(argv);
+
+ if(pInstance) {
+
+ aClangCompiler *Clang = pInstance->ClangCompiler;
+ //fprintf(stderr, "Clang is 0x%x\n", Clang);
+
+ //fprintf(stderr, "want to get pointer to clang ast for procedure %s\n", proc_name);
+ pInstance->setCurrentFunction( NULL ); // we have no function AST yet
+
+ entire_file_AST = Clang->entire_file_AST; // ugly that same name, different classes
+ chillAST_FunctionDecl *localFD = Clang->findprocedurebyname( proc_name ); // stored locally
+ //fprintf(stderr, "back from findprocedurebyname( %s )\n", proc_name );
+ //localFD->print();
+
+ pInstance->setCurrentFunction( localFD );
+
+ chillAST_node *b = localFD->getBody(); // we do this just because it will get done next
+ fprintf(stderr, "in IR_xxxxCode::IR_xxxxCode(), new CG_xxxxBuilder\n");
+
+ fprintf(stderr, "ir_clang.cc calling new CG_chillBuilder() umwut?\n");
+ ocg_ = new omega::CG_chillBuilder(); // ocg == omega code gen
+ chillfunc = localFD;
+
+ }
+
+ fprintf(stderr, "IR_xxxxCode::IR_xxxxCode() returning after reading source file and finding function\n\n");
+
+ //chillfunc->dump( 0, stderr);
+
+}
+
+
+IR_clangCode::~IR_clangCode() {
+ //func_->print(llvm::outs(), 4); // printing as part of the destructor !!
+ fprintf(stderr, "IR_xxxxCode::~IR_xxxxCode()\noutput happening as part of the destructor !!\n");
+ //chillfunc->dump();
+ //chillfunc->print();
+
+ //fprintf(stderr, "Constant Folding before\n");
+ //chillfunc->print();
+ chillfunc->constantFold();
+ //fprintf(stderr, "\nConstant Folding after\n");
+ //chillfunc->print();
+
+ chillfunc->cleanUpVarDecls();
+
+ //chillfunc->dump();
+
+ // TODO should output the entire file, not just the function we're working on
+ chillAST_SourceFile *src = chillfunc->getSourceFile();
+ //chillAST_node *p = chillfunc->parent; // should be translationDeclUnit
+ if (src) {
+ //src->print(); // tmp
+ if (src->isSourceFile()) src->printToFile( );
+ }
+}
+
+
+
+
+
+//TODO
+IR_ScalarSymbol *IR_clangCode::CreateScalarSymbol(const IR_Symbol *sym, int i) {
+ //fprintf(stderr, "IR_clangCode::CreateScalarSymbol()\n");
+ if (typeid(*sym) == typeid( IR_chillScalarSymbol ) ) { // should be the case ???
+ fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from a scalar symbol\n");
+ //fprintf(stderr, "(typeid(*sym) == typeid( IR_chillScalarSymbol )\n");
+ const IR_chillScalarSymbol *CSS = (IR_chillScalarSymbol*) sym;
+ chillAST_VarDecl *vd = CSS->chillvd;
+
+ // do we have to check to see if it's already there?
+ VariableDeclarations.push_back(vd);
+ chillAST_node *bod = chillfunc->getBody(); // always a compoundStmt ??
+ bod->insertChild(0, vd);
+ fprintf(stderr, "returning ... really\n");
+ return new IR_chillScalarSymbol( this, CSS->chillvd); // CSS->clone();
+ }
+
+ // ??
+ if (typeid(*sym) == typeid( IR_chillArraySymbol ) ) {
+ fprintf(stderr, "IR_xxxxCode::CreateScalarSymbol() from an array symbol?\n");
+ const IR_chillArraySymbol *CAS = (IR_chillArraySymbol*) sym;
+ //fprintf(stderr, "CAS 0x%x chillvd = 0x%x\n", CAS, CAS->chillvd);
+ //fprintf(stderr, "\nthis is the SYMBOL?: \n");
+ //CAS->print();
+ //CAS->dump();
+
+ chillAST_VarDecl *vd = CAS->chillvd;
+ //fprintf(stderr, "\nthis is the var decl?: ");
+ //vd->print(); printf("\n");
+ //vd->dump(); printf("\n\n");
+ fflush(stdout);
+
+ // figure out the base type (probably float) of the array
+ char *basetype = vd->underlyingtype;
+ fprintf(stderr, "scalar will be of type SgType%s\n", basetype);
+
+ char tmpname[128];
+ sprintf(tmpname, "newVariable%i\0", vd->chill_scalar_counter++);
+ chillAST_VarDecl * scalarvd = new chillAST_VarDecl( basetype, tmpname, "", NULL); // TODO parent
+ scalarvd->print(); printf("\n"); fflush(stdout);
+
+ fprintf(stderr, "VarDecl has parent that is a NULL\n");
+
+ return (IR_ScalarSymbol *) (new IR_chillScalarSymbol( this, scalarvd)); // CSS->clone();
+ }
+
+ fprintf(stderr, "IR_clangCode::CreateScalarSymbol(), passed a sym that is not a clang scalar symbol OR an array symbol???\n");
+ int *n = NULL;
+ n[0] = 1;
+ exit(-1);
+ return NULL;
+}
+
+
+IR_ArraySymbol *IR_clangCode::CreateArraySymbol(const IR_Symbol *sym, std::vector<omega::CG_outputRepr *> &size, int i) {
+ fprintf(stderr, "IR_xxxxCode::CreateArraySymbol()\n");
+
+ // build a new array name
+ char namestring[128];
+
+ sprintf(namestring, "_P%d\0", entire_file_AST->chill_array_counter++);
+ fprintf(stderr, "creating Array %s\n", namestring);
+
+ char arraypart[100];
+ char *s = &arraypart[0];
+
+ for (int i=0; i<size.size(); i++) {
+ omega::CG_outputRepr *OR = size[i];
+ CG_chillRepr * CR = (CG_chillRepr * ) OR;
+ //fprintf(stderr, "%d chillnodes\n", CR->chillnodes.size());
+
+ // this SHOULD be 1 chillnode of type IntegerLiteral (per dimension)
+ int numnodes = CR->chillnodes.size();
+ if (1 != numnodes) {
+ fprintf(stderr,
+ "IR_clangCode::CreateArraySymbol() array dimension %d has %d chillnodes\n",
+ i, numnodes );
+ exit(-1);
+ }
+
+ chillAST_node *nodezero = CR->chillnodes[0];
+ if (!nodezero->isIntegerLiteral()) {
+ fprintf(stderr, "IR_clangCode::CreateArraySymbol() array dimension %d not an IntegerLiteral\n", i);
+ exit(-1);
+ }
+
+ chillAST_IntegerLiteral *IL = (chillAST_IntegerLiteral *)nodezero;
+ int val = IL->value;
+ sprintf(s, "[%d]\0", val);
+ s = &arraypart[ strlen(arraypart) ];
+ }
+ //fprintf(stderr, "arraypart '%s'\n", arraypart);
+
+ chillAST_VarDecl *vd = new chillAST_VarDecl( "float", namestring, arraypart, NULL); // todo type from sym
+
+ // put decl in some symbol table
+ VariableDeclarations.push_back(vd);
+ // insert decl in the IR_code body
+ chillAST_node *bod = chillfunc->getBody(); // always a compoundStmt ??
+ bod->insertChild(0, vd);
+
+ return new IR_chillArraySymbol( this, vd);
+}
+
+// TODO
+std::vector<IR_ScalarRef *> IR_clangCode::FindScalarRef(const omega::CG_outputRepr *repr) const {
+ std::vector<IR_ScalarRef *> scalars;
+ fprintf(stderr, "IR_clangCode::FindScalarRef() DIE\n"); exit(-1);
+ return scalars;
+}
+
+
+
+IR_ScalarRef *IR_clangCode::CreateScalarRef(const IR_ScalarSymbol *sym) {
+ //fprintf(stderr, "\n***** ir_clang.cc IR_clangCode::CreateScalarRef( sym %s )\n", sym->name().c_str());
+ //DeclRefExpr *de = new (vd->getASTContext())DeclRefExpr(static_cast<ValueDecl*>(vd), vd->getType(), SourceLocation());
+ //fprintf(stderr, "sym 0x%x\n", sym);
+
+ IR_chillScalarRef *sr = new IR_chillScalarRef(this, buildDeclRefExpr(((IR_chillScalarSymbol*)sym)->chillvd)); // uses VarDecl to mak a declrefexpr
+ //fprintf(stderr, "returning ScalarRef with dre 0x%x\n", sr->dre);
+ return sr;
+ //return (IR_ScalarRef *)NULL;
+}
+
+
+
+IR_ArrayRef *IR_clangCode::CreateArrayRef(const IR_ArraySymbol *sym, std::vector<omega::CG_outputRepr *> &index) {
+ fprintf(stderr, "IR_clangCode::CreateArrayRef() ir_clang.cc\n");
+ fprintf(stderr, "sym->n_dim() %d index.size() %d\n", sym->n_dim(), index.size());
+
+ int t;
+ if(sym->n_dim() != index.size()) {
+ throw std::invalid_argument("incorrect array symbol dimensionality dim != size ir_clang.cc L2359");
+ }
+
+ const IR_chillArraySymbol *c_sym = static_cast<const IR_chillArraySymbol *>(sym);
+ chillAST_VarDecl *vd = c_sym->chillvd;
+ std::vector<chillAST_node *> inds;
+
+ //fprintf(stderr, "%d array indeces\n", sym->n_dim());
+ for (int i=0; i< index.size(); i++) {
+ CG_chillRepr *CR = (CG_chillRepr *)index[i];
+
+ int numnodes = CR->chillnodes.size();
+ if (1 != numnodes) {
+ fprintf(stderr,
+ "IR_clangCode::CreateArrayRef() array dimension %d has %d chillnodes\n",
+ i, numnodes );
+ exit(-1);
+ }
+
+ inds.push_back( CR->chillnodes[0] );
+
+ /*
+ chillAST_node *nodezero = CR->chillnodes[0];
+ if (!nodezero->isIntegerLiteral()) {
+ fprintf(stderr,"IR_clangCode::CreateArrayRef() array dimension %d not an IntegerLiteral\n",i);
+ fprintf(stderr, "it is a %s\n", nodezero->getTypeString());
+ nodezero->print(); printf("\n"); fflush(stdout);
+ exit(-1);
+ }
+
+ chillAST_IntegerLiteral *IL = (chillAST_IntegerLiteral *)nodezero;
+ int val = IL->value;
+ inds.push_back( val );
+ */
+ }
+
+ // now we've got the vardecl AND the indeces to make a chillAST that represents the array reference
+ // TODO Passing NULL for chillAST node?
+ chillAST_ArraySubscriptExpr *ASE = new chillAST_ArraySubscriptExpr( vd, inds, NULL);
+
+ auto ref = new IR_chillArrayRef( this, ASE, 0 );
+
+ return ref;
+}
+
+// find all array references ANYWHERE in this block of code ??
+std::vector<IR_ArrayRef *> IR_clangCode::FindArrayRef(const omega::CG_outputRepr *repr) const {
+ //fprintf(stderr, "FindArrayRef()\n");
+ std::vector<IR_ArrayRef *> arrays;
+ const omega::CG_chillRepr *crepr = static_cast<const omega::CG_chillRepr *>(repr);
+ std::vector<chillAST_node*> chillstmts = crepr->getChillCode();
+
+ //fprintf(stderr, "there are %d chill statements in this repr\n", chillstmts.size());
+
+ std::vector<chillAST_ArraySubscriptExpr*> refs;
+ for (int i=0; i<chillstmts.size(); i++) {
+ //fprintf(stderr, "\nchillstatement %d = ", i); chillstmts[i]->print(0, stderr); fprintf(stderr, "\n");
+ chillstmts[i]->gatherArrayRefs( refs, false );
+ }
+ //fprintf(stderr, "%d total refs\n", refs.size());
+ for (int i=0; i<refs.size(); i++) {
+ if (refs[i]->imreadfrom) {
+ //fprintf(stderr, "ref[%d] going to be put in TWICE, as both read and write\n", i);
+ arrays.push_back( new IR_chillArrayRef( this, refs[i], 0 ) ); // UGLY TODO dual usage of a ref in "+="
+ }
+ arrays.push_back( new IR_chillArrayRef( this, refs[i], refs[i]->imwrittento ) ); // this is wrong
+ // we need to know whether this reference will be written, etc.
+ }
+
+ /*
+ if(chillstmts.size() > 1) {
+ for(int i=0; i<tnl->size(); ++i) {
+ omega::CG_chillRepr *r = new omega::CG_chillRepr((*tnl)[i]);
+ std::vector<IR_ArrayRef *> a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ }
+ } else if(chillstmts.size() == 1) {
+ Stmt *s = (*tnl)[0];
+
+ if(CompoundStmt *cs = dyn_cast<CompoundStmt>(s)) {
+ for(CompoundStmt::body_iterator bi = cs->body_begin(); bi != cs->body_end(); ++bi) {
+ omega::CG_chillRepr *r = new omega::CG_chillRepr(*bi);
+ std::vector<IR_ArrayRef *> a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ }
+ } else if(ForStmt *fs = dyn_cast<ForStmt>(s)) {
+ omega::CG_chillRepr *r = new omega::CG_chillRepr(fs->getBody());
+ std::vector<IR_ArrayRef *> a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ } else if(IfStmt *ifs = dyn_cast<IfStmt>(s)) {
+ omega::CG_chillRepr *r = new omega::CG_chillRepr(ifs->getCond());
+ std::vector<IR_ArrayRef *> a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ r = new omega::CG_chillRepr(ifs->getThen());
+ a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ if(Stmt *s_else = ifs->getElse()) {
+ r = new omega::CG_chillRepr(s_else);
+ a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ }
+ } else if(Expr *e = dyn_cast<Expr>(s)) {
+ omega::CG_chillRepr *r = new omega::CG_chillRepr(static_cast<Expr*>(s));
+ std::vector<IR_ArrayRef *> a = FindArrayRef(r);
+ delete r;
+ std::copy(a.begin(), a.end(), back_inserter(arrays));
+ } else throw ir_error("control structure not supported");
+ }
+ */
+/*
+ else { // We have an expression
+ Expr *op = static_cast<const omega::CG_chillRepr *>(repr)->GetExpression();
+ if(0) { // TODO: Handle pointer reference exp. here
+ } else if(BinaryOperator *bop = dyn_cast<BinaryOperator>(op)) {
+ omega::CG_chillRepr *r1 = new omega::CG_chillRepr(bop->getLHS());
+ std::vector<IR_ArrayRef *> a1 = FindArrayRef(r1);
+ delete r1;
+ std::copy(a1.begin(), a1.end(), back_inserter(arrays));
+ omega::CG_chillRepr *r2 = new omega::CG_chillRepr(bop->getRHS());
+ std::vector<IR_ArrayRef *> a2 = FindArrayRef(r2);
+ delete r2;
+ std::copy(a2.begin(), a2.end(), back_inserter(arrays));
+ } else if(UnaryOperator *uop = dyn_cast<UnaryOperator>(op)) {
+ omega::CG_chillRepr *r1 = new omega::CG_chillRepr(uop->getSubExpr());
+ std::vector<IR_ArrayRef *> a1 = FindArrayRef(r1);
+ delete r1;
+ std::copy(a1.begin(), a1.end(), back_inserter(arrays));
+ } //else throw ir_error("Invalid expr. type passed to FindArrayRef");
+ }
+ */
+ return arrays;
+}
+
+
+std::vector<IR_Control *> IR_clangCode::FindOneLevelControlStructure(const IR_Block *block) const {
+ fprintf(stderr, "IR_xxxxCode::FindOneLevelControlStructure()\n");
+ const IR_chillBlock *CB = (const IR_chillBlock *) block;
+ //fprintf(stderr, "block 0x%x\n", block);
+
+ std::vector<IR_Control *> controls;
+
+ chillAST_node *blockast = CB->chillAST;
+ //fprintf(stderr, "blockast 0x%x\n", blockast);
+ if (blockast == NULL) {
+ int numstmts = CB->statements.size();
+ fprintf(stderr, "%d statements\n", numstmts);
+
+ if (numstmts == 0) return controls;
+
+ else if (numstmts == 1) blockast = CB->statements[0]; // a single statement
+
+ else {
+ fprintf(stderr, "IR_xxxBlock is dumb, with multiple ways to hold statements\n");
+ exit(-1); // TODO FIX
+ }
+ }
+
+ //fprintf(stderr, "block's AST is of type %s\n", blockast->getTypeString());
+ //blockast->print(); printf("\n\n"); fflush(stdout);
+
+
+ //vector<chillAST_node *> funcchildren = chillfunc->getChildren();
+ //fprintf(stderr, "%d children of clangcode\n", funcchildren.size()); // includes parameters
+
+ // build up a vector of "controls".
+ // a run of straight-line code (statements that can't cause branching) will be
+ // bundled up into an IR_Block
+ // ifs and loops will get their own entry
+
+ std::vector<chillAST_node *> children;
+
+
+ if (blockast->asttype == CHILLAST_NODETYPE_FORSTMT) { fflush(stdout);
+ fprintf(stderr, "found a top level For statement (Loop)\n");
+ fprintf(stderr, "For Stmt (loop) is:\n");
+ blockast->print();
+ fprintf(stderr, "pushing the loop at TOP\n");
+
+ controls.push_back( new IR_chillLoop( this, (chillAST_ForStmt *)blockast));
+ }
+ //else if (blockast->asttype == CHILLAST_NODETYPE_IFSTMT) {
+ // controls.push_back( new IR_clangIf( this, (chillAST_IfStmt *)blockast));
+ //}
+ else if (blockast->asttype == CHILLAST_NODETYPE_COMPOUNDSTMT ||
+ blockast->asttype == CHILLAST_NODETYPE_FUNCTIONDECL) {
+
+ if (blockast->asttype == CHILLAST_NODETYPE_FUNCTIONDECL) {
+ //fprintf(stderr, "ir_clanc.cc blockast->asttype == CHILLAST_NODETYPE_FUNCTIONDECL\n");
+
+ chillAST_FunctionDecl *FD = (chillAST_FunctionDecl *)blockast;
+ chillAST_node *bod = FD->getBody();
+ //fprintf(stderr, "bod 0x%x\n", bod);
+
+ children = bod->getChildren();
+
+ //fprintf(stderr, "FunctionDecl body is of type %s\n", bod->getTypeString());
+ //fprintf(stderr, "found a top level FunctionDecl (Basic Block)\n");
+ //fprintf(stderr, "basic block has %d statements\n", children.size() );
+ //fprintf(stderr, "basic block is:\n");
+ //bod->print();
+ }
+ else /* CompoundStmt */ {
+ //fprintf(stderr, "found a top level Basic Block\n");
+ children = blockast->getChildren();
+ }
+
+ int numchildren = children.size();
+ //fprintf(stderr, "basic block has %d statements\n", numchildren);
+ //fprintf(stderr, "basic block is:\n");
+ //fprintf(stderr, "{\n");
+ //blockast->print();
+ //fprintf(stderr, "}\n");
+
+ int ns;
+ IR_chillBlock *basicblock = new IR_chillBlock(this); // no statements
+ for (int i=0; i<numchildren; i++) {
+ //fprintf(stderr, "child %d is of type %s\n", i, children[i]->getTypeString());
+ CHILL_ASTNODE_TYPE typ = children[i]->asttype;
+ if (typ == CHILLAST_NODETYPE_LOOP) {
+ if (numchildren == 1) {
+ fprintf(stderr, "found a For statement (Loop)\n");
+ }
+ else {
+ fprintf(stderr, "found a For statement (Loop) at %d within a Basic Block\n", i);
+ }
+ //children[i]->print(); printf("\n"); fflush(stdout);
+
+ ns = basicblock->numstatements();
+ if (ns) {
+ fprintf(stderr, "pushing a run of statements %d to %d as a block\n", i-ns, i-1);
+ controls.push_back( basicblock );
+ basicblock = new IR_chillBlock(this); // start a new one
+ }
+
+ //fprintf(stderr, "pushing the loop at %d\n", i);
+ controls.push_back( new IR_chillLoop(this, (chillAST_ForStmt *)children[i] ));
+
+ }
+ //else if (typ == CHILLAST_NODETYPE_IFSTMT ) // TODO
+ else { // straight line code
+ //fprintf(stderr, "straight line code\n");
+ basicblock->addStatement( children[i] );
+ //fprintf(stderr, "child %d = \n", i); children[i]->print(); printf("\n"); fflush(stdout);
+ //fprintf(stderr, "child %d is part of a basic block\n", i);
+ }
+ } // for each child
+ ns = basicblock->numstatements();
+ //fprintf(stderr, "ns %d\n", ns);
+ if (ns != 0 ) {
+ if (ns != numchildren) {
+ //fprintf(stderr, "end of body ends the run of %d statements in the Basic Block\n", ns);
+ controls.push_back( basicblock );
+ }
+ else {
+ //fprintf(stderr, "NOT sending straightline run of statements, because it would be the entire block. There are no control statements in the block\n");
+ }
+ }
+ //else fprintf(stderr, "NOT sending the last run of %d statements\n", ns);
+
+ }
+ else {
+ fprintf(stderr, "IR_clangCode::FindOneLevelControlStructure(), block is a %s???\n", blockast->getTypeString());
+ exit(-1);
+ }
+
+ fprintf(stderr, "returning vector of %d controls\n", controls.size() );
+ return controls;
+}
+
+
+IR_Block *IR_clangCode::MergeNeighboringControlStructures(const std::vector<IR_Control *> &controls) const {
+ fprintf(stderr, "IR_xxxxCode::MergeNeighboringControlStructures %d controls\n", controls.size());
+
+ if (controls.size() == 0)
+ return NULL;
+
+ IR_chillBlock *CBlock = new IR_chillBlock(controls[0]->ir_); // the thing we're building
+
+ std::vector<chillAST_node*> statements;
+ chillAST_node *parent = NULL;
+ for (int i = 0; i < controls.size(); i++) {
+ switch (controls[i]->type()) {
+ case IR_CONTROL_LOOP: {
+ fprintf(stderr, "control %d is IR_CONTROL_LOOP\n", i);
+ chillAST_ForStmt *loop = static_cast<IR_chillLoop *>(controls[i])->chillforstmt;
+ if (parent == NULL) {
+ parent = loop->parent;
+ } else {
+ if (parent != loop->parent) {
+ throw ir_error("controls to merge not at the same level");
+ }
+ }
+ CBlock->addStatement( loop );
+ break;
+ }
+ case IR_CONTROL_BLOCK: {
+ fprintf(stderr, "control %d is IR_CONTROL_BLOCK\n", i);
+ IR_chillBlock *CB = static_cast<IR_chillBlock*>(controls[i]);
+ std::vector<chillAST_node*> blockstmts = CB->statements;
+ if (statements.size() != 0) {
+ for (int j=0; j< blockstmts.size(); j++) {
+ if (parent == NULL) {
+ parent = blockstmts[j]->parent;
+ }
+ else {
+ if (parent != blockstmts[j]->parent) {
+ throw ir_error("ir_clang.cc IR_clangCode::MergeNeighboringControlStructures controls to merge not at the same level");
+ }
+ }
+ CBlock->addStatement( blockstmts[j] );
+ }
+ }
+ else {
+ if (CB->chillAST) CBlock->addStatement(CBlock->chillAST); // if this is a block, add theblock's statements?
+ else { // should never happen
+ fprintf(stderr, "WARNING: ir_clang.cc IR_clangCode::MergeNeighboringControlStructures");
+ fprintf(stderr, " empty IR_CONTROL_BLOCK \n");
+ }
+ }
+ break;
+ }
+ default:
+ throw ir_error("unrecognized control to merge");
+ }
+ } // for each control
+
+ return CBlock;
+}
+
+
+IR_Block *IR_clangCode::GetCode() const { // return IR_Block corresponding to current function?
+ //fprintf(stderr, "IR_clangCode::GetCode()\n");
+ //Stmt *s = func_->getBody(); // clang statement, and clang getBody
+ //fprintf(stderr, "chillfunc 0x%x\n", chillfunc);
+
+ //chillAST_node *bod = chillfunc->getBody(); // chillAST
+ //fprintf(stderr, "printing the function getBody()\n");
+ //fprintf(stderr, "sourceManager 0x%x\n", sourceManager);
+ //bod->print();
+
+ return new IR_chillBlock(this, chillfunc ) ;
+}
+
+
+void IR_clangCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) {
+ fflush(stdout);
+ fprintf(stderr, "IR_xxxxCode::ReplaceCode( old, *repr)\n");
+
+ CG_chillRepr *chillrepr = (CG_chillRepr *) repr;
+ std::vector<chillAST_node*> newcode = chillrepr->getChillCode();
+ int numnew = newcode.size();
+
+ //fprintf(stderr, "new code (%d) is\n", numnew);
+ //for (int i=0; i<numnew; i++) {
+ // newcode[i]->print(0, stderr);
+ // fprintf(stderr, "\n");
+ //}
+
+ struct IR_chillLoop* cloop;
+
+ std::vector<chillAST_VarDecl*> olddecls;
+ chillfunc->gatherVarDecls( olddecls );
+ //fprintf(stderr, "\n%d old decls they are:\n", olddecls.size());
+ //for (int i=0; i<olddecls.size(); i++) {
+ // fprintf(stderr, "olddecl[%d] ox%x ",i, olddecls[i]);
+ // olddecls[i]->print(); printf("\n"); fflush(stdout);
+ //}
+
+
+ //fprintf(stderr, "num new stmts %d\n", numnew);
+ //fprintf(stderr, "new code we're look for decls in:\n");
+ std::vector<chillAST_VarDecl*> decls;
+ for (int i=0; i<numnew; i++) {
+ //newcode[i]->print(0,stderr);
+ //fprintf(stderr, "\n");
+ newcode[i]->gatherVarUsage( decls );
+ }
+
+ //fprintf(stderr, "\n%d new vars used they are:\n", decls.size());
+ //for (int i=0; i<decls.size(); i++) {
+ // fprintf(stderr, "decl[%d] ox%x ",i, decls[i]);
+ // decls[i]->print(); printf("\n"); fflush(stdout);
+ //}
+
+
+ for (int i=0; i<decls.size(); i++) {
+ //fprintf(stderr, "\nchecking "); decls[i]->print(); printf("\n"); fflush(stdout);
+ int inthere = 0;
+ for (int j=0; j<VariableDeclarations.size(); j++) {
+ if (VariableDeclarations[j] == decls[i]) {
+ //fprintf(stderr, "it's in the Variable Declarations()\n");
+ }
+ }
+ for (int j=0; j<olddecls.size(); j++) {
+ if (decls[i] == olddecls[j]) {
+ //fprintf(stderr, "it's in the olddecls (exactly)\n");
+ inthere = 1;
+ }
+ if (streq(decls[i]->varname, olddecls[j]->varname)) {
+ if (streq(decls[i]->arraypart, olddecls[j]->arraypart)) {
+ //fprintf(stderr, "it's in the olddecls (INEXACTLY)\n");
+ inthere = 1;
+ }
+ }
+ }
+ if (!inthere) {
+ //fprintf(stderr, "inserting decl[%d] for ",i); decls[i]->print(); printf("\n");fflush(stdout);
+ chillfunc->getBody()->insertChild(0, decls[i]);
+ olddecls.push_back( decls[i] );
+ }
+ }
+
+ chillAST_node *par;
+ switch (old->type()) {
+ case IR_CONTROL_LOOP:
+ {
+ //fprintf(stderr, "old is IR_CONTROL_LOOP\n");
+ cloop = (struct IR_chillLoop* )old;
+ chillAST_ForStmt *forstmt = cloop->chillforstmt;
+
+ fprintf(stderr, "old was\n");
+ forstmt->print(); printf("\n"); fflush(stdout);
+
+ //fprintf(stderr, "\nnew code is\n");
+ //for (int i=0; i<numnew; i++) { newcode[i]->print(); printf("\n"); }
+ //fflush(stdout);
+
+
+ par = forstmt->parent;
+ if (!par) {
+ fprintf(stderr, "old parent was NULL\n");
+ fprintf(stderr, "ir_clang.cc that will not work very well.\n");
+ exit(-1);
+ }
+
+
+
+ fprintf(stderr, "\nold parent was\n\n{\n");
+ par->print(); printf("\n"); fflush(stdout);
+ fprintf(stderr, "\n}\n");
+
+ std::vector<chillAST_node*> oldparentcode = par->getChildren(); // probably only works for compoundstmts
+ //fprintf(stderr, "ir_clang.cc oldparentcode\n");
+
+ // find loop in the parent
+ int index = -1;
+ int numstatements = oldparentcode.size();
+ for (int i=0; i<numstatements; i++) if (oldparentcode[i] == forstmt) { index = i; }
+ if (index == -1) {
+ fprintf(stderr, "ir_clang.cc can't find the loop in its parent\n");
+ exit(-1);
+ }
+ //fprintf(stderr, "loop is index %d\n", index);
+
+ // insert the new code
+ par->setChild(index, newcode[0]); // overwrite old stmt
+ //fprintf(stderr, "inserting %s 0x%x as index %d of 0x%x\n", newcode[0]->getTypeString(), newcode[0], index, par);
+ // do we need to update the IR_cloop?
+ cloop->chillforstmt = (chillAST_ForStmt*) newcode[0]; // ?? DFL
+
+
+
+ //printf("inserting "); newcode[0]->print(); printf("\n");
+ if (numnew > 1){
+ //oldparentcode.insert( oldparentcode.begin()+index+1, numnew-1, NULL); // allocate in bulk
+
+ // add the rest of the new statements
+ for (int i=1; i<numnew; i++) {
+ printf("inserting "); newcode[i]->print(); printf("\n");
+ par->insertChild( index+i, newcode[i] ); // sets parent
+ }
+ }
+
+ // TODO add in (insert) variable declarations that go with the new loops
+
+
+ fflush(stdout);
+ }
+ break;
+ case IR_CONTROL_BLOCK:
+ fprintf(stderr, "old is IR_CONTROL_BLOCK\n");
+ fprintf(stderr, "IR_clangCode::ReplaceCode() stubbed out\n");
+ exit(-1);
+ //tf_old = static_cast<IR_chillBlock *>(old)->getStmtList()[0];
+ break;
+ default:
+ throw ir_error("control structure to be replaced not supported");
+ break;
+ }
+
+ fflush(stdout);
+ //fprintf(stderr, "\nafter inserting %d statements into the Clang IR,", numnew);
+ fprintf(stderr, "\nnew parent2 is\n\n{\n");
+ std::vector<chillAST_node*> newparentcode = par->getChildren();
+ for (int i=0; i<newparentcode.size(); i++) {
+ fflush(stdout);
+ //fprintf(stderr, "%d ", i);
+ newparentcode[i]->print(); printf(";\n"); fflush(stdout);
+ }
+
+
+
+ fprintf(stderr, "}\n");
+
+}
+
+
+
+
+void IR_clangCode::ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr) {
+ fprintf(stderr, "IR_xxxxCode::ReplaceExpression()\n");
+
+ if (typeid(*old) == typeid(IR_chillArrayRef)) {
+ //fprintf(stderr, "expressions is IR_chillArrayRef\n");
+ IR_chillArrayRef *CAR = (IR_chillArrayRef *)old;
+ chillAST_ArraySubscriptExpr* CASE = CAR->chillASE;
+ printf("\nreplacing old "); CASE->print(); printf("\n"); fflush(stdout);
+
+ omega::CG_chillRepr *crepr = (omega::CG_chillRepr *)repr;
+ if (crepr->chillnodes.size() != 1) {
+ fprintf(stderr, "IR_clangCode::ReplaceExpression(), replacing with %d chillnodes???\n");
+ //exit(-1);
+ }
+
+ chillAST_node *newthing = crepr->chillnodes[0];
+ fprintf(stderr, "with new "); newthing->print(); printf("\n\n"); fflush(stdout);
+
+ if (!CASE->parent) {
+ fprintf(stderr, "IR_clangCode::ReplaceExpression() old has no parent ??\n");
+ exit(-1);
+ }
+
+ fprintf(stderr, "OLD parent = "); // of type %s\n", CASE->parent->getTypeString());
+ if (CASE->parent->isImplicitCastExpr()) CASE->parent->parent->print();
+ else CASE->parent->print();
+ printf("\n"); fflush(stdout);
+
+ //CASE->parent->print(); printf("\n"); fflush(stdout);
+ //CASE->parent->parent->print(); printf("\n"); fflush(stdout);
+ //CASE->parent->parent->print(); printf("\n"); fflush(stdout);
+ //CASE->parent->parent->parent->print(); printf("\n"); fflush(stdout);
+
+ CASE->parent->replaceChild( CASE, newthing );
+
+ fprintf(stderr, "after replace parent is "); // of type %s\n", CASE->parent->getTypeString());
+ if (CASE->parent->isImplicitCastExpr()) CASE->parent->parent->print();
+ else CASE->parent->print();
+ printf("\n\n"); fflush(stdout);
+
+
+
+ //CASE->parent->print(); printf("\n"); fflush(stdout);
+ //CASE->parent->parent->print(); printf("\n"); fflush(stdout);
+ //CASE->parent->parent->print(); printf("\n"); fflush(stdout);
+ //CASE->parent->parent->parent->print(); printf("\n"); fflush(stdout);
+
+
+ }
+ else if (typeid(*old) == typeid(IR_chillScalarRef)) {
+ fprintf(stderr, "IR_clangCode::ReplaceExpression() IR_chillScalarRef unhandled\n");
+ }
+ else {
+ fprintf(stderr, "UNKNOWN KIND OF REF\n"); exit(-1);
+ }
+
+ delete old;
+}
+
+
+// TODO
+IR_CONDITION_TYPE IR_clangCode::QueryBooleanExpOperation(const omega::CG_outputRepr *repr) const {
+ return IR_COND_UNKNOWN;
+}
+
+
+
+IR_OPERATION_TYPE IR_clangCode::QueryExpOperation(const omega::CG_outputRepr *repr) const {
+ //fprintf(stderr, "IR_clangCode::QueryExpOperation()\n");
+
+ CG_chillRepr *crepr = (CG_chillRepr *) repr;
+ chillAST_node *node = crepr->chillnodes[0];
+ //fprintf(stderr, "chillAST node type %s\n", node->getTypeString());
+
+ // really need to be more rigorous than this hack // TODO
+ if (node->isImplicitCastExpr()) node = ((chillAST_ImplicitCastExpr*)node)->subexpr;
+ if (node->isCStyleCastExpr()) node = ((chillAST_CStyleCastExpr*) node)->subexpr;
+ if (node->isParenExpr()) node = ((chillAST_ParenExpr*) node)->subexpr;
+
+ if (node->isIntegerLiteral() || node->isFloatingLiteral()) return IR_OP_CONSTANT;
+ else if (node->isBinaryOperator() || node->isUnaryOperator()) {
+ char *opstring;
+ if (node->isBinaryOperator())
+ opstring= ((chillAST_BinaryOperator*)node)->op; // TODO enum
+ else
+ opstring= ((chillAST_UnaryOperator*)node)->op; // TODO enum
+
+ if (!strcmp(opstring, "+")) return IR_OP_PLUS;
+ if (!strcmp(opstring, "-")) return IR_OP_MINUS;
+ if (!strcmp(opstring, "*")) return IR_OP_MULTIPLY;
+ if (!strcmp(opstring, "/")) return IR_OP_DIVIDE;
+ if (!strcmp(opstring, "=")) return IR_OP_ASSIGNMENT;
+
+ fprintf(stderr, "ir_clang.cc IR_clangCode::QueryExpOperation() UNHANDLED Binary(or Unary)Operator op type (%s)\n", opstring);
+ exit(-1);
+ }
+ else if (node->isDeclRefExpr() ) return IR_OP_VARIABLE; // ??
+ //else if (node->is ) return something;
+ else {
+ fprintf(stderr, "IR_clangCode::QueryExpOperation() UNHANDLED NODE TYPE %s\n", node->getTypeString());
+ exit(-1);
+ }
+
+ /* CLANG
+ Expr *e = static_cast<const omega::CG_chillRepr *>(repr)->GetExpression();
+ if(isa<IntegerLiteral>(e) || isa<FloatingLiteral>(e)) return IR_OP_CONSTANT;
+ else if(isa<DeclRefExpr>(e)) return IR_OP_VARIABLE;
+ else if(BinaryOperator *bop = dyn_cast<BinaryOperator>(e)) {
+ switch(bop->getOpcode()) {
+ case BO_Assign: return IR_OP_ASSIGNMENT;
+ case BO_Add: return IR_OP_PLUS;
+ case BO_Sub: return IR_OP_MINUS;
+ case BO_Mul: return IR_OP_MULTIPLY;
+ case BO_Div: return IR_OP_DIVIDE;
+ default: return IR_OP_UNKNOWN;
+ }
+ } else if(UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
+ switch(uop->getOpcode()) {
+ case UO_Minus: return IR_OP_NEGATIVE;
+ case UO_Plus: return IR_OP_POSITIVE;
+ default: return IR_OP_UNKNOWN;
+ }
+ } else if(ConditionalOperator *cop = dyn_cast<ConditionalOperator>(e)) {
+ BinaryOperator *bop;
+ if(bop = dyn_cast<BinaryOperator>(cop->getCond())) {
+ if(bop->getOpcode() == BO_GT) return IR_OP_MAX;
+ else if(bop->getOpcode() == BO_LT) return IR_OP_MIN;
+ } else return IR_OP_UNKNOWN;
+
+ }
+
+ else if(e == NULL) return IR_OP_NULL;
+ else return IR_OP_UNKNOWN;
+ }
+ END CLANG */
+}
+
+
+std::vector<omega::CG_outputRepr *> IR_clangCode::QueryExpOperand(const omega::CG_outputRepr *repr) const {
+ //fprintf(stderr, "IR_clangCode::QueryExpOperand()\n");
+ std::vector<omega::CG_outputRepr *> v;
+
+ CG_chillRepr *crepr = (CG_chillRepr *) repr;
+ //Expr *e = static_cast<const omega::CG_chillRepr *>(repr)->GetExpression(); wrong.. CLANG
+ chillAST_node *e = crepr->chillnodes[0]; // ??
+ //e->print(); printf("\n"); fflush(stdout);
+
+ // really need to be more rigorous than this hack // TODO
+ if (e->isImplicitCastExpr()) e = ((chillAST_ImplicitCastExpr*)e)->subexpr;
+ if (e->isCStyleCastExpr()) e = ((chillAST_CStyleCastExpr*) e)->subexpr;
+ if (e->isParenExpr()) e = ((chillAST_ParenExpr*) e)->subexpr;
+
+
+ //if(isa<IntegerLiteral>(e) || isa<FloatingLiteral>(e) || isa<DeclRefExpr>(e)) {
+ if (e->isIntegerLiteral() || e->isFloatingLiteral() || e->isDeclRefExpr() ) {
+ //fprintf(stderr, "it's a constant\n");
+ omega::CG_chillRepr *repr = new omega::CG_chillRepr(e);
+ v.push_back(repr);
+ //} else if(BinaryOperator *bop = dyn_cast<BinaryOperator>(e)) {
+ } else if (e->isBinaryOperator()) {
+ //fprintf(stderr, "ir_clang.cc BOP TODO\n"); exit(-1); //
+ chillAST_BinaryOperator *bop = (chillAST_BinaryOperator*)e;
+ char *op = bop->op; // TODO enum for operator types
+ if (streq(op, "=")) {
+ v.push_back(new omega::CG_chillRepr( bop->rhs )); // for assign, return RHS
+ }
+ else if (streq(op, "+") || streq(op, "-") || streq(op, "*") || streq(op, "/") ) {
+ v.push_back(new omega::CG_chillRepr( bop->lhs )); // for +*-/ return both lhs and rhs
+ v.push_back(new omega::CG_chillRepr( bop->rhs ));
+ }
+ else {
+ fprintf(stderr, "ir_clang.cc IR_clangCode::QueryExpOperand() Binary Operator UNHANDLED op (%s)\n", op);
+ exit(-1);
+ }
+ } // BinaryOperator
+ else if (e->isUnaryOperator()) {
+ omega::CG_chillRepr *repr;
+ chillAST_UnaryOperator *uop = (chillAST_UnaryOperator*)e;
+ char *op = uop->op; // TODO enum
+ if (streq(op, "+") || streq(op, "-")) {
+ v.push_back( new omega::CG_chillRepr( uop->subexpr ));
+ }
+ else {
+ fprintf(stderr, "ir_clang.cc IR_clangCode::QueryExpOperand() Unary Operator UNHANDLED op (%s)\n", op);
+ exit(-1);
+ }
+ } // unaryoperator
+ else {
+ fprintf(stderr, "ir_clang.cc IR_clangCode::QueryExpOperand() UNHANDLED node type %s\n", e->getTypeString());
+ exit(-1);
+ }
+
+
+ /*
+ Expr *op1, *op2;
+ switch(bop->getOpcode()) {
+ case BO_Assign:
+ op2 = bop->getRHS();
+ repr = new omega::CG_chillRepr(op2);
+ v.push_back(repr);
+ break;
+ case BO_Add:
+ case BO_Sub:
+ case BO_Mul:
+ case BO_Div:
+ op1 = bop->getLHS();
+ repr = new omega::CG_chillRepr(op1);
+ v.push_back(repr);
+ op2 = bop->getRHS();
+ repr = new omega::CG_chillRepr(op2);
+ v.push_back(repr);
+ break;
+ default:
+ throw ir_error("operation not supported");
+ }
+ */
+ //} else if(UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
+ //} else if(e->isUnaryOperator()) {
+ /*
+ omega::CG_chillRepr *repr;
+
+ switch(uop->getOpcode()) {
+ case UO_Minus:
+ case UO_Plus:
+ op1 = uop->getSubExpr();
+ repr = new omega::CG_chillRepr(op1);
+ v.push_back(repr);
+ break;
+ default:
+ throw ir_error("operation not supported");
+ }
+ */
+ //} else if(ConditionalOperator *cop = dyn_cast<ConditionalOperator>(e)) {
+ //omega::CG_chillRepr *repr;
+
+ // TODO: Handle conditional operator here
+ //} else throw ir_error("operand type UNsupported");
+
+ return v;
+}
+
+IR_Ref *IR_clangCode::Repr2Ref(const omega::CG_outputRepr *repr) const {
+ CG_chillRepr *crepr = (CG_chillRepr *) repr;
+ chillAST_node *node = crepr->chillnodes[0];
+
+ //Expr *e = static_cast<const omega::CG_chillRep *>(repr)->GetExpression();
+
+ if(node->isIntegerLiteral()) {
+ // FIXME: Not sure if it'll work in all cases (long?)
+ int val = ((chillAST_IntegerLiteral*)node)->value;
+ return new IR_chillConstantRef(this, static_cast<omega::coef_t>(val) );
+ } else if(node->isFloatingLiteral()) {
+ float val = ((chillAST_FloatingLiteral*)node)->value;
+ return new IR_chillConstantRef(this, val );
+ } else if(node->isDeclRefExpr()) {
+ //fprintf(stderr, "ir_clang.cc IR_clangCode::Repr2Ref() declrefexpr TODO\n"); exit(-1);
+ return new IR_chillScalarRef(this, (chillAST_DeclRefExpr*)node); // uses DRE
+ } else {
+ fprintf(stderr, "ir_clang.cc IR_clangCode::Repr2Ref() UNHANDLED node type %s\n", node->getTypeString());
+ exit(-1);
+ //assert(0);
+ }
+}
+
+chillAST_node * ConvertMemberExpr( clang::MemberExpr *clangME , chillAST_node *) {
+ fprintf(stderr, "ConvertMemberExpr()\n");
+
+ clang::Expr *E = clangME->getBase();
+ E->dump();
+
+ chillAST_node *base = ConvertGenericClangAST( clangME->getBase(), NULL );
+
+ DeclarationNameInfo memnameinfo = clangME->getMemberNameInfo();
+ DeclarationName DN = memnameinfo.getName();
+ const char *member = DN.getAsString().c_str();
+ //fprintf(stderr, "%s\n", DN.getAsString().c_str());
+
+ chillAST_MemberExpr *ME = new chillAST_MemberExpr( base, member, NULL, clangME );
+
+ fprintf(stderr, "this is the Member Expresion\n");
+ ME->print();
+ fprintf(stderr, "\n");
+
+ return ME;
+
+}
diff --git a/src/ir_rose.cc b/src/ir_rose.cc
deleted file mode 100644
index f4039ab..0000000
--- a/src/ir_rose.cc
+++ /dev/null
@@ -1,1699 +0,0 @@
-/*****************************************************************************
- Copyright (C) 2009-2010 University of Utah
- All Rights Reserved.
-
- Purpose:
- CHiLL's rose interface.
-
- Notes:
- Array supports mixed pointer and array type in a single declaration.
-
- History:
- 02/23/2009 Created by Chun Chen.
-*****************************************************************************/
-#include <string>
-#include "ir_rose.hh"
-#include "ir_rose_utils.hh"
-#include "code_gen/rose_attributes.h"
-#include "code_gen/CG_roseRepr.h"
-#include "code_gen/CG_roseBuilder.h"
-
-using namespace SageBuilder;
-using namespace SageInterface;
-using namespace omega;
-// ----------------------------------------------------------------------------
-// Class: IR_roseScalarSymbol
-// ----------------------------------------------------------------------------
-
-std::string IR_roseScalarSymbol::name() const {
- return vs_->get_name().getString();
-}
-
-int IR_roseScalarSymbol::size() const {
- return (vs_->get_type()->memoryUsage()) / (vs_->get_type()->numberOfNodes());
-}
-
-bool IR_roseScalarSymbol::operator==(const IR_Symbol &that) const {
- if (typeid(*this) != typeid(that))
- return false;
-
- const IR_roseScalarSymbol *l_that =
- static_cast<const IR_roseScalarSymbol *>(&that);
- return this->vs_ == l_that->vs_;
-}
-
-IR_Symbol *IR_roseScalarSymbol::clone() const {
- return NULL;
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseArraySymbol
-// ----------------------------------------------------------------------------
-
-std::string IR_roseArraySymbol::name() const {
- return (vs_->get_declaration()->get_name().getString());
-}
-
-int IR_roseArraySymbol::elem_size() const {
-
- SgType *tn = vs_->get_type();
- SgType* arrType;
-
- int elemsize;
-
- if (arrType = isSgArrayType(tn)) {
- while (isSgArrayType(arrType)) {
- arrType = arrType->findBaseType();
- }
- } else if (arrType = isSgPointerType(tn)) {
- while (isSgPointerType(arrType)) {
- arrType = arrType->findBaseType();
- }
- }
-
- elemsize = (int) arrType->memoryUsage() / arrType->numberOfNodes();
- return elemsize;
-}
-
-int IR_roseArraySymbol::n_dim() const {
- int dim = 0;
- SgType* arrType = isSgArrayType(vs_->get_type());
- SgType* ptrType = isSgPointerType(vs_->get_type());
- if (arrType != NULL) {
- while (isSgArrayType(arrType)) {
- arrType = isSgArrayType(arrType)->get_base_type();
- dim++;
- }
- } else if (ptrType != NULL) {
- while (isSgPointerType(ptrType)) {
- ptrType = isSgPointerType(ptrType)->get_base_type();
- dim++;
- }
- }
-
- // Manu:: fortran support
- if (static_cast<const IR_roseCode *>(ir_)->is_fortran_) {
-
- if (arrType != NULL) {
- dim = 0;
- SgExprListExp * dimList = isSgArrayType(vs_->get_type())->get_dim_info();
- SgExpressionPtrList::iterator it = dimList->get_expressions().begin();
- for(;it != dimList->get_expressions().end(); it++) {
- dim++;
- }
- } else if (ptrType != NULL) {
- ; // not sure if this case will happen
- }
- }
-
- return dim;
-}
-
-omega::CG_outputRepr *IR_roseArraySymbol::size(int dim) const {
-
- SgArrayType* arrType = isSgArrayType(vs_->get_type());
- int count = 0;
- SgExpression* expr;
- SgType* pntrType = isSgPointerType(vs_->get_type());
-
- if (arrType != NULL) {
- SgExprListExp* dimList = arrType->get_dim_info();
- if (!static_cast<const IR_roseCode *>(ir_)->is_fortran_) {
- SgExpressionPtrList::iterator it =
- dimList->get_expressions().begin();
-
- while ((it != dimList->get_expressions().end()) && (count < dim)) {
- it++;
- count++;
- }
-
- expr = *it;
- } else {
- SgExpressionPtrList::reverse_iterator i =
- dimList->get_expressions().rbegin();
- for (; (i != dimList->get_expressions().rend()) && (count < dim);
- i++) {
-
- count++;
- }
-
- expr = *i;
- }
- } else if (pntrType != NULL) {
-
- while (count < dim) {
- pntrType = (isSgPointerType(pntrType))->get_base_type();
- count++;
- }
- if (isSgPointerType(pntrType))
- expr = new SgExpression;
- }
-
- if (!expr)
- throw ir_error("Index variable is NULL!!");
-
- // Manu :: debug
- std::cout << "---------- size :: " << isSgNode(expr)->unparseToString().c_str() << "\n";
-
- return new omega::CG_roseRepr(expr);
-
-}
-
-IR_ARRAY_LAYOUT_TYPE IR_roseArraySymbol::layout_type() const {
- if (static_cast<const IR_roseCode *>(ir_)->is_fortran_)
- return IR_ARRAY_LAYOUT_COLUMN_MAJOR;
- else
- return IR_ARRAY_LAYOUT_ROW_MAJOR;
-
-}
-
-bool IR_roseArraySymbol::operator==(const IR_Symbol &that) const {
-
- if (typeid(*this) != typeid(that))
- return false;
-
- const IR_roseArraySymbol *l_that =
- static_cast<const IR_roseArraySymbol *>(&that);
- return this->vs_ == l_that->vs_;
-
-}
-
-IR_Symbol *IR_roseArraySymbol::clone() const {
- return new IR_roseArraySymbol(ir_, vs_);
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseConstantRef
-// ----------------------------------------------------------------------------
-
-bool IR_roseConstantRef::operator==(const IR_Ref &that) const {
-
- if (typeid(*this) != typeid(that))
- return false;
-
- const IR_roseConstantRef *l_that =
- static_cast<const IR_roseConstantRef *>(&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_roseConstantRef::convert() {
- if (type_ == IR_CONSTANT_INT) {
- omega::CG_roseRepr *result = new omega::CG_roseRepr(
- isSgExpression(buildIntVal(static_cast<int>(i_))));
- delete this;
- return result;
- } else
- throw ir_error("constant type not supported");
-
-}
-
-IR_Ref *IR_roseConstantRef::clone() const {
- if (type_ == IR_CONSTANT_INT)
- return new IR_roseConstantRef(ir_, i_);
- else if (type_ == IR_CONSTANT_FLOAT)
- return new IR_roseConstantRef(ir_, f_);
- else
- throw ir_error("constant type not supported");
-
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseScalarRef
-// ----------------------------------------------------------------------------
-
-bool IR_roseScalarRef::is_write() const {
- if (is_write_ == 1)
- return true;
-
- return false;
-}
-
-IR_ScalarSymbol *IR_roseScalarRef::symbol() const {
- return new IR_roseScalarSymbol(ir_, vs_->get_symbol());
-}
-
-bool IR_roseScalarRef::operator==(const IR_Ref &that) const {
- if (typeid(*this) != typeid(that))
- return false;
-
- const IR_roseScalarRef *l_that =
- static_cast<const IR_roseScalarRef *>(&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_roseScalarRef::convert() {
- omega::CG_roseRepr *result = new omega::CG_roseRepr(isSgExpression(vs_));
- delete this;
- return result;
-
-}
-
-IR_Ref * IR_roseScalarRef::clone() const {
- return new IR_roseScalarRef(ir_, vs_, this->is_write_);
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseArrayRef
-// ----------------------------------------------------------------------------
-
-bool IR_roseArrayRef::is_write() const {
- SgAssignOp* assignment;
-
- if (is_write_ == 1 || is_write_ == 0)
- return is_write_;
- if (assignment = isSgAssignOp(ia_->get_parent())) {
- if (assignment->get_lhs_operand() == ia_)
- return true;
- } else if (SgExprStatement* expr_stmt = isSgExprStatement(
- ia_->get_parent())) {
- SgExpression* exp = expr_stmt->get_expression();
-
- if (exp) {
- if (assignment = isSgAssignOp(exp)) {
- if (assignment->get_lhs_operand() == ia_)
- return true;
-
- }
- }
-
- }
- return false;
-}
-
-omega::CG_outputRepr *IR_roseArrayRef::index(int dim) const {
-
- SgExpression *current = isSgExpression(ia_);
- SgExpression* expr;
- int count = 0;
-
- while (isSgPntrArrRefExp(current)) {
- current = isSgPntrArrRefExp(current)->get_lhs_operand();
- count++;
- }
-
- current = ia_;
-
- while (count > dim) {
- expr = isSgPntrArrRefExp(current)->get_rhs_operand();
- current = isSgPntrArrRefExp(current)->get_lhs_operand();
- count--;
- }
-
- // Manu:: fortran support
- if (static_cast<const IR_roseCode *>(ir_)->is_fortran_) {
- expr = isSgPntrArrRefExp(ia_)->get_rhs_operand();
- count = 0;
- if (isSgExprListExp(expr)) {
- SgExpressionPtrList::iterator indexList = isSgExprListExp(expr)->get_expressions().begin();
- while (count < dim) {
- indexList++;
- count++;
- }
- expr = isSgExpression(*indexList);
- }
- }
-
- if (!expr)
- throw ir_error("Index variable is NULL!!");
-
-
- omega::CG_roseRepr* ind = new omega::CG_roseRepr(expr);
-
- return ind->clone();
-
-}
-
-IR_ArraySymbol *IR_roseArrayRef::symbol() const {
-
- SgExpression *current = isSgExpression(ia_);
-
- SgVarRefExp* base;
- SgVariableSymbol *arrSymbol;
- while (isSgPntrArrRefExp(current) || isSgUnaryOp(current)) {
- if (isSgPntrArrRefExp(current))
- current = isSgPntrArrRefExp(current)->get_lhs_operand();
- else if (isSgUnaryOp(current))
- /* To handle support for addressof operator and pointer dereference
- * both of which are unary ops
- */
- current = isSgUnaryOp(current)->get_operand();
- }
- if (base = isSgVarRefExp(current)) {
- arrSymbol = (SgVariableSymbol*) (base->get_symbol());
- std::string x = arrSymbol->get_name().getString();
- } else
- throw ir_error("Array Symbol is not a variable?!");
-
- return new IR_roseArraySymbol(ir_, arrSymbol);
-
-}
-
-bool IR_roseArrayRef::operator==(const IR_Ref &that) const {
- if (typeid(*this) != typeid(that))
- return false;
-
- const IR_roseArrayRef *l_that = static_cast<const IR_roseArrayRef *>(&that);
-
- return this->ia_ == l_that->ia_;
-}
-
-omega::CG_outputRepr *IR_roseArrayRef::convert() {
- omega::CG_roseRepr *temp = new omega::CG_roseRepr(
- isSgExpression(this->ia_));
- omega::CG_outputRepr *result = temp->clone();
-// delete this; // Commented by Manu
- return result;
-}
-
-IR_Ref *IR_roseArrayRef::clone() const {
- return new IR_roseArrayRef(ir_, ia_, is_write_);
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseLoop
-// ----------------------------------------------------------------------------
-
-IR_ScalarSymbol *IR_roseLoop::index() const {
- SgForStatement *tf = isSgForStatement(tf_);
- SgFortranDo *tfortran = isSgFortranDo(tf_);
- SgVariableSymbol* vs = NULL;
- if (tf) {
- SgForInitStatement* list = tf->get_for_init_stmt();
- SgStatementPtrList& initStatements = list->get_init_stmt();
- SgStatementPtrList::const_iterator j = initStatements.begin();
-
- if (SgExprStatement *expr = isSgExprStatement(*j))
- if (SgAssignOp* op = isSgAssignOp(expr->get_expression()))
- if (SgVarRefExp* var_ref = isSgVarRefExp(op->get_lhs_operand()))
- vs = var_ref->get_symbol();
- } else if (tfortran) {
- SgExpression* init = tfortran->get_initialization();
-
- if (SgAssignOp* op = isSgAssignOp(init))
- if (SgVarRefExp* var_ref = isSgVarRefExp(op->get_lhs_operand()))
- vs = var_ref->get_symbol();
-
- }
-
- if (vs == NULL)
- throw ir_error("Index variable is NULL!!");
-
- return new IR_roseScalarSymbol(ir_, vs);
-}
-
-omega::CG_outputRepr *IR_roseLoop::lower_bound() const {
- SgForStatement *tf = isSgForStatement(tf_);
- SgFortranDo *tfortran = isSgFortranDo(tf_);
-
- SgExpression* lowerBound = NULL;
-
- if (tf) {
- SgForInitStatement* list = tf->get_for_init_stmt();
- SgStatementPtrList& initStatements = list->get_init_stmt();
- SgStatementPtrList::const_iterator j = initStatements.begin();
-
- if (SgExprStatement *expr = isSgExprStatement(*j))
- if (SgAssignOp* op = isSgAssignOp(expr->get_expression())) {
- lowerBound = op->get_rhs_operand();
- //Rose sometimes introduces an unnecessary cast which is a unary op
- if (isSgUnaryOp(lowerBound))
- lowerBound = isSgUnaryOp(lowerBound)->get_operand();
-
- }
- } else if (tfortran) {
- SgExpression* init = tfortran->get_initialization();
-
- if (SgAssignOp* op = isSgAssignOp(init))
- lowerBound = op->get_rhs_operand();
- }
-
- if (lowerBound == NULL)
- throw ir_error("Lower Bound is NULL!!");
-
- return new omega::CG_roseRepr(lowerBound);
-}
-
-omega::CG_outputRepr *IR_roseLoop::upper_bound() const {
- SgForStatement *tf = isSgForStatement(tf_);
- SgFortranDo *tfortran = isSgFortranDo(tf_);
- SgExpression* upperBound = NULL;
- if (tf) {
- SgBinaryOp* test_expr = isSgBinaryOp(tf->get_test_expr());
- if (test_expr == NULL)
- throw ir_error("Test Expression is NULL!!");
-
- upperBound = test_expr->get_rhs_operand();
- //Rose sometimes introduces an unnecessary cast which is a unary op
- if (isSgUnaryOp(upperBound))
- upperBound = isSgUnaryOp(upperBound)->get_operand();
- if (upperBound == NULL)
- throw ir_error("Upper Bound is NULL!!");
- } else if (tfortran) {
-
- upperBound = tfortran->get_bound();
-
- }
-
- return new omega::CG_roseRepr(upperBound);
-
-}
-
-IR_CONDITION_TYPE IR_roseLoop::stop_cond() const {
- SgForStatement *tf = isSgForStatement(tf_);
- SgFortranDo *tfortran = isSgFortranDo(tf_);
-
- if (tf) {
- SgExpression* stopCond = NULL;
- SgExpression* test_expr = tf->get_test_expr();
-
- if (isSgLessThanOp(test_expr))
- return IR_COND_LT;
- else if (isSgLessOrEqualOp(test_expr))
- return IR_COND_LE;
- else if (isSgGreaterThanOp(test_expr))
- return IR_COND_GT;
- else if (isSgGreaterOrEqualOp(test_expr))
- return IR_COND_GE;
-
- else
- throw ir_error("loop stop condition unsupported");
- } else if (tfortran) {
- SgExpression* increment = tfortran->get_increment();
- if (!isSgNullExpression(increment)) {
- if (isSgMinusOp(increment)
- && !isSgBinaryOp(isSgMinusOp(increment)->get_operand()))
- return IR_COND_GE;
- else
- return IR_COND_LE;
- } else {
- return IR_COND_LE; // Manu:: if increment is not present, assume it to be 1. Just a workaround, not sure if it will be correct for all cases.
- SgExpression* lowerBound = NULL;
- SgExpression* upperBound = NULL;
- SgExpression* init = tfortran->get_initialization();
- SgIntVal* ub;
- SgIntVal* lb;
- if (SgAssignOp* op = isSgAssignOp(init))
- lowerBound = op->get_rhs_operand();
-
- upperBound = tfortran->get_bound();
-
- if ((upperBound != NULL) && (lowerBound != NULL)) {
-
- if ((ub = isSgIntVal(isSgValueExp(upperBound))) && (lb =
- isSgIntVal(isSgValueExp(lowerBound)))) {
- if (ub->get_value() > lb->get_value())
- return IR_COND_LE;
- else
- return IR_COND_GE;
- } else
- throw ir_error("loop stop condition unsupported");
-
- } else
- throw ir_error("malformed fortran loop bounds!!");
-
- }
- }
-
-}
-
-IR_Block *IR_roseLoop::body() const {
- SgForStatement *tf = isSgForStatement(tf_);
- SgFortranDo *tfortran = isSgFortranDo(tf_);
- SgNode* loop_body = NULL;
- SgStatement* body_statements = NULL;
-
- if (tf) {
- body_statements = tf->get_loop_body();
- } else if (tfortran) {
- body_statements = isSgStatement(tfortran->get_body());
-
- }
-
- loop_body = isSgNode(body_statements);
-
- SgStatementPtrList list;
- if (isSgBasicBlock(loop_body)) {
- list = isSgBasicBlock(loop_body)->get_statements();
-
- if (list.size() == 1)
- loop_body = isSgNode(*(list.begin()));
- }
-
- if (loop_body == NULL)
- throw ir_error("for loop body is NULL!!");
-
- return new IR_roseBlock(ir_, loop_body);
-}
-
-int IR_roseLoop::step_size() const {
-
- SgForStatement *tf = isSgForStatement(tf_);
- SgFortranDo *tfortran = isSgFortranDo(tf_);
-
- if (tf) {
- SgExpression *increment = tf->get_increment();
-
- if (isSgPlusPlusOp(increment))
- return 1;
- if (isSgMinusMinusOp(increment))
- return -1;
- else if (SgAssignOp* assignment = isSgAssignOp(increment)) {
- SgBinaryOp* stepsize = isSgBinaryOp(assignment->get_lhs_operand());
- if (stepsize == NULL)
- throw ir_error("Step size expression is NULL!!");
- SgIntVal* step = isSgIntVal(stepsize->get_lhs_operand());
- return step->get_value();
- } else if (SgBinaryOp* inc = isSgPlusAssignOp(increment)) {
- SgIntVal* step = isSgIntVal(inc->get_rhs_operand());
- return (step->get_value());
- } else if (SgBinaryOp * inc = isSgMinusAssignOp(increment)) {
- SgIntVal* step = isSgIntVal(inc->get_rhs_operand());
- return -(step->get_value());
- } else if (SgBinaryOp * inc = isSgCompoundAssignOp(increment)) {
- SgIntVal* step = isSgIntVal(inc->get_rhs_operand());
- return (step->get_value());
- }
-
- } else if (tfortran) {
-
- SgExpression* increment = tfortran->get_increment();
-
- if (!isSgNullExpression(increment)) {
- if (isSgMinusOp(increment)) {
- if (SgValueExp *inc = isSgValueExp(
- isSgMinusOp(increment)->get_operand()))
- if (isSgIntVal(inc))
- return -(isSgIntVal(inc)->get_value());
- } else {
- if (SgValueExp* inc = isSgValueExp(increment))
- if (isSgIntVal(inc))
- return isSgIntVal(inc)->get_value();
- }
- } else {
- return 1; // Manu:: if increment is not present, assume it to be 1. Just a workaround, not sure if it will be correct for all cases.
- SgExpression* lowerBound = NULL;
- SgExpression* upperBound = NULL;
- SgExpression* init = tfortran->get_initialization();
- SgIntVal* ub;
- SgIntVal* lb;
- if (SgAssignOp* op = isSgAssignOp(init))
- lowerBound = op->get_rhs_operand();
-
- upperBound = tfortran->get_bound();
-
- if ((upperBound != NULL) && (lowerBound != NULL)) {
-
- if ((ub = isSgIntVal(isSgValueExp(upperBound))) && (lb =
- isSgIntVal(isSgValueExp(lowerBound)))) {
- if (ub->get_value() > lb->get_value())
- return 1;
- else
- return -1;
- } else
- throw ir_error("loop stop condition unsupported");
-
- } else
- throw ir_error("loop stop condition unsupported");
-
- }
-
- }
-
-}
-
-IR_Block *IR_roseLoop::convert() {
- const IR_Code *ir = ir_;
- SgNode *tnl = isSgNode(tf_);
- delete this;
- return new IR_roseBlock(ir, tnl);
-}
-
-IR_Control *IR_roseLoop::clone() const {
-
- return new IR_roseLoop(ir_, tf_);
-
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseBlock
-// ----------------------------------------------------------------------------
-
-omega::CG_outputRepr *IR_roseBlock::original() const {
-
- omega::CG_outputRepr * tnl;
-
- if (isSgBasicBlock(tnl_)) {
-
- SgStatementPtrList *bb = new SgStatementPtrList();
- SgStatementPtrList::iterator it;
- for (it = (isSgBasicBlock(tnl_)->get_statements()).begin();
- it != (isSgBasicBlock(tnl_)->get_statements()).end()
- && (*it != start_); it++)
- ;
-
- if (it != (isSgBasicBlock(tnl_)->get_statements()).end()) {
- for (; it != (isSgBasicBlock(tnl_)->get_statements()).end(); it++) {
- bb->push_back(*it);
- if ((*it) == end_)
- break;
- }
- }
- tnl = new omega::CG_roseRepr(bb);
-
- } else {
-
- tnl = new omega::CG_roseRepr(tnl_);
-
- }
-
- return tnl;
-
-}
-omega::CG_outputRepr *IR_roseBlock::extract() const {
-
- std::string x = tnl_->unparseToString();
-
- omega::CG_roseRepr * tnl;
-
- omega::CG_outputRepr* block;
-
- if (isSgBasicBlock(tnl_)) {
-
- SgStatementPtrList *bb = new SgStatementPtrList();
- SgStatementPtrList::iterator it;
- for (it = (isSgBasicBlock(tnl_)->get_statements()).begin();
- it != (isSgBasicBlock(tnl_)->get_statements()).end()
- && (*it != start_); it++)
- ;
-
- if (it != (isSgBasicBlock(tnl_)->get_statements()).end()) {
- for (; it != (isSgBasicBlock(tnl_)->get_statements()).end(); it++) {
- bb->push_back(*it);
- if ((*it) == end_)
- break;
- }
- }
- tnl = new omega::CG_roseRepr(bb);
- block = tnl->clone();
-
- } else {
- tnl = new omega::CG_roseRepr(tnl_);
-
- block = tnl->clone();
- }
-
- delete tnl;
- return block;
-}
-
-IR_Control *IR_roseBlock::clone() const {
- return new IR_roseBlock(ir_, tnl_, start_, end_);
-
-}
-// ----------------------------------------------------------------------------
-// Class: IR_roseIf
-// ----------------------------------------------------------------------------
-omega::CG_outputRepr *IR_roseIf::condition() const {
- SgNode *tnl = isSgNode(isSgIfStmt(ti_)->get_conditional());
- SgExpression* exp = NULL;
- if (SgExprStatement* stmt = isSgExprStatement(tnl))
- exp = stmt->get_expression();
- if (exp == NULL)
- return new omega::CG_roseRepr(tnl);
- else
- return new omega::CG_roseRepr(exp);
-}
-
-IR_Block *IR_roseIf::then_body() const {
- SgNode *tnl = isSgNode(isSgIfStmt(ti_)->get_true_body());
-
- if (tnl == NULL)
- return NULL;
-
- return new IR_roseBlock(ir_, tnl);
-}
-
-IR_Block *IR_roseIf::else_body() const {
- SgNode *tnl = isSgNode(isSgIfStmt(ti_)->get_false_body());
-
- if (tnl == NULL)
- return NULL;
-
- return new IR_roseBlock(ir_, tnl);
-}
-
-IR_Block *IR_roseIf::convert() {
- const IR_Code *ir = ir_;
- delete this;
- return new IR_roseBlock(ir, ti_);
-}
-
-IR_Control *IR_roseIf::clone() const {
- return new IR_roseIf(ir_, ti_);
-}
-
-// -----------------------------------------------------------y-----------------
-// Class: IR_roseCode_Global_Init
-// ----------------------------------------------------------------------------
-
-IR_roseCode_Global_Init *IR_roseCode_Global_Init::pinstance = 0;
-
-IR_roseCode_Global_Init * IR_roseCode_Global_Init::Instance(char** argv) {
- if (pinstance == 0) {
- pinstance = new IR_roseCode_Global_Init;
- pinstance->project = frontend(2, argv);
-
- }
- return pinstance;
-}
-
-// ----------------------------------------------------------------------------
-// Class: IR_roseCode
-// ----------------------------------------------------------------------------
-
-IR_roseCode::IR_roseCode(const char *filename, const char* proc_name) :
- IR_Code() {
-
- SgProject* project;
-
- char* argv[2];
- int counter = 0;
- argv[0] = (char*) malloc(5 * sizeof(char));
- argv[1] = (char*) malloc((strlen(filename) + 1) * sizeof(char));
- strcpy(argv[0], "rose");
- strcpy(argv[1], filename);
-
- project = (IR_roseCode_Global_Init::Instance(argv))->project;
- firstScope = getFirstGlobalScope(project);
- SgFilePtrList& file_list = project->get_fileList();
-
- for (SgFilePtrList::iterator it = file_list.begin(); it != file_list.end();
- it++) {
- file = isSgSourceFile(*it);
- if (file->get_outputLanguage() == SgFile::e_Fortran_output_language)
- is_fortran_ = true;
- else
- is_fortran_ = false;
-
- root = file->get_globalScope();
-
- if (!is_fortran_) { // Manu:: this macro should not be created if the input code is in fortran
- buildCpreprocessorDefineDeclaration(root,
- "#define __rose_lt(x,y) ((x)<(y)?(x):(y))",
- PreprocessingInfo::before);
- buildCpreprocessorDefineDeclaration(root,
- "#define __rose_gt(x,y) ((x)>(y)?(x):(y))",
- PreprocessingInfo::before);
- }
-
- symtab_ = isSgScopeStatement(root)->get_symbol_table();
- SgDeclarationStatementPtrList& declList = root->get_declarations();
-
- p = declList.begin();
-
- while (p != declList.end()) {
- func = isSgFunctionDeclaration(*p);
- if (func) {
- if (!strcmp((func->get_name().getString()).c_str(), proc_name))
- break;
-
- }
- p++;
- counter++;
- }
- if (p != declList.end())
- break;
-
- }
-
- symtab2_ = func->get_definition()->get_symbol_table();
- symtab3_ = func->get_definition()->get_body()->get_symbol_table();
- // Manu:: added is_fortran_ parameter
- // TODO Substitute it with a better builder
- ocg_ = new omega::CG_roseBuilder(is_fortran_, root, firstScope,
- func->get_definition()->get_symbol_table(),
- func->get_definition()->get_body()->get_symbol_table(),
- isSgNode(func->get_definition()->get_body()));
-
- i_ = 0; /*i_ handling may need revision */
-
- free(argv[1]);
- free(argv[0]);
-
-}
-
-IR_roseCode::~IR_roseCode() {
-}
-
-void IR_roseCode::finalizeRose() {
- SgProject* project = (IR_roseCode_Global_Init::Instance(NULL))->project;
- project->unparse();
-}
-
-IR_ScalarSymbol *IR_roseCode::CreateScalarSymbol(const IR_Symbol *sym, int) {
- char str1[14];
- if (typeid(*sym) == typeid(IR_roseScalarSymbol)) {
- SgType *tn =
- static_cast<const IR_roseScalarSymbol *>(sym)->vs_->get_type();
- sprintf(str1, "newVariable%i", i_);
- SgVariableDeclaration* defn = buildVariableDeclaration(str1, tn);
- i_++;
-
- SgInitializedNamePtrList& variables = defn->get_variables();
- SgInitializedNamePtrList::const_iterator i = variables.begin();
- SgInitializedName* initializedName = *i;
- SgVariableSymbol* vs = new SgVariableSymbol(initializedName);
-
- prependStatement(defn,
- isSgScopeStatement(func->get_definition()->get_body()));
- vs->set_parent(symtab_);
- symtab_->insert(str1, vs);
-
- if (vs == NULL)
- throw ir_error("in CreateScalarSymbol: vs is NULL!!");
-
- return new IR_roseScalarSymbol(this, vs);
- } else if (typeid(*sym) == typeid(IR_roseArraySymbol)) {
- SgType *tn1 =
- static_cast<const IR_roseArraySymbol *>(sym)->vs_->get_type();
- while (isSgArrayType(tn1) || isSgPointerType(tn1)) {
- if (isSgArrayType(tn1))
- tn1 = isSgArrayType(tn1)->get_base_type();
- else if (isSgPointerType(tn1))
- tn1 = isSgPointerType(tn1)->get_base_type();
- else
- throw ir_error(
- "in CreateScalarSymbol: symbol not an array nor a pointer!");
- }
-
- sprintf(str1, "newVariable%i", i_);
- i_++;
-
- SgVariableDeclaration* defn1 = buildVariableDeclaration(str1, tn1);
- SgInitializedNamePtrList& variables1 = defn1->get_variables();
-
- SgInitializedNamePtrList::const_iterator i1 = variables1.begin();
- SgInitializedName* initializedName1 = *i1;
-
- SgVariableSymbol *vs1 = new SgVariableSymbol(initializedName1);
- prependStatement(defn1,
- isSgScopeStatement(func->get_definition()->get_body()));
-
- vs1->set_parent(symtab_);
- symtab_->insert(str1, vs1);
-
- if (vs1 == NULL)
- throw ir_error("in CreateScalarSymbol: vs1 is NULL!!");
-
- return new IR_roseScalarSymbol(this, vs1);
- } else
- throw std::bad_typeid();
-
-}
-
-IR_ArraySymbol *IR_roseCode::CreateArraySymbol(const IR_Symbol *sym,
- std::vector<omega::CG_outputRepr *> &size, int) {
- SgType *tn;
- char str1[14];
-
- if (typeid(*sym) == typeid(IR_roseScalarSymbol)) {
- tn = static_cast<const IR_roseScalarSymbol *>(sym)->vs_->get_type();
- } else if (typeid(*sym) == typeid(IR_roseArraySymbol)) {
- tn = static_cast<const IR_roseArraySymbol *>(sym)->vs_->get_type();
- while (isSgArrayType(tn) || isSgPointerType(tn)) {
- if (isSgArrayType(tn))
- tn = isSgArrayType(tn)->get_base_type();
- else if (isSgPointerType(tn))
- tn = isSgPointerType(tn)->get_base_type();
- else
- throw ir_error(
- "in CreateScalarSymbol: symbol not an array nor a pointer!");
- }
- } else
- throw std::bad_typeid();
-
-
- // Manu:: Fortran support
- std::vector<SgExpression *>exprs;
- SgExprListExp *exprLstExp;
- SgExpression* sizeExpression = new SgNullExpression();
- SgArrayType* arrayType = new SgArrayType(tn,sizeExpression);
- sizeExpression->set_parent(arrayType);
-
- if (!is_fortran_) {
- for (int i = size.size() - 1; i >= 0; i--) {
- tn = buildArrayType(tn,static_cast<omega::CG_roseRepr *>(size[i])->GetExpression());
- }
- } else { // Manu:: required for fortran support
- for (int i = size.size() - 1; i >= 0; i--) {
- exprs.push_back(static_cast<omega::CG_roseRepr *>(size[i])->GetExpression());
- }
- }
-
- if (is_fortran_) {
- exprLstExp = buildExprListExp(exprs);
- arrayType->set_dim_info(exprLstExp);
- exprLstExp->set_parent(arrayType);
- arrayType->set_rank(exprLstExp->get_expressions().size());
- }
-
- static int rose_array_counter = 1;
- SgVariableDeclaration* defn2;
- std::string s;
- if (!is_fortran_) {
- s = std::string("_P") + omega::to_string(rose_array_counter++);
- defn2 = buildVariableDeclaration(const_cast<char *>(s.c_str()), tn);
- } else {// Manu:: fortran support
- s = std::string("f_P") + omega::to_string(rose_array_counter++);
- defn2 = buildVariableDeclaration(const_cast<char *>(s.c_str()), arrayType);
- }
-
-
- SgInitializedNamePtrList& variables2 = defn2->get_variables();
-
- SgInitializedNamePtrList::const_iterator i2 = variables2.begin();
- SgInitializedName* initializedName2 = *i2;
- SgVariableSymbol *vs = new SgVariableSymbol(initializedName2);
-
- prependStatement(defn2,
- isSgScopeStatement(func->get_definition()->get_body()));
-
- vs->set_parent(symtab_);
- symtab_->insert(SgName(s.c_str()), vs);
-
- return new IR_roseArraySymbol(this, vs);
-}
-
-IR_ScalarRef *IR_roseCode::CreateScalarRef(const IR_ScalarSymbol *sym) {
- return new IR_roseScalarRef(this,
- buildVarRefExp(static_cast<const IR_roseScalarSymbol *>(sym)->vs_));
-
-}
-
-IR_ArrayRef *IR_roseCode::CreateArrayRef(const IR_ArraySymbol *sym,
- std::vector<omega::CG_outputRepr *> &index) {
-
- int t;
-
- if (sym->n_dim() != index.size())
- throw std::invalid_argument("incorrect array symbol dimensionality");
-
- const IR_roseArraySymbol *l_sym =
- static_cast<const IR_roseArraySymbol *>(sym);
-
- SgVariableSymbol *vs = l_sym->vs_;
- SgExpression* ia1 = buildVarRefExp(vs);
-
-
-
- if (is_fortran_) { // Manu:: fortran support
- std::vector<SgExpression *>exprs;
- for (int i = 0 ; i < index.size(); i++) {
- exprs.push_back(static_cast<omega::CG_roseRepr *>(index[i])->GetExpression());
- }
- SgExprListExp *exprLstExp;
- exprLstExp = buildExprListExp(exprs);
- ia1 = buildPntrArrRefExp(ia1,exprLstExp);
- } else {
- for (int i = 0; i < index.size(); i++) {
-
- ia1 = buildPntrArrRefExp(ia1,
- static_cast<omega::CG_roseRepr *>(index[i])->GetExpression());
-
- }
- }
-
- SgPntrArrRefExp *ia = isSgPntrArrRefExp(ia1);
-
- return new IR_roseArrayRef(this, ia, -1);
-
-}
-
-std::vector<IR_ScalarRef *> IR_roseCode::FindScalarRef(
- const omega::CG_outputRepr *repr) const {
- std::vector<IR_ScalarRef *> scalars;
- SgNode *tnl = static_cast<const omega::CG_roseRepr *>(repr)->GetCode();
- SgStatementPtrList *list =
- static_cast<const omega::CG_roseRepr *>(repr)->GetList();
- SgStatement* stmt;
- SgExpression * exp;
-
- if (list != NULL) {
- for (SgStatementPtrList::iterator it = (*list).begin();
- it != (*list).end(); it++) {
- omega::CG_roseRepr *r = new omega::CG_roseRepr(isSgNode(*it));
- std::vector<IR_ScalarRef *> a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- }
- }
-
- else if (tnl != NULL) {
- if (stmt = isSgStatement(tnl)) {
- if (isSgBasicBlock(stmt)) {
- SgStatementPtrList& stmts =
- isSgBasicBlock(stmt)->get_statements();
- for (int i = 0; i < stmts.size(); i++) {
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgNode(stmts[i]));
- std::vector<IR_ScalarRef *> a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- }
-
- } else if (isSgForStatement(stmt)) {
-
- SgForStatement *tnf = isSgForStatement(stmt);
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgStatement(tnf->get_loop_body()));
- std::vector<IR_ScalarRef *> a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- } else if (isSgFortranDo(stmt)) {
- SgFortranDo *tfortran = isSgFortranDo(stmt);
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgStatement(tfortran->get_body()));
- std::vector<IR_ScalarRef *> a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- } else if (isSgIfStmt(stmt)) {
- SgIfStmt* tni = isSgIfStmt(stmt);
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgNode(tni->get_conditional()));
- std::vector<IR_ScalarRef *> a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- r = new omega::CG_roseRepr(isSgNode(tni->get_true_body()));
- a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- r = new omega::CG_roseRepr(isSgNode(tni->get_false_body()));
- a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
- } else if (isSgExprStatement(stmt)) {
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgExpression(
- isSgExprStatement(stmt)->get_expression()));
- std::vector<IR_ScalarRef *> a = FindScalarRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(scalars));
-
- }
- }
- } else {
- SgExpression* op =
- static_cast<const omega::CG_roseRepr *>(repr)->GetExpression();
- if (isSgVarRefExp(op)
- && (!isSgArrayType(isSgVarRefExp(op)->get_type()))) {
- if (SgBinaryOp* op_ = isSgBinaryOp(
- isSgVarRefExp(op)->get_parent())) {
- if (SgCompoundAssignOp *op__ = isSgCompoundAssignOp(op_)) {
- if (isSgCompoundAssignOp(op_)->get_lhs_operand()
- == isSgVarRefExp(op)) {
- scalars.push_back(
- new IR_roseScalarRef(this, isSgVarRefExp(op),
- 1));
- scalars.push_back(
- new IR_roseScalarRef(this, isSgVarRefExp(op),
- 0));
- }
- }
- } else if (SgAssignOp* assmt = isSgAssignOp(
- isSgVarRefExp(op)->get_parent())) {
-
- if (assmt->get_lhs_operand() == isSgVarRefExp(op))
- scalars.push_back(
- new IR_roseScalarRef(this, isSgVarRefExp(op), 1));
- } else if (SgAssignOp * assmt = isSgAssignOp(
- isSgVarRefExp(op)->get_parent())) {
-
- if (assmt->get_rhs_operand() == isSgVarRefExp(op))
- scalars.push_back(
- new IR_roseScalarRef(this, isSgVarRefExp(op), 0));
- } else
- scalars.push_back(
- new IR_roseScalarRef(this, isSgVarRefExp(op), 0));
- } else if (isSgAssignOp(op)) {
- omega::CG_roseRepr *r1 = new omega::CG_roseRepr(
- isSgAssignOp(op)->get_lhs_operand());
- std::vector<IR_ScalarRef *> a1 = FindScalarRef(r1);
- delete r1;
- std::copy(a1.begin(), a1.end(), back_inserter(scalars));
- omega::CG_roseRepr *r2 = new omega::CG_roseRepr(
- isSgAssignOp(op)->get_rhs_operand());
- std::vector<IR_ScalarRef *> a2 = FindScalarRef(r2);
- delete r2;
- std::copy(a2.begin(), a2.end(), back_inserter(scalars));
-
- } else if (isSgBinaryOp(op)) {
- omega::CG_roseRepr *r1 = new omega::CG_roseRepr(
- isSgBinaryOp(op)->get_lhs_operand());
- std::vector<IR_ScalarRef *> a1 = FindScalarRef(r1);
- delete r1;
- std::copy(a1.begin(), a1.end(), back_inserter(scalars));
- omega::CG_roseRepr *r2 = new omega::CG_roseRepr(
- isSgBinaryOp(op)->get_rhs_operand());
- std::vector<IR_ScalarRef *> a2 = FindScalarRef(r2);
- delete r2;
- std::copy(a2.begin(), a2.end(), back_inserter(scalars));
- } else if (isSgUnaryOp(op)) {
- omega::CG_roseRepr *r1 = new omega::CG_roseRepr(
- isSgUnaryOp(op)->get_operand());
- std::vector<IR_ScalarRef *> a1 = FindScalarRef(r1);
- delete r1;
- std::copy(a1.begin(), a1.end(), back_inserter(scalars));
- }
-
- }
- return scalars;
-
-}
-
-std::vector<IR_ArrayRef *> IR_roseCode::FindArrayRef(
- const omega::CG_outputRepr *repr) const {
- std::vector<IR_ArrayRef *> arrays;
- SgNode *tnl = static_cast<const omega::CG_roseRepr *>(repr)->GetCode();
- SgStatementPtrList* list =
- static_cast<const omega::CG_roseRepr *>(repr)->GetList();
- SgStatement* stmt;
- SgExpression * exp;
-
- if (list != NULL) {
- for (SgStatementPtrList::iterator it = (*list).begin();
- it != (*list).end(); it++) {
- omega::CG_roseRepr *r = new omega::CG_roseRepr(isSgNode(*it));
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- }
- } else if (tnl != NULL) {
- if (stmt = isSgStatement(tnl)) {
- if (isSgBasicBlock(stmt)) {
- SgStatementPtrList& stmts =
- isSgBasicBlock(stmt)->get_statements();
- for (int i = 0; i < stmts.size(); i++) {
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgNode(stmts[i]));
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- }
-
- } else if (isSgForStatement(stmt)) {
-
- SgForStatement *tnf = isSgForStatement(stmt);
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgStatement(tnf->get_loop_body()));
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- } else if (isSgFortranDo(stmt)) {
- SgFortranDo *tfortran = isSgFortranDo(stmt);
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgStatement(tfortran->get_body()));
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- } else if (isSgIfStmt(stmt)) {
- SgIfStmt* tni = isSgIfStmt(stmt);
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgNode(tni->get_conditional()));
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- r = new omega::CG_roseRepr(isSgNode(tni->get_true_body()));
- a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- r = new omega::CG_roseRepr(isSgNode(tni->get_false_body()));
- a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
- } else if (isSgExprStatement(stmt)) {
- omega::CG_roseRepr *r = new omega::CG_roseRepr(
- isSgExpression(
- isSgExprStatement(stmt)->get_expression()));
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
-
- }
- }
- } else {
- SgExpression* op =
- static_cast<const omega::CG_roseRepr *>(repr)->GetExpression();
- if (isSgPntrArrRefExp(op)) {
-
- SgVarRefExp* base;
- SgExpression* op2;
- if (isSgCompoundAssignOp(isSgPntrArrRefExp(op)->get_parent())) {
- IR_roseArrayRef *ref1 = new IR_roseArrayRef(this,
- isSgPntrArrRefExp(op), 0);
- arrays.push_back(ref1);
- IR_roseArrayRef *ref2 = new IR_roseArrayRef(this,
- isSgPntrArrRefExp(op), 1);
- arrays.push_back(ref2);
- } else {
- IR_roseArrayRef *ref3 = new IR_roseArrayRef(this,
- isSgPntrArrRefExp(op), -1);
- arrays.push_back(ref3);
-
- while (isSgPntrArrRefExp(op)) {
- op2 = isSgPntrArrRefExp(op)->get_rhs_operand();
- op = isSgPntrArrRefExp(op)->get_lhs_operand();
- omega::CG_roseRepr *r = new omega::CG_roseRepr(op2);
- std::vector<IR_ArrayRef *> a = FindArrayRef(r);
- delete r;
- std::copy(a.begin(), a.end(), back_inserter(arrays));
-
- }
- }
- } else if (isSgAssignOp(op)) {
- omega::CG_roseRepr *r1 = new omega::CG_roseRepr(
- isSgAssignOp(op)->get_lhs_operand());
- std::vector<IR_ArrayRef *> a1 = FindArrayRef(r1);
- delete r1;
- std::copy(a1.begin(), a1.end(), back_inserter(arrays));
- omega::CG_roseRepr *r2 = new omega::CG_roseRepr(
- isSgAssignOp(op)->get_rhs_operand());
- std::vector<IR_ArrayRef *> a2 = FindArrayRef(r2);
- delete r2;
- std::copy(a2.begin(), a2.end(), back_inserter(arrays));
-
- } else if (isSgBinaryOp(op)) {
- omega::CG_roseRepr *r1 = new omega::CG_roseRepr(
- isSgBinaryOp(op)->get_lhs_operand());
- std::vector<IR_ArrayRef *> a1 = FindArrayRef(r1);
- delete r1;
- std::copy(a1.begin(), a1.end(), back_inserter(arrays));
- omega::CG_roseRepr *r2 = new omega::CG_roseRepr(
- isSgBinaryOp(op)->get_rhs_operand());
- std::vector<IR_ArrayRef *> a2 = FindArrayRef(r2);
- delete r2;
- std::copy(a2.begin(), a2.end(), back_inserter(arrays));
- } else if (isSgUnaryOp(op)) {
- omega::CG_roseRepr *r1 = new omega::CG_roseRepr(
- isSgUnaryOp(op)->get_operand());
- std::vector<IR_ArrayRef *> a1 = FindArrayRef(r1);
- delete r1;
- std::copy(a1.begin(), a1.end(), back_inserter(arrays));
- }
-
- }
- return arrays;
-}
-
-std::vector<IR_Control *> IR_roseCode::FindOneLevelControlStructure(
- const IR_Block *block) const {
-
- std::vector<IR_Control *> controls;
- int i;
- int j;
- int begin;
- int end;
- SgNode* tnl_ =
- ((static_cast<IR_roseBlock *>(const_cast<IR_Block *>(block)))->tnl_);
-
- if (isSgForStatement(tnl_))
- controls.push_back(new IR_roseLoop(this, tnl_));
- else if (isSgFortranDo(tnl_))
- controls.push_back(new IR_roseLoop(this, tnl_));
- else if (isSgIfStmt(tnl_))
- controls.push_back(new IR_roseIf(this, tnl_));
-
- else if (isSgBasicBlock(tnl_)) {
-
- SgStatementPtrList& stmts = isSgBasicBlock(tnl_)->get_statements();
-
- for (i = 0; i < stmts.size(); i++) {
- if (isSgNode(stmts[i])
- == ((static_cast<IR_roseBlock *>(const_cast<IR_Block *>(block)))->start_))
- begin = i;
- if (isSgNode(stmts[i])
- == ((static_cast<IR_roseBlock *>(const_cast<IR_Block *>(block)))->end_))
- end = i;
- }
-
- SgNode* start = NULL;
- SgNode* prev = NULL;
- for (i = begin; i <= end; i++) {
- if (isSgForStatement(stmts[i]) || isSgFortranDo(stmts[i])) {
- if (start != NULL) {
- controls.push_back(
- new IR_roseBlock(this,
- (static_cast<IR_roseBlock *>(const_cast<IR_Block *>(block)))->tnl_,
- start, prev));
- start = NULL;
- }
- controls.push_back(new IR_roseLoop(this, isSgNode(stmts[i])));
- } else if (isSgIfStmt(stmts[i])) {
- if (start != NULL) {
- controls.push_back(
- new IR_roseBlock(this,
- (static_cast<IR_roseBlock *>(const_cast<IR_Block *>(block)))->tnl_,
- start, prev));
- start = NULL;
- }
- controls.push_back(new IR_roseIf(this, isSgNode(stmts[i])));
-
- } else if (start == NULL)
- start = isSgNode(stmts[i]);
-
- prev = isSgNode(stmts[i]);
- }
-
- if ((start != NULL) && (start != isSgNode(stmts[begin])))
- controls.push_back(
- new IR_roseBlock(this,
- (static_cast<IR_roseBlock *>(const_cast<IR_Block *>(block)))->tnl_,
- start, prev));
- }
-
- return controls;
-
-}
-
-IR_Block *IR_roseCode::MergeNeighboringControlStructures(
- const std::vector<IR_Control *> &controls) const {
- if (controls.size() == 0)
- return NULL;
-
- SgNode *tnl = NULL;
- SgNode *start, *end;
- for (int i = 0; i < controls.size(); i++) {
- switch (controls[i]->type()) {
- case IR_CONTROL_LOOP: {
- SgNode *tf = static_cast<IR_roseLoop *>(controls[i])->tf_;
- if (tnl == NULL) {
- tnl = tf->get_parent();
- start = end = tf;
- } else {
- if (tnl != tf->get_parent())
- throw ir_error("controls to merge not at the same level");
- end = tf;
- }
- break;
- }
- case IR_CONTROL_BLOCK: {
- if (tnl == NULL) {
- tnl = static_cast<IR_roseBlock *>(controls[0])->tnl_;
- start = static_cast<IR_roseBlock *>(controls[0])->start_;
- end = static_cast<IR_roseBlock *>(controls[0])->end_;
- } else {
- if (tnl != static_cast<IR_roseBlock *>(controls[0])->tnl_)
- throw ir_error("controls to merge not at the same level");
- end = static_cast<IR_roseBlock *>(controls[0])->end_;
- }
- break;
- }
- default:
- throw ir_error("unrecognized control to merge");
- }
- }
-
- return new IR_roseBlock(controls[0]->ir_, tnl, start, end);
-}
-
-IR_Block *IR_roseCode::GetCode() const {
- SgFunctionDefinition* def = NULL;
- SgBasicBlock* block = NULL;
- if (func != 0) {
- if (def = func->get_definition()) {
- if (block = def->get_body())
- return new IR_roseBlock(this,
- func->get_definition()->get_body());
- }
- }
-
- return NULL;
-
-}
-
-void IR_roseCode::ReplaceCode(IR_Control *old, omega::CG_outputRepr *repr) {
- SgStatementPtrList *tnl =
- static_cast<omega::CG_roseRepr *>(repr)->GetList();
- SgNode* node_ = static_cast<omega::CG_roseRepr *>(repr)->GetCode();
- SgNode * tf_old;
-
- /* May need future revision if tnl has more than one statement */
-
- switch (old->type()) {
-
- case IR_CONTROL_LOOP:
- tf_old = static_cast<IR_roseLoop *>(old)->tf_;
- break;
- case IR_CONTROL_BLOCK:
- tf_old = static_cast<IR_roseBlock *>(old)->start_;
- break;
-
- default:
- throw ir_error("control structure to be replaced not supported");
- break;
- }
-
- std::string y = tf_old->unparseToString();
- SgStatement *s = isSgStatement(tf_old);
- if (s != 0) {
- SgStatement *p = isSgStatement(tf_old->get_parent());
-
- if (p != 0) {
- SgStatement* temp = s;
- if (tnl != NULL) {
- SgStatementPtrList::iterator it = (*tnl).begin();
- p->insert_statement(temp, *it, true);
- temp = *it;
- p->remove_statement(s);
- it++;
- for (; it != (*tnl).end(); it++) {
- p->insert_statement(temp, *it, false);
- temp = *it;
- }
- } else if (node_ != NULL) {
- if (!isSgStatement(node_))
- throw ir_error("Replacing Code not a statement!");
- else {
- SgStatement* replace_ = isSgStatement(node_);
- p->insert_statement(s, replace_, true);
- p->remove_statement(s);
-
- }
- } else {
- throw ir_error("Replacing Code not a statement!");
- }
- } else
- throw ir_error("Replacing Code not a statement!");
- } else
- throw ir_error("Replacing Code not a statement!");
-
- delete old;
- delete repr;
-}
-
-void IR_roseCode::ReplaceExpression(IR_Ref *old, omega::CG_outputRepr *repr) {
-
- SgExpression* op = static_cast<omega::CG_roseRepr *>(repr)->GetExpression();
-
- if (typeid(*old) == typeid(IR_roseArrayRef)) {
- SgPntrArrRefExp* ia_orig = static_cast<IR_roseArrayRef *>(old)->ia_;
- SgExpression* parent = isSgExpression(isSgNode(ia_orig)->get_parent());
- std::string x = isSgNode(op)->unparseToString();
- std::string y = isSgNode(ia_orig)->unparseToString();
- if (parent != NULL) {
- std::string z = isSgNode(parent)->unparseToString();
- parent->replace_expression(ia_orig, op);
- isSgNode(op)->set_parent(isSgNode(parent));
- } else {
- SgStatement* parent_stmt = isSgStatement(
- isSgNode(ia_orig)->get_parent());
- if (parent_stmt != NULL)
- parent_stmt->replace_expression(ia_orig, op);
- else
- throw ir_error(
- "ReplaceExpression: parent neither expression nor statement");
- }
- } else
- throw ir_error("replacing a scalar variable not implemented");
-
- delete old;
-}
-
-IR_OPERATION_TYPE IR_roseCode::QueryExpOperation(
- const omega::CG_outputRepr *repr) const {
- SgExpression* op =
- static_cast<const omega::CG_roseRepr *>(repr)->GetExpression();
-
- if (isSgValueExp(op))
- return IR_OP_CONSTANT;
- else if (isSgVarRefExp(op) || isSgPntrArrRefExp(op))
- return IR_OP_VARIABLE;
- else if (isSgAssignOp(op) || isSgCompoundAssignOp(op))
- return IR_OP_ASSIGNMENT;
- else if (isSgAddOp(op))
- return IR_OP_PLUS;
- else if (isSgSubtractOp(op))
- return IR_OP_MINUS;
- else if (isSgMultiplyOp(op))
- return IR_OP_MULTIPLY;
- else if (isSgDivideOp(op))
- return IR_OP_DIVIDE;
- else if (isSgMinusOp(op))
- return IR_OP_NEGATIVE;
- else if (isSgConditionalExp(op)) {
- SgExpression* cond = isSgConditionalExp(op)->get_conditional_exp();
- if (isSgGreaterThanOp(cond))
- return IR_OP_MAX;
- else if (isSgLessThanOp(cond))
- return IR_OP_MIN;
- } else if (isSgUnaryAddOp(op))
- return IR_OP_POSITIVE;
- else if (isSgNullExpression(op))
- return IR_OP_NULL;
- else
- return IR_OP_UNKNOWN;
-}
-
-IR_CONDITION_TYPE IR_roseCode::QueryBooleanExpOperation(
- const omega::CG_outputRepr *repr) const {
- SgExpression* op2 =
- static_cast<const omega::CG_roseRepr *>(repr)->GetExpression();
- SgNode* op;
-
- if (op2 == NULL) {
- op = static_cast<const omega::CG_roseRepr *>(repr)->GetCode();
-
- if (op != NULL) {
- if (isSgExprStatement(op))
- op2 = isSgExprStatement(op)->get_expression();
- else
- return IR_COND_UNKNOWN;
- } else
- return IR_COND_UNKNOWN;
- }
-
- if (isSgEqualityOp(op2))
- return IR_COND_EQ;
- else if (isSgNotEqualOp(op2))
- return IR_COND_NE;
- else if (isSgLessThanOp(op2))
- return IR_COND_LT;
- else if (isSgLessOrEqualOp(op2))
- return IR_COND_LE;
- else if (isSgGreaterThanOp(op2))
- return IR_COND_GT;
- else if (isSgGreaterOrEqualOp(op2))
- return IR_COND_GE;
-
- return IR_COND_UNKNOWN;
-
-}
-
-std::vector<omega::CG_outputRepr *> IR_roseCode::QueryExpOperand(
- const omega::CG_outputRepr *repr) const {
- std::vector<omega::CG_outputRepr *> v;
- SgExpression* op1;
- SgExpression* op2;
- SgExpression* op =
- static_cast<const omega::CG_roseRepr *>(repr)->GetExpression();
- omega::CG_roseRepr *repr1;
-
- if (isSgValueExp(op) || isSgVarRefExp(op)) {
- omega::CG_roseRepr *repr = new omega::CG_roseRepr(op);
- v.push_back(repr);
- } else if (isSgAssignOp(op)) {
- op1 = isSgAssignOp(op)->get_rhs_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
- /*may be a problem as assignOp is a binaryop destop might be needed */
- } else if (isSgMinusOp(op)) {
- op1 = isSgMinusOp(op)->get_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
- } else if (isSgUnaryAddOp(op)) {
- op1 = isSgUnaryAddOp(op)->get_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
- } else if ((isSgAddOp(op) || isSgSubtractOp(op))
- || (isSgMultiplyOp(op) || isSgDivideOp(op))) {
- op1 = isSgBinaryOp(op)->get_lhs_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
-
- op2 = isSgBinaryOp(op)->get_rhs_operand();
- repr1 = new omega::CG_roseRepr(op2);
- v.push_back(repr1);
- } else if (isSgConditionalExp(op)) {
- SgExpression* cond = isSgConditionalExp(op)->get_conditional_exp();
- op1 = isSgBinaryOp(cond)->get_lhs_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
-
- op2 = isSgBinaryOp(cond)->get_rhs_operand();
- repr1 = new omega::CG_roseRepr(op2);
- v.push_back(repr1);
- } else if (isSgCompoundAssignOp(op)) {
- SgExpression* cond = isSgCompoundAssignOp(op);
- op1 = isSgBinaryOp(cond)->get_lhs_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
-
- op2 = isSgBinaryOp(cond)->get_rhs_operand();
- repr1 = new omega::CG_roseRepr(op2);
- v.push_back(repr1);
-
- } else if (isSgBinaryOp(op)) {
-
- op1 = isSgBinaryOp(op)->get_lhs_operand();
- repr1 = new omega::CG_roseRepr(op1);
- v.push_back(repr1);
-
- op2 = isSgBinaryOp(op)->get_rhs_operand();
- repr1 = new omega::CG_roseRepr(op2);
- v.push_back(repr1);
- }
-
- else
- throw ir_error("operation not supported");
-
- return v;
-}
-
-IR_Ref *IR_roseCode::Repr2Ref(const omega::CG_outputRepr *repr) const {
- SgExpression* op =
- static_cast<const omega::CG_roseRepr *>(repr)->GetExpression();
-
- if (SgValueExp* im = isSgValueExp(op)) {
- if (isSgIntVal(im))
- return new IR_roseConstantRef(this,
- static_cast<omega::coef_t>(isSgIntVal(im)->get_value()));
- else if (isSgUnsignedIntVal(im))
- return new IR_roseConstantRef(this,
- static_cast<omega::coef_t>(isSgUnsignedIntVal(im)->get_value()));
- else if (isSgLongIntVal(im))
- return new IR_roseConstantRef(this,
- static_cast<omega::coef_t>(isSgLongIntVal(im)->get_value()));
- else if (isSgFloatVal(im))
- return new IR_roseConstantRef(this, isSgFloatVal(im)->get_value());
- else
- assert(0);
-
- } else if (isSgVarRefExp(op))
- return new IR_roseScalarRef(this, isSgVarRefExp(op));
- else
- assert(0);
-
-}
-
diff --git a/src/ir_rose_utils.cc b/src/ir_rose_utils.cc
deleted file mode 100644
index 1329031..0000000
--- a/src/ir_rose_utils.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/*****************************************************************************
- Copyright (C) 2008 University of Southern California
- Copyright (C) 2009 University of Utah
- All Rights Reserved.
-
- Purpose:
- ROSE interface utilities.
-
- Notes:
-
- Update history:
- 01/2006 created by Chun Chen
-*****************************************************************************/
-
-#include "ir_rose_utils.hh"
-
-
-
-std::vector<SgForStatement *> find_loops(SgNode *tnl) {
- std::vector<SgForStatement *> result;
-
- SgStatementPtrList& blockStatements = isSgBasicBlock(tnl)->get_statements();
- for(SgStatementPtrList::const_iterator j = blockStatements.begin(); j != blockStatements.end(); j++)
- if(isSgForStatement(*j))
- result.push_back(isSgForStatement(*j));
-
- return result;
-}
-
-std::vector<SgForStatement *> find_deepest_loops(SgStatementPtrList& tnl) {
-
- std::vector<SgForStatement *> loops;
-
- for(SgStatementPtrList::const_iterator j = tnl.begin(); j != tnl.end(); j++)
- {
- std::vector<SgForStatement *> t = find_deepest_loops(isSgNode(*j));
- if (t.size() > loops.size())
- loops = t;
- }
-
- return loops;
-}
-
-std::vector<SgForStatement *> find_deepest_loops(SgNode *tn) {
- if (isSgForStatement(tn)) {
- std::vector<SgForStatement *> loops;
-
- SgForStatement *tnf = static_cast<SgForStatement*>(tn);
- loops.insert(loops.end(), tnf);
- std::vector<SgForStatement*> t = find_deepest_loops(isSgNode(tnf->get_loop_body()));
- std::copy(t.begin(), t.end(), std::back_inserter(loops));
-
- return loops;
- }
- else if (isSgBasicBlock(tn)) {
- SgBasicBlock *tnb = static_cast<SgBasicBlock*>(tn);
- return find_deepest_loops(tnb->get_statements());
- }
- else
- return std::vector<SgForStatement *>();
-}
-
diff --git a/src/irtools.cc b/src/irtools.cc
index e7e5029..16c4f7c 100644
--- a/src/irtools.cc
+++ b/src/irtools.cc
@@ -19,61 +19,80 @@
using namespace omega;
-std::vector<ir_tree_node *> build_ir_tree(IR_Control *control, ir_tree_node *parent) {
+// Build Chill IR tree from the source code (from the front end compiler's AST).
+// Block type node can only be a leaf, i.e., there are no further structures
+// inside a block allowed.
+std::vector<ir_tree_node *> build_ir_tree(IR_Control *control,
+ ir_tree_node *parent) {
std::vector<ir_tree_node *> result;
+ fprintf(stderr, "irtools.cc, build_ir_tree( control, parent) building a CHILL IR tree \n");
+
switch (control->type()) {
case IR_CONTROL_BLOCK: {
- std::vector<IR_Control *> controls = control->ir_->FindOneLevelControlStructure(static_cast<IR_Block *>(control));
+ fprintf(stderr, "irtools.cc L31 case IR_CONTROL_BLOCK\n");
+ IR_Block *IRCB = static_cast<IR_Block *>(control);
+ std::vector<IR_Control *> controls = control->ir_->FindOneLevelControlStructure(IRCB);
+
+ fprintf(stderr, "irtools.cc BACK FROM FindOneLevelControlStructure() %d controls\n", controls.size());
+
if (controls.size() == 0) {
+ fprintf(stderr, "controls.size() == 0\n");
+
ir_tree_node *node = new ir_tree_node;
- node->content = control;
- node->parent = parent;
+ node->content = control;
+ node->parent = parent;
node->payload = -1;
result.push_back(node);
}
else {
+ fprintf(stderr, "controls.size() == %d (NONZERO)\n", controls.size());
delete control;
+
for (int i = 0; i < controls.size(); i++)
switch (controls[i]->type()) {
case IR_CONTROL_BLOCK: {
+ fprintf(stderr, "controls[%d] is IR_CONTROL_BLOCK\n", i);
std::vector<ir_tree_node *> t = build_ir_tree(controls[i], parent);
result.insert(result.end(), t.begin(), t.end());
break;
}
case IR_CONTROL_LOOP: {
+ fprintf(stderr, "controls[%d] is IR_CONTROL_LOOP\n", i);
ir_tree_node *node = new ir_tree_node;
node->content = controls[i];
node->parent = parent;
- node->children = build_ir_tree(static_cast<IR_Loop *>(controls[i])->body(), node);
+ node->children = build_ir_tree(static_cast<IR_Loop *>(controls[i])->body(), node); // recurse
node->payload = -1;
result.push_back(node);
break;
}
case IR_CONTROL_IF: {
+ fprintf(stderr, "controls[%d] is IR_CONTROL_IF\n", i);
static int unique_if_identifier = 0;
- IR_Block *block = static_cast<IR_If *>(controls[i])->then_body();
+ IR_If* theif = static_cast<IR_If *>(controls[i]);
+ IR_Block *block = theif->then_body();
if (block != NULL) {
ir_tree_node *node = new ir_tree_node;
node->content = controls[i];
node->parent = parent;
- node->children = build_ir_tree(block, node);
+ node->children = build_ir_tree(block, node); // recurse
node->payload = unique_if_identifier+1;
result.push_back(node);
}
- block = static_cast<IR_If *>(controls[i])->else_body();
- if ( block != NULL) {
+ block = theif->else_body();
+ if (block != NULL) {
+ fprintf(stderr, "IF_CONTROL has an else\n");
ir_tree_node *node = new ir_tree_node;
node->content = controls[i]->clone();
node->parent = parent;
- node->children = build_ir_tree(block, node);
+ node->children = build_ir_tree(block, node); // recurse
node->payload = unique_if_identifier;
result.push_back(node);
}
-
unique_if_identifier += 2;
break;
}
@@ -89,42 +108,58 @@ std::vector<ir_tree_node *> build_ir_tree(IR_Control *control, ir_tree_node *par
break;
}
case IR_CONTROL_LOOP: {
+ fprintf(stderr, "case IR_CONTROL_LOOP\n");
ir_tree_node *node = new ir_tree_node;
node->content = control;
- node->parent = parent;
- node->children = build_ir_tree(static_cast<const IR_Loop *>(control)->body(), node);
+ node->parent = parent;
+ fprintf(stderr, "recursing. build_ir_tree() of CONTROL_LOOP creating children L122\n");
+ node->children = build_ir_tree(
+ static_cast<const IR_Loop *>(control)->body(), node);
node->payload = -1;
result.push_back(node);
+ fprintf(stderr, "recursing. build_ir_tree() of CONTROL_LOOP creating children DONE\n");
break;
}
default:
ir_tree_node *node = new ir_tree_node;
node->content = control;
- node->parent = parent;
+ node->parent = parent;
node->payload = -1;
result.push_back(node);
break;
}
+ fprintf(stderr, "build_ir_tree() vector result has %ld parts\n", result.size());
return result;
}
+
+// Extract statements from IR tree. Statements returned are ordered in
+// lexical order in the source code.
std::vector<ir_tree_node *> extract_ir_stmts(const std::vector<ir_tree_node *> &ir_tree) {
+
+ fprintf(stderr, "extract_ir_stmts() ir_tree.size() %d\n", ir_tree.size());
std::vector<ir_tree_node *> result;
for (int i = 0; i < ir_tree.size(); i++)
switch (ir_tree[i]->content->type()) {
+
case IR_CONTROL_BLOCK:
+ fprintf(stderr, "IR_CONTROL_BLOCK\n");
result.push_back(ir_tree[i]);
break;
+
case IR_CONTROL_LOOP: {
+ fprintf(stderr, "IR_CONTROL_LOOP( recursing )\n");
// clear loop payload from previous unsuccessful initialization process
ir_tree[i]->payload = -1;
std::vector<ir_tree_node *> t = extract_ir_stmts(ir_tree[i]->children);
+
result.insert(result.end(), t.begin(), t.end());
break;
}
case IR_CONTROL_IF: {
+ fprintf(stderr, "IR_CONTROL_IF( recursing )\n");
std::vector<ir_tree_node *> t = extract_ir_stmts(ir_tree[i]->children);
result.insert(result.end(), t.begin(), t.end());
break;
@@ -136,6 +171,20 @@ std::vector<ir_tree_node *> extract_ir_stmts(const std::vector<ir_tree_node *> &
return result;
}
+std::string chill_ir_control_type_string( IR_CONTROL_TYPE type ) {
+ switch(type) {
+ case IR_CONTROL_BLOCK: return std::string( "IR_CONTROL_BLOCK");
+ case IR_CONTROL_LOOP: return std::string( "IR_CONTROL_LOOP" );
+ case IR_CONTROL_IF: return std::string( "IR_CONTROL_IF" );
+ case IR_CONTROL_WHILE: return std::string( "IR_CONTROL_WHLIE"); break;
+ default: return std::string( "UNKNOWN_IR_NODE_TYPE" );
+ }
+}
+
+std::string chill_ir_node_type_string( ir_tree_node *node ) {
+ return chill_ir_control_type_string( node->content->type() );
+}
+
bool is_dependence_valid(ir_tree_node *src_node, ir_tree_node *dst_node,
const DependenceVector &dv, bool before) {
@@ -179,46 +228,240 @@ bool is_dependence_valid(ir_tree_node *src_node, ir_tree_node *dst_node,
}
-std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > test_data_dependences(
- IR_Code *ir, const CG_outputRepr *repr1, const Relation &IS1,
- const CG_outputRepr *repr2, const Relation &IS2,
- std::vector<Free_Var_Decl*> &freevar, std::vector<std::string> index,
- int i, int j) {
+
+//Anand: Adding function to collect the loop inductive and possibly if conditions
+//enclosing a statement
+
+std::vector<omega::CG_outputRepr *> collect_loop_inductive_and_conditionals(
+ ir_tree_node * stmt_node) {
+
+ std::vector<omega::CG_outputRepr *> to_return;
+ ir_tree_node *itn = stmt_node;
+
+ while (itn->parent != NULL) {
+ itn = itn->parent;
+
+ switch (itn->content->type()) {
+ case IR_CONTROL_LOOP: {
+ IR_Loop *lp = static_cast<IR_Loop *>(itn->content);
+ to_return.push_back(lp->lower_bound());
+ to_return.push_back(lp->upper_bound());
+
+ break;
+ }
+ case IR_CONTROL_IF: {
+ CG_outputRepr *cond =
+ static_cast<IR_If *>(itn->content)->condition();
+
+ to_return.push_back(cond);
+ break;
+ }
+ default:
+ throw std::invalid_argument("invalid ir tree");
+ }
+ }
+ return to_return;
+}
+
+
+// Test data dependences between two statements. The first statement
+// in parameter must be lexically before the second statement in
+// parameter. Returned dependences are all lexicographically
+// positive. The first vector in returned pair is dependences from the
+// first statement to the second statement and the second vector in
+// returned pair is in reverse order.
+std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> >
+test_data_dependences(IR_Code *ir,
+ const CG_outputRepr *repr1,
+ const Relation &IS1,
+ const CG_outputRepr *repr2,
+ const Relation &IS2,
+ std::vector<Free_Var_Decl*> &freevar,
+ std::vector<std::string> index,
+ int nestLeveli,
+ int nestLevelj,
+ std::map<std::string, std::vector<omega::CG_outputRepr * > > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr * > > &uninterpreted_symbols_stringrepr) {
+
+ fprintf(stderr, "\nirtools.cc test_data_dependences() %d freevars\n", freevar.size());
+ fprintf(stderr, "\nrepr1 %p ", repr1); repr1->dump(); fflush(stdout);
+ fprintf(stderr, "\nrepr2 %p ", repr2); repr2->dump(); fflush(stdout);
+
+ for (int i=0; i<index.size(); i++) fprintf(stderr, "index %d %s\n", i, index[i].c_str());
+ Relation *helper = new Relation(IS1); fprintf(stderr, "IS1 "); helper->print(); fflush(stdout);
+ helper = new Relation(IS2); fprintf(stderr, "IS2 "); helper->print(); fflush(stdout);
+
+
+ //for (int i=0; i<freevar.size(); i++) {
+ // std::string shit = (const std::string)(freevar[i]->base_name());
+
+ // fprintf(stderr, "freevar %d %s\n", i, shit.c_str());
+ //}
+
std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > result;
if (repr1 == repr2) {
+ fprintf(stderr, "repr1 == repr2\nrepr1->dump()\n");
+ repr1->dump();
+ fflush(stdout);
+
std::vector<IR_ArrayRef *> access = ir->FindArrayRef(repr1);
+ fprintf(stderr, "access of size %d\n", access.size());
+ for (int i = 0; i < access.size(); i++) {
+ IR_ArrayRef *a = access[i];
+
+ if (a->is_write()) {
+ fprintf(stderr, "WRITE array access %d = %s\n", i, a->name().c_str());
+ }
+ else {
+ fprintf(stderr, " array access %d = %s\n", i, a->name().c_str());
+ }
+ }
+ fprintf(stderr, "that was the list\n\n");
+
+ // Manu:: variables/structures added to identify dependence vectors related to reduction operation
+ tempResultMap trMap;
+ tempResultMap::iterator ittrMap;
+ int ref2Stmt[access.size()]; // mapping of reference to statement
+ std::set<int> nrStmts; // stores statements that can't be reduced
+ std::set<int> tnrStmts;
+ int stmtId = 1;
+ int tempStmtId = 1;
+ std::map<int,std::set<int> > rMap; // This maps statement number to a set of dependences
+ std::map<int, std::set<int> >::iterator itMap;
+ for (int i = 0; i < access.size(); i++) {
+ ref2Stmt[i] = -1;
+ }
+
+ // Manu -- changes for identifying possible reduction operation
+ // The below loop nest is used to classify array references into different statements
+ fprintf(stderr, "\nbefore mapRefstoStatements()\n");
+ mapRefstoStatements(ir,access,ref2Stmt,rMap,tnrStmts,nrStmts);
+ fprintf(stderr, "after mapRefstoStatements()\n\n");
+
+ //-------------------------------------------------------------
+ omega::coef_t lbound[3], ubound[3]; // for each kind of dependence. We can potentially have reduction only if all
+ // lbounds match and all ubounds match. At present, we only check the last loop level.
+ lbound[0] = lbound[1] = lbound[2] = LLONG_MAX;
+ ubound[0] = ubound[1] = ubound[2] = LLONG_MIN;
+ //-------------------------------------------------------------
for (int i = 0; i < access.size(); i++) {
+ fprintf(stderr, "i %d\n", i);
IR_ArrayRef *a = access[i];
IR_ArraySymbol *sym_a = a->symbol();
+ fprintf(stderr, "sym_a = %s\n", a->name().c_str());
for (int j = i; j < access.size(); j++) {
+ fprintf(stderr, "irtools.cc j %d\n", j);
IR_ArrayRef *b = access[j];
IR_ArraySymbol *sym_b = b->symbol();
+ fprintf(stderr, "sym_b = %s\n", b->name().c_str());
+
+ fprintf(stderr, "irtools.cc ij %d %d\n", i, j);
+ if (*sym_a == *sym_b) fprintf(stderr, "*sym_a == *sym_b\n");
+ else fprintf(stderr, "*sym_a NOT == *sym_b\n");
+
+ if ( a->is_write()) fprintf(stderr, "%d a->is_write()\n", i);
+ else fprintf(stderr, "%d a->is_NOT_write()\n", i);
+ if ( b->is_write()) fprintf(stderr, "%d b->is_write()\n", j);
+ else fprintf(stderr, "%d b->is_NOT_write()\n", j);
+
if (*sym_a == *sym_b && (a->is_write() || b->is_write())) {
- Relation r = arrays2relation(ir, freevar, a, IS1, b, IS2);
+ fprintf(stderr, "\nirtools.cc ij %d %d SYMBOL A == SYMBOL B and one is a write\n", i, j);
+ Relation r = arrays2relation(ir, freevar, a, IS1, b, IS2,uninterpreted_symbols,uninterpreted_symbols_stringrepr);
+ helper = new Relation(r); fprintf(stderr, "r "); helper->print(); fflush(stdout);
+
+
+ fprintf(stderr, "1\n");
std::pair<std::vector<DependenceVector>,
std::vector<DependenceVector> > dv =
relation2dependences(a, b, r);
- result.first.insert(result.first.end(), dv.first.begin(),
+ fprintf(stderr, "\nirtools.cc ij %d %d dv.first %d dv.second %d\n", i, j, dv.first.size(), dv.second.size());
+ fprintf(stderr, "2");
+ result.first.insert(result.first.end(), dv.first.begin(),
dv.first.end());
+ fprintf(stderr, "3");
result.second.insert(result.second.end(), dv.second.begin(),
dv.second.end());
+ fprintf(stderr, "4");
+
+ // Manu:: check if the array references belong to the same statement
+ // If yes, set the flag in the dependence vector
+ //----------------------------------------------
+ if(DEP_DEBUG){
+ std::cout << "Size of the dependence vector '" << a->name().c_str() << "' -- " << dv.first.size() << "\n";
+ std::cout << "------------ Printing dependence vector START ---------------\n";
+
+ for (std::vector<DependenceVector>::iterator itd = dv.first.begin(); itd != dv.first.end(); itd++){
+ if (itd->type == DEP_R2W)
+ std::cout<<"WAR\n";
+ else if (itd->type == DEP_W2R)
+ std::cout<<"RAW\n";
+ else if (itd->type == DEP_W2W)
+ std::cout<<"WAW\n";
+
+ std::vector<omega::coef_t>::iterator itu = itd->ubounds.begin();
+ for (std::vector<omega::coef_t>::iterator itl = itd->lbounds.begin(); itl != itd->lbounds.end(); itl++){
+ std::cout << "(" << *itl << ", " << *itu << ")\n";
+ itu++;
+ }
+ }
+ std::cout << "--------\n";
+ for (std::vector<DependenceVector>::iterator itd = dv.second.begin(); itd != dv.second.end(); itd++){
+ if (itd->type == DEP_R2W)
+ std::cout<<"WAR\n";
+ else if (itd->type == DEP_W2R)
+ std::cout<<"RAW\n";
+ else if (itd->type == DEP_W2W)
+ std::cout<<"WAW\n";
+
+ std::vector<omega::coef_t>::iterator itu = itd->ubounds.begin();
+ for (std::vector<omega::coef_t>::iterator itl = itd->lbounds.begin(); itl != itd->lbounds.end(); itl++){
+ std::cout << "(" << *itl << ", " << *itu << ")\n";
+ itu++;
+ }
+ }
+ std::cout << "------------ Printing dependence vector END---------------\n";
+ }
+ checkReductionDependence(i,j,nestLeveli,lbound,ubound,ref2Stmt,rMap,dv,trMap,nrStmts);
+ //----------------------------------------------
+
+// // Manu:: original code without the condition
+ if (((rMap.find(ref2Stmt[i])->second).size() != 3) || (lbound[0] != lbound[1]) || (lbound[1] != lbound[2]) ||
+ (lbound[0] != lbound[2]) || (ubound[0] != ubound[1]) || (ubound[1] != ubound[2]) || (ubound[0] != ubound[2])) { // Manu:: original code without the condition
+ result.first.insert(result.first.end(),
+ dv.first.begin(), dv.first.end());
+ result.second.insert(result.second.end(),
+ dv.second.begin(), dv.second.end());
+ }
+
+
}
delete sym_b;
}
delete sym_a;
-
+ }
+
+ // Manu
+ for (ittrMap = trMap.begin(); ittrMap != trMap.end(); ittrMap++) {
+ DVPair tdv = ittrMap->second;
+ result.first.insert(result.first.end(), tdv.first.begin(),
+ tdv.first.end());
+ result.second.insert(result.second.end(), tdv.second.begin(),
+ tdv.second.end());
}
for (int i = 0; i < access.size(); i++)
delete access[i];
} else {
+ fprintf(stderr, "\nrepr1 != repr2\n");
+
std::vector<IR_ArrayRef *> access1 = ir->FindArrayRef(repr1);
std::vector<IR_ArrayRef *> access2 = ir->FindArrayRef(repr2);
for (int i = 0; i < access1.size(); i++) {
+ fprintf(stderr, "i %d\n", i);
IR_ArrayRef *a = access1[i];
IR_ArraySymbol *sym_a = a->symbol();
@@ -226,7 +469,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > test_da
IR_ArrayRef *b = access2[j];
IR_ArraySymbol *sym_b = b->symbol();
if (*sym_a == *sym_b && (a->is_write() || b->is_write())) {
- Relation r = arrays2relation(ir, freevar, a, IS1, b, IS2);
+ Relation r = arrays2relation(ir, freevar, a, IS1, b, IS2, uninterpreted_symbols,uninterpreted_symbols_stringrepr);
std::pair<std::vector<DependenceVector>,
std::vector<DependenceVector> > dv =
relation2dependences(a, b, r);
@@ -246,6 +489,242 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > test_da
for (int i = 0; i < access2.size(); i++)
delete access2[i];
}
+ /*std::pair<std::vector<DependenceVector>,
+ std::vector<DependenceVector> > dv =
+ ir->FindScalarDeps(repr1, repr2, index, i, j);
+
+
+ result.first.insert(result.first.end(), dv.first.begin(),
+ dv.first.end());
+ result.second.insert(result.second.end(), dv.second.begin(),
+ dv.second.end());*/
+ /*result.first.insert(result.first.end(), dv.first.begin(),
+ dv.first.end());
+ result.second.insert(result.second.end(), dv.second.begin(),
+ dv.second.end());
+ */
+
+ fprintf(stderr, "LEAVING test_data_dependences() first size %d second size %d\n\n", result.first.size(), result.second.size());
return result;
}
+
+//Manu:: This function tests if two references are from the same statement
+//CG_outputRepr * from_same_statement(IR_Code *ir, IR_ArrayRef *a, IR_ArrayRef *b) {
+bool from_same_statement(IR_Code *ir, IR_ArrayRef *a, IR_ArrayRef *b) {
+ return ir->FromSameStmt(a,b);
+}
+
+// Manu
+int stmtType(IR_Code *ir, const CG_outputRepr *repr) {
+ fprintf(stderr, "stmtType() DIE \n");
+ exit(-1);
+ return (ir->getStmtType(repr)); /// AIEEE returns a meaningless number encoding rose internals.
+}
+
+// Manu:: set the reduction operation
+IR_OPERATION_TYPE getReductionOperator(IR_Code *ir, const CG_outputRepr *repr) {
+ return (ir->getReductionOp(repr));
+}
+
+// Manu:: map references to its corresponding statements
+void mapRefstoStatements(IR_Code *ir, std::vector<IR_ArrayRef *> access, int ref2Stmt[], std::map<int,std::set<int> >& rMap, std::set<int>& tnrStmts, std::set<int>& nrStmts) {
+
+ int stmtId = 1;
+ for (int i = 0; i < access.size(); i++) {
+ IR_ArrayRef *a = access[i];
+ IR_ArraySymbol *sym_a = a->symbol();
+ for (int j = i; j < access.size(); j++) {
+ IR_ArrayRef *b = access[j];
+ IR_ArraySymbol *sym_b = b->symbol();
+ bool inSameStmt;
+ if (from_same_statement(ir,access[i],access[j])) {
+ inSameStmt = true;
+// std::cout << "Manu:: inSameStmt " << a->name().c_str() << ", " << b->name().c_str() << "\n";
+ } else {
+ inSameStmt = false;
+// std::cout << "Manu:: NOT inSameStmt " << a->name().c_str() << ", " << b->name().c_str() << "\n";
+ }
+ if (inSameStmt) {
+ if (ref2Stmt[i] == -1)
+ ref2Stmt[i] = stmtId++;
+ ref2Stmt[j] = ref2Stmt[i];
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],std::set<int>()));
+ } else {
+ if (ref2Stmt[i] == -1)
+ ref2Stmt[i] = stmtId++;
+ if (ref2Stmt[j] == -1)
+ ref2Stmt[j] = stmtId++;
+ if (*sym_a == *sym_b && (a->is_write() || b->is_write())) {
+ tnrStmts.insert(i);
+ tnrStmts.insert(j);
+ }
+ }
+
+ }
+ }
+ std::set<int>::iterator itS;
+ for (itS = tnrStmts.begin(); itS != tnrStmts.end(); itS++) {
+ nrStmts.insert(ref2Stmt[*itS]);
+ }
+
+}
+
+// Manu:: This function tests reduction dependence and updates corresponding data structures
+void checkReductionDependence(int i, int j, int nestLeveli, omega::coef_t lbound[], omega::coef_t ubound[], int ref2Stmt[], std::map<int,std::set<int> >& rMap, DVPair& dv, tempResultMap& trMap, std::set<int> nrStmts ) {
+
+ std::map<int, std::set<int> >::iterator itMap;
+ tempResultMap::iterator ittrMap;
+ bool raw,war,waw, flg;
+ raw = war = waw = flg = false;
+ if ((ref2Stmt[i] == ref2Stmt[j]) && (nrStmts.find(ref2Stmt[i])== nrStmts.end())) {
+ for (int k = 0; k < dv.first.size(); k++) {
+ if ((dv.first[k].lbounds[nestLeveli-1] == 0) && (dv.first[k].ubounds[nestLeveli-1] == 0))
+ continue;
+ itMap = rMap.find(ref2Stmt[i]);
+ if (dv.first[k].type == DEP_R2W) {
+ war = true;
+ std::set<int> s = itMap->second;
+ s.insert(1); // war == 1
+ rMap.erase(itMap);
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],s));
+ if (lbound[0] > dv.first[k].lbounds[nestLeveli-1])
+ lbound[0] = dv.first[k].lbounds[nestLeveli-1];
+ if(ubound[0] < dv.first[k].ubounds[nestLeveli-1])
+ ubound[0] = dv.first[k].ubounds[nestLeveli-1];
+ } else if (dv.first[k].type == DEP_W2R) {
+ // for (int k1 = 0; k1 < dv.first[k].lbounds.size(); k1++) {
+ // omega::coef_t lbound = dv.first[k].lbounds[k1];
+ omega::coef_t lbound1 = dv.first[k].lbounds[nestLeveli-1];
+ if (lbound1 > 0) {
+ flg = true;
+ // break;
+ }
+ // }
+ raw = true;
+ if (raw) {
+ std::set<int> s = itMap->second;
+ s.insert(2); // raw == 2
+ rMap.erase(itMap);
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],s));
+ if (lbound[1] > dv.first[k].lbounds[nestLeveli-1])
+ lbound[1] = dv.first[k].lbounds[nestLeveli-1];
+ if(ubound[1] < dv.first[k].ubounds[nestLeveli-1])
+ ubound[1] = dv.first[k].ubounds[nestLeveli-1];
+ }
+ } else if (dv.first[k].type == DEP_W2W) {
+ waw = true;
+ std::set<int> s = itMap->second;
+ s.insert(3); // waw == 3
+ rMap.erase(itMap);
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],s));
+ if (lbound[2] > dv.first[k].lbounds[nestLeveli-1])
+ lbound[2] = dv.first[k].lbounds[nestLeveli-1];
+ if(ubound[2] < dv.first[k].ubounds[nestLeveli-1])
+ ubound[2] = dv.first[k].ubounds[nestLeveli-1];
+ }
+// std::cout<< "Manu:: Flags:: " << "raw " << raw << ", war " << war << ", waw " << waw << "\n";
+ }
+ flg = false;
+ for (int k = 0; k < dv.second.size(); k++) {
+ if ((dv.second[k].lbounds[nestLeveli-1] == 0) && (dv.second[k].ubounds[nestLeveli-1] == 0))
+ continue;
+ itMap = rMap.find(ref2Stmt[i]);
+ if (dv.second[k].type == DEP_R2W) {
+ war = true;
+ std::set<int> s = itMap->second;
+ s.insert(1); // war == 1
+ rMap.erase(itMap);
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],s));
+ if (lbound[0] > dv.second[k].lbounds[nestLeveli-1])
+ lbound[0] = dv.second[k].lbounds[nestLeveli-1];
+ if (ubound[0] < dv.second[k].ubounds[nestLeveli-1])
+ ubound[0] = dv.second[k].ubounds[nestLeveli-1];
+
+ } else if (dv.second[k].type == DEP_W2R) {
+ // for (int k1 = 0; k1 < dv.second[k].lbounds.size(); k1++) {
+ //omega::coef_t lbound = dv.second[k].lbounds[k1];
+ omega::coef_t lbound1 = dv.second[k].lbounds[nestLeveli-1];
+ if (lbound1 > 0) {
+ flg = true;
+ // break;
+ }
+ // }
+ raw = true;
+ if (raw) {
+ std::set<int> s = itMap->second;
+ s.insert(2); // raw == 2
+ rMap.erase(itMap);
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],s));
+ if (lbound[1] > dv.second[k].lbounds[nestLeveli-1])
+ lbound[1] = dv.second[k].lbounds[nestLeveli-1];
+ if (ubound[1] < dv.second[k].ubounds[nestLeveli-1])
+ ubound[1] = dv.second[k].ubounds[nestLeveli-1];
+
+ }
+
+ } else if (dv.second[k].type == DEP_W2W) {
+ waw = true;
+ std::set<int> s = itMap->second;
+ s.insert(3); // waw == 3
+ rMap.erase(itMap);
+ rMap.insert(std::pair<int,std::set<int> >(ref2Stmt[i],s));
+ if (lbound[2] > dv.second[k].lbounds[nestLeveli-1])
+ lbound[2] = dv.second[k].lbounds[nestLeveli-1];
+ if (ubound[2] < dv.second[k].ubounds[nestLeveli-1])
+ ubound[2] = dv.second[k].ubounds[nestLeveli-1];
+
+ }
+// std::cout<< "Manu:: Flags:: " << "raw " << raw << ", war " << war << ", waw " << waw << "\n";
+ }
+
+// if ((rMap.find(ref2Stmt[i])->second).size() == 3) {
+ if(DEP_DEBUG){
+ std::cout << "lbounds: " << lbound[0] << ", " << lbound[1] << ", " <<lbound[2] << "\n";
+ std::cout << "ubounds: " << ubound[0] << ", " << ubound[1] << ", " <<ubound[2] << "\n";
+ }
+ if (((rMap.find(ref2Stmt[i])->second).size() == 3) && (lbound[0] == lbound[1]) && (lbound[1] == lbound[2])
+ && (ubound[0] == ubound[1]) && (ubound[1] == ubound[2])) {
+// std::cout << "Manu:: All dependences present 1 \n";
+ for (int k = 0; k < dv.second.size(); k++)
+ dv.second[k].is_reduction_cand = true;
+ for (int k = 0; k < dv.first.size(); k++)
+ dv.first[k].is_reduction_cand = true;
+ trMap.insert(std::pair<int,DVPair>(ref2Stmt[i],DVPair(dv.first,dv.second)));
+ }
+ } else {
+ // tempArrayRefId[i] = tempArrayRefId[j] = 0;
+ for (int k = 0; k < dv.second.size(); k++)
+ dv.second[k].is_reduction_cand = false;
+ for (int k = 0; k < dv.first.size(); k++)
+ dv.first[k].is_reduction_cand = false;
+// reductionCand = false;
+ ittrMap = trMap.find(ref2Stmt[i]);
+ if (ittrMap != trMap.end()) {
+ DVPair tdv = ittrMap->second;
+ for (int k = 0; k < (tdv.first).size(); k++)
+ tdv.first[k].is_reduction_cand = false;
+ for (int k = 0; k < (tdv.second).size(); k++)
+ tdv.second[k].is_reduction_cand = false;
+ trMap.erase(ittrMap);
+ trMap.insert(std::pair<int,DVPair>(ref2Stmt[i],DVPair(tdv.first,tdv.second)));
+ }
+ }
+
+}
+
+
+
+void print_control( IR_Control *con ) {
+ IR_CONTROL_TYPE type = con->type();
+ fprintf(stderr, "this is IR_Control of type %s\n", chill_ir_control_type_string( type ).c_str());
+
+ switch (type) {
+ case IR_CONTROL_BLOCK:
+ case IR_CONTROL_LOOP:
+ case IR_CONTROL_IF:
+ case IR_CONTROL_WHILE:
+ default: return;
+ }
+
+}
diff --git a/src/loop.cc b/src/loop.cc
index 19378a4..5f863f2 100644
--- a/src/loop.cc
+++ b/src/loop.cc
@@ -26,6 +26,8 @@
#include <math.h>
#include <code_gen/codegen.h>
#include <code_gen/CG_utils.h>
+#include <code_gen/CG_stringRepr.h>
+#include <code_gen/CG_chillRepr.h> // Mark. Bad idea. TODO
#include <iostream>
#include <algorithm>
#include <map>
@@ -35,11 +37,258 @@
#include "chill_error.hh"
#include <string.h>
#include <list>
+
+// TODO
+#define _DEBUG_ true
+
+
+
using namespace omega;
const std::string Loop::tmp_loop_var_name_prefix = std::string("chill_t"); // Manu:: In fortran, first character of a variable name must be a letter, so this change
const std::string Loop::overflow_var_name_prefix = std::string("over");
+void echocontroltype( const IR_Control *control ) {
+ switch(control->type()) {
+ case IR_CONTROL_BLOCK: {
+ fprintf(stderr, "IR_CONTROL_BLOCK\n");
+ break;
+ }
+ case IR_CONTROL_LOOP: {
+ fprintf(stderr, "IR_CONTROL_LOOP\n");
+ break;
+ }
+ case IR_CONTROL_IF: {
+ fprintf(stderr, "IR_CONTROL_IF\n");
+ break;
+ }
+ default:
+ fprintf(stderr, "just a bunch of statements?\n");
+
+ } // switch
+}
+
+omega::Relation Loop::getNewIS(int stmt_num) const {
+
+ omega::Relation result;
+
+ if (stmt[stmt_num].xform.is_null()) {
+ omega::Relation known = omega::Extend_Set(omega::copy(this->known),
+ stmt[stmt_num].IS.n_set() - this->known.n_set());
+ result = omega::Intersection(omega::copy(stmt[stmt_num].IS), known);
+ } else {
+ omega::Relation known = omega::Extend_Set(omega::copy(this->known),
+ stmt[stmt_num].xform.n_out() - this->known.n_set());
+ result = omega::Intersection(
+ omega::Range(
+ omega::Restrict_Domain(
+ omega::copy(stmt[stmt_num].xform),
+ omega::copy(stmt[stmt_num].IS))), known);
+ }
+
+ result.simplify(2, 4);
+
+ return result;
+}
+
+
+
+void Loop::reduce(int stmt_num,
+ std::vector<int> &level,
+ int param,
+ std::string func_name,
+ std::vector<int> &seq_levels,
+ std::vector<int> cudaized_levels,
+ int bound_level) {
+
+ // illegal instruction?? fprintf(stderr, " Loop::reduce( stmt %d, param %d, func_name (encrypted)...)\n", stmt, param); // , func_name.c_str());
+
+ //std::cout << "Reducing stmt# " << stmt_num << " at level " << level << "\n";
+ //ir->printStmt(stmt[stmt_num].code);
+
+ if (stmt[stmt_num].reduction != 1) {
+ std::cout << "loop.cc Cannot reduce this statement\n";
+ return;
+ }
+ fprintf(stderr, "loop.cc CAN reduce this statment?\n");
+
+ /*for (int i = 0; i < level.size(); i++)
+ if (stmt[stmt_num].loop_level[level[i] - 1].segreducible != true) {
+ std::cout << "Cannot reduce this statement\n";
+ return;
+ }
+ for (int i = 0; i < seq_levels.size(); i++)
+ if (stmt[stmt_num].loop_level[seq_levels[i] - 1].segreducible != true) {
+ std::cout << "Cannot reduce this statement\n";
+ return;
+ }
+ */
+ // std::pair<int, std::string> to_insert(level, func_name);
+ // reduced_statements.insert(std::pair<int, std::pair<int, std::string> >(stmt_num, to_insert ));
+ // invalidate saved codegen computation
+ delete last_compute_cgr_;
+ last_compute_cgr_ = NULL;
+ delete last_compute_cg_;
+ last_compute_cg_ = NULL;
+ fprintf(stderr, "set last_compute_cg_ = NULL;\n");
+
+ omega::CG_outputBuilder *ocg = ir->builder();
+
+ omega::CG_outputRepr *funCallRepr;
+ std::vector<omega::CG_outputRepr *> arg_repr_list;
+ apply_xform(stmt_num);
+ std::vector<IR_ArrayRef *> access = ir->FindArrayRef(stmt[stmt_num].code);
+ std::set<std::string> names;
+ for (int i = 0; i < access.size(); i++) {
+ std::vector<IR_ArrayRef *> access2;
+ for (int j = 0; j < access[i]->n_dim(); j++) {
+ std::vector<IR_ArrayRef *> access3 = ir->FindArrayRef(
+ access[i]->index(j));
+ access2.insert(access2.end(), access3.begin(), access3.end());
+ }
+ if (access2.size() == 0) {
+ if (names.find(access[i]->name()) == names.end()) {
+ arg_repr_list.push_back(
+ ocg->CreateAddressOf(access[i]->convert()));
+ names.insert(access[i]->name());
+ if (access[i]->is_write())
+ reduced_write_refs.insert(access[i]->name());
+ }
+ } else {
+ if (names.find(access[i]->name()) == names.end()) {
+ arg_repr_list.push_back(ocg->CreateAddressOf(ocg->CreateArrayRefExpression(ocg->CreateIdent(access[i]->name()),
+ ocg->CreateInt(0))));
+ names.insert(access[i]->name());
+ if (access[i]->is_write())
+ reduced_write_refs.insert(access[i]->name());
+ }
+ }
+ }
+
+ for (int i = 0; i < seq_levels.size(); i++)
+ arg_repr_list.push_back(
+ ocg->CreateIdent(
+ stmt[stmt_num].IS.set_var(seq_levels[i])->name()));
+
+ if (bound_level != -1) {
+
+ omega::Relation new_IS = copy(stmt[stmt_num].IS);
+ new_IS.copy_names(stmt[stmt_num].IS);
+ new_IS.setup_names();
+ new_IS.simplify();
+ int dim = bound_level;
+ //omega::Relation r = getNewIS(stmt_num);
+ for (int j = dim + 1; j <= new_IS.n_set(); j++)
+ new_IS = omega::Project(new_IS, new_IS.set_var(j));
+
+ new_IS.simplify(2, 4);
+
+ omega::Relation bound_ = get_loop_bound(copy(new_IS), dim - 1);
+ omega::Variable_ID v = bound_.set_var(dim);
+ std::vector<omega::CG_outputRepr *> ubList;
+ for (omega::GEQ_Iterator e(
+ const_cast<omega::Relation &>(bound_).single_conjunct()->GEQs());
+ e; e++) {
+ if ((*e).get_coef(v) < 0) {
+ // && (*e).is_const_except_for_global(v))
+ omega::CG_outputRepr *UPPERBOUND =
+ omega::output_upper_bound_repr(ir->builder(), *e, v,
+ bound_,
+ std::vector<
+ std::pair<omega::CG_outputRepr *, int> >(
+ bound_.n_set(),
+ std::make_pair(
+ static_cast<omega::CG_outputRepr *>(NULL),
+ 0)), uninterpreted_symbols[stmt_num]);
+ if (UPPERBOUND != NULL)
+ ubList.push_back(UPPERBOUND);
+
+ }
+
+ }
+
+ omega::CG_outputRepr * ubRepr;
+ if (ubList.size() > 1) {
+
+ ubRepr = ir->builder()->CreateInvoke("min", ubList);
+ arg_repr_list.push_back(ubRepr);
+ } else if (ubList.size() == 1)
+ arg_repr_list.push_back(ubList[0]);
+ }
+
+ funCallRepr = ocg->CreateInvoke(func_name, arg_repr_list);
+ stmt[stmt_num].code = funCallRepr;
+ for (int i = 0; i < level.size(); i++) {
+ //stmt[*i].code = outputStatement(ocg, stmt[*i].code, 0, mapping, known, std::vector<CG_outputRepr *>(mapping.n_out(), NULL));
+ std::vector<std::string> loop_vars;
+ loop_vars.push_back(stmt[stmt_num].IS.set_var(level[i])->name());
+
+ std::vector<omega::CG_outputRepr *> subs;
+ subs.push_back(ocg->CreateInt(0));
+
+ stmt[stmt_num].code = ocg->CreateSubstitutedStmt(0, stmt[stmt_num].code,
+ loop_vars, subs);
+
+ }
+
+ omega::Relation new_IS = copy(stmt[stmt_num].IS);
+ new_IS.copy_names(stmt[stmt_num].IS);
+ new_IS.setup_names();
+ new_IS.simplify();
+ int old_size = new_IS.n_set();
+
+ omega::Relation R = omega::copy(stmt[stmt_num].IS);
+ R.copy_names(stmt[stmt_num].IS);
+ R.setup_names();
+
+ for (int i = level.size() - 1; i >= 0; i--) {
+ int j;
+
+ for (j = 0; j < cudaized_levels.size(); j++) {
+ if (cudaized_levels[j] == level[i])
+ break;
+
+ }
+
+ if (j == cudaized_levels.size()) {
+ R = omega::Project(R, level[i], omega::Input_Var);
+ R.simplify();
+
+ }
+ //
+
+ }
+
+ omega::F_And *f_Root = R.and_with_and();
+ for (int i = level.size() - 1; i >= 0; i--) {
+ int j;
+
+ for (j = 0; j < cudaized_levels.size(); j++) {
+ if (cudaized_levels[j] == level[i])
+ break;
+
+ }
+
+ if (j == cudaized_levels.size()) {
+
+ omega::EQ_Handle h = f_Root->add_EQ();
+
+ h.update_coef(R.set_var(level[i]), 1);
+ h.update_const(-1);
+ }
+ //
+
+ }
+
+ R.simplify();
+ stmt[stmt_num].IS = R;
+}
+
+
+
+
+
+
//-----------------------------------------------------------------------------
// Class Loop
//-----------------------------------------------------------------------------
@@ -53,11 +302,24 @@ bool Loop::isInitialized() const {
bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
std::vector<ir_tree_node *> &ir_stmt) {
+
+ fprintf(stderr, "\n Loop::init_loop()\n");
+
+ fprintf(stderr, "extract_ir_stmts()\n");
+ fprintf(stderr, "ir_tree has %d statements\n", ir_tree.size());
ir_stmt = extract_ir_stmts(ir_tree);
+
+ fprintf(stderr,"nesting level stmt size = %d\n", (int)ir_stmt.size());
stmt_nesting_level_.resize(ir_stmt.size());
+
std::vector<int> stmt_nesting_level(ir_stmt.size());
+
+ fprintf(stderr, "%d statements?\n", (int)ir_stmt.size());
+
+ // find out how deeply nested each statement is. (how can these be different?)
for (int i = 0; i < ir_stmt.size(); i++) {
+ fprintf(stderr, "i %d\n", i);
ir_stmt[i]->payload = i;
int t = 0;
ir_tree_node *itn = ir_stmt[i];
@@ -68,145 +330,240 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
}
stmt_nesting_level_[i] = t;
stmt_nesting_level[i] = t;
+ fprintf(stderr, "stmt_nesting_level[%d] = %d\n", i, t);
}
-
+
+ if (actual_code.size() == 0)
+ actual_code = std::vector<CG_outputRepr*>(ir_stmt.size());
+
stmt = std::vector<Statement>(ir_stmt.size());
+ fprintf(stderr, "in init_loop, made %d stmts\n", (int)ir_stmt.size());
+
+ uninterpreted_symbols = std::vector<std::map<std::string, std::vector<omega::CG_outputRepr * > > >(ir_stmt.size());
+ uninterpreted_symbols_stringrepr = std::vector<std::map<std::string, std::vector<omega::CG_outputRepr * > > >(ir_stmt.size());
+
int n_dim = -1;
int max_loc;
//std::vector<std::string> index;
for (int i = 0; i < ir_stmt.size(); i++) {
int max_nesting_level = -1;
int loc;
- for (int j = 0; j < ir_stmt.size(); j++)
+
+ // find the max nesting level and remember the statement that was at that level
+ for (int j = 0; j < ir_stmt.size(); j++) {
if (stmt_nesting_level[j] > max_nesting_level) {
max_nesting_level = stmt_nesting_level[j];
loc = j;
}
-
+ }
+
+ fprintf(stderr, "max nesting level %d at location %d\n", max_nesting_level, loc);
+
// most deeply nested statement acting as a reference point
if (n_dim == -1) {
+ fprintf(stderr, "loop.cc L356 n_dim now max_nesting_level %d\n", max_nesting_level);
n_dim = max_nesting_level;
max_loc = loc;
-
+
index = std::vector<std::string>(n_dim);
-
+
ir_tree_node *itn = ir_stmt[loc];
+ fprintf(stderr, "itn = stmt[%d]\n", loc);
int cur_dim = n_dim - 1;
while (itn->parent != NULL) {
+ fprintf(stderr, "parent\n");
+
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP) {
- index[cur_dim] =
- static_cast<IR_Loop *>(itn->content)->index()->name();
+ fprintf(stderr, "IR_CONTROL_LOOP cur_dim %d\n", cur_dim);
+ IR_Loop *IRL = static_cast<IR_Loop *>(itn->content);
+ index[cur_dim] = IRL->index()->name();
+ fprintf(stderr, "index[%d] = '%s'\n", cur_dim, index[cur_dim].c_str());
itn->payload = cur_dim--;
}
}
}
-
+
+ fprintf(stderr, "align loops by names,\n");
// align loops by names, temporary solution
- ir_tree_node *itn = ir_stmt[loc];
+ ir_tree_node *itn = ir_stmt[loc]; // defined outside loops??
int depth = stmt_nesting_level_[loc] - 1;
+
for (int t = depth; t >= 0; t--) {
int y = t;
- ir_tree_node *itn = ir_stmt[loc];
-
+ itn = ir_stmt[loc];
+
while ((itn->parent != NULL) && (y >= 0)) {
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP)
y--;
}
-
+
if (itn->content->type() == IR_CONTROL_LOOP && itn->payload == -1) {
CG_outputBuilder *ocg = ir->builder();
-
+
itn->payload = depth - t;
-
+
CG_outputRepr *code =
static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
-
+
std::vector<CG_outputRepr *> index_expr;
std::vector<std::string> old_index;
CG_outputRepr *repl = ocg->CreateIdent(index[itn->payload]);
index_expr.push_back(repl);
old_index.push_back(
- static_cast<IR_Loop *>(itn->content)->index()->name());
+ static_cast<IR_Loop *>(itn->content)->index()->name());
code = ocg->CreateSubstitutedStmt(0, code, old_index,
index_expr);
-
+
replace.insert(std::pair<int, CG_outputRepr*>(loc, code));
+ //stmt[loc].code = code;
+
}
}
-
+
+ fprintf(stderr, "\nset relation variable names ****\n");
// set relation variable names
+
+ // this finds the loop variables for loops enclosing this statement and puts
+ // them in an Omega Relation (just their names, which could fail)
+
+ fprintf(stderr, "Relation r(%d)\n", n_dim);
Relation r(n_dim);
F_And *f_root = r.add_and();
itn = ir_stmt[loc];
int temp_depth = depth;
while (itn->parent != NULL) {
-
+
itn = itn->parent;
if (itn->content->type() == IR_CONTROL_LOOP) {
+ fprintf(stderr, "it's a loop. temp_depth %d\n", temp_depth);
+ fprintf(stderr, "r.name_set_var( %d, %s )\n", itn->payload + 1, index[temp_depth].c_str());
r.name_set_var(itn->payload + 1, index[temp_depth]);
-
+
temp_depth--;
}
+ //static_cast<IR_Loop *>(itn->content)->index()->name());
}
-
+ fprintf(stderr, "Relation r "); r.print(); fflush(stdout);
+ //fprintf(stderr, "f_root "); f_root->print(stderr); fprintf(stderr, "\n");
+
+ /*while (itn->parent != NULL) {
+ itn = itn->parent;
+ if (itn->content->type() == IR_CONTROL_LOOP)
+ r.name_set_var(itn->payload+1, static_cast<IR_Loop *>(itn->content)->index()->name());
+ }*/
+
+
+
+
+ fprintf(stderr, "extract information from loop/if structures\n");
// extract information from loop/if structures
std::vector<bool> processed(n_dim, false);
std::vector<std::string> vars_to_be_reversed;
+
+ std::vector<std::string> insp_lb;
+ std::vector<std::string> insp_ub;
+
itn = ir_stmt[loc];
- while (itn->parent != NULL) {
+ while (itn->parent != NULL) { // keep heading upward
itn = itn->parent;
-
+
switch (itn->content->type()) {
case IR_CONTROL_LOOP: {
+ fprintf(stderr, "loop.cc l 462 IR_CONTROL_LOOP\n");
IR_Loop *lp = static_cast<IR_Loop *>(itn->content);
Variable_ID v = r.set_var(itn->payload + 1);
int c;
-
+
try {
c = lp->step_size();
+ //fprintf(stderr, "step size %d\n", c);
if (c > 0) {
CG_outputRepr *lb = lp->lower_bound();
+ fprintf(stderr, "loop.cc, got the lower bound. it is:\n");
+ lb->dump(); printf("\n"); fflush(stdout);
+
exp2formula(ir, r, f_root, freevar, lb, v, 's',
- IR_COND_GE, true);
+ IR_COND_GE, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
+
CG_outputRepr *ub = lp->upper_bound();
+ //fprintf(stderr, "loop.cc, got the upper bound. it is:\n");
+ //ub->dump(); printf("\n"); fflush(stdout);
+
+
+
IR_CONDITION_TYPE cond = lp->stop_cond();
if (cond == IR_COND_LT || cond == IR_COND_LE)
exp2formula(ir, r, f_root, freevar, ub, v, 's',
- cond, true);
+ cond, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
else
throw ir_error("loop condition not supported");
-
+
+
+ if ((ir->QueryExpOperation(lp->lower_bound())
+ == IR_OP_ARRAY_VARIABLE)
+ && (ir->QueryExpOperation(lp->lower_bound())
+ == ir->QueryExpOperation(
+ lp->upper_bound()))) {
+
+ fprintf(stderr, "loop.cc lower and upper are both IR_OP_ARRAY_VARIABLE?\n");
+
+ std::vector<CG_outputRepr *> v =
+ ir->QueryExpOperand(lp->lower_bound());
+ IR_ArrayRef *ref =
+ static_cast<IR_ArrayRef *>(ir->Repr2Ref(
+ v[0]));
+ std::string s0 = ref->name();
+ std::vector<CG_outputRepr *> v2 =
+ ir->QueryExpOperand(lp->upper_bound());
+ IR_ArrayRef *ref2 =
+ static_cast<IR_ArrayRef *>(ir->Repr2Ref(
+ v2[0]));
+ std::string s1 = ref2->name();
+
+ if (s0 == s1) {
+ insp_lb.push_back(s0);
+ insp_ub.push_back(s1);
+
+ }
+
+ }
+
+
} else if (c < 0) {
CG_outputBuilder *ocg = ir->builder();
CG_outputRepr *lb = lp->lower_bound();
lb = ocg->CreateMinus(NULL, lb);
exp2formula(ir, r, f_root, freevar, lb, v, 's',
- IR_COND_GE, true);
+ IR_COND_GE, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
CG_outputRepr *ub = lp->upper_bound();
ub = ocg->CreateMinus(NULL, ub);
IR_CONDITION_TYPE cond = lp->stop_cond();
if (cond == IR_COND_GE)
exp2formula(ir, r, f_root, freevar, ub, v, 's',
- IR_COND_LE, true);
+ IR_COND_LE, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
else if (cond == IR_COND_GT)
exp2formula(ir, r, f_root, freevar, ub, v, 's',
- IR_COND_LT, true);
+ IR_COND_LT, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
else
throw ir_error("loop condition not supported");
-
+
vars_to_be_reversed.push_back(lp->index()->name());
} else
throw ir_error("loop step size zero");
} catch (const ir_error &e) {
+ actual_code[loc] =
+ static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
for (int i = 0; i < itn->children.size(); i++)
delete itn->children[i];
itn->children = std::vector<ir_tree_node *>();
itn->content = itn->content->convert();
return false;
}
-
+
+ // check for loop increment or decrement that is not 1
+ //fprintf(stderr, "abs(c)\n");
if (abs(c) != 1) {
F_Exists *f_exists = f_root->add_exists();
Variable_ID e = f_exists->declare();
@@ -219,22 +576,28 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
h.update_coef(v, -1);
CG_outputRepr *lb = lp->lower_bound();
exp2formula(ir, r, f_and, freevar, lb, e, 's', IR_COND_EQ,
- true);
+ true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
}
-
+
processed[itn->payload] = true;
break;
}
+
+
case IR_CONTROL_IF: {
+ fprintf(stderr, "IR_CONTROL_IF\n");
+ IR_If *theif = static_cast<IR_If *>(itn->content);
+
CG_outputRepr *cond =
static_cast<IR_If *>(itn->content)->condition();
+
try {
if (itn->payload % 2 == 1)
- exp2constraint(ir, r, f_root, freevar, cond, true);
+ exp2constraint(ir, r, f_root, freevar, cond, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
else {
F_Not *f_not = f_root->add_not();
F_And *f_and = f_not->add_and();
- exp2constraint(ir, r, f_and, freevar, cond, true);
+ exp2constraint(ir, r, f_and, freevar, cond, true,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
}
} catch (const ir_error &e) {
std::vector<ir_tree_node *> *t;
@@ -258,10 +621,11 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
}
return false;
}
-
+
break;
}
default:
+ //fprintf(stderr, "default?\n");
for (int i = 0; i < itn->children.size(); i++)
delete itn->children[i];
itn->children = std::vector<ir_tree_node *>();
@@ -269,7 +633,9 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
return false;
}
}
-
+
+
+ //fprintf(stderr, "add information for missing loops n_dim(%d)\n", n_dim);
// add information for missing loops
for (int j = 0; j < n_dim; j++)
if (!processed[j]) {
@@ -280,32 +646,138 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
&& itn->payload == j)
break;
}
-
+
Variable_ID v = r.set_var(j + 1);
if (loc < max_loc) {
-
+
CG_outputBuilder *ocg = ir->builder();
-
+
CG_outputRepr *lb =
static_cast<IR_Loop *>(itn->content)->lower_bound();
-
+
exp2formula(ir, r, f_root, freevar, lb, v, 's', IR_COND_EQ,
- false);
-
+ false,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
+
+ /* if (ir->QueryExpOperation(
+ static_cast<IR_Loop *>(itn->content)->lower_bound())
+ == IR_OP_VARIABLE) {
+ IR_ScalarRef *ref =
+ static_cast<IR_ScalarRef *>(ir->Repr2Ref(
+ static_cast<IR_Loop *>(itn->content)->lower_bound()));
+ std::string name_ = ref->name();
+
+ for (int i = 0; i < index.size(); i++)
+ if (index[i] == name_) {
+ exp2formula(ir, r, f_root, freevar, lb, v, 's',
+ IR_COND_GE, false);
+
+ CG_outputRepr *ub =
+ static_cast<IR_Loop *>(itn->content)->upper_bound();
+ IR_CONDITION_TYPE cond =
+ static_cast<IR_Loop *>(itn->content)->stop_cond();
+ if (cond == IR_COND_LT || cond == IR_COND_LE)
+ exp2formula(ir, r, f_root, freevar, ub, v,
+ 's', cond, false);
+
+
+
+ }
+
+ }
+ */
+
} else { // loc > max_loc
-
+
CG_outputBuilder *ocg = ir->builder();
CG_outputRepr *ub =
static_cast<IR_Loop *>(itn->content)->upper_bound();
-
+
exp2formula(ir, r, f_root, freevar, ub, v, 's', IR_COND_EQ,
- false);
+ false,uninterpreted_symbols[i],uninterpreted_symbols_stringrepr[i]);
+ /*if (ir->QueryExpOperation(
+ static_cast<IR_Loop *>(itn->content)->upper_bound())
+ == IR_OP_VARIABLE) {
+ IR_ScalarRef *ref =
+ static_cast<IR_ScalarRef *>(ir->Repr2Ref(
+ static_cast<IR_Loop *>(itn->content)->upper_bound()));
+ std::string name_ = ref->name();
+
+ for (int i = 0; i < index.size(); i++)
+ if (index[i] == name_) {
+
+ CG_outputRepr *lb =
+ static_cast<IR_Loop *>(itn->content)->lower_bound();
+
+ exp2formula(ir, r, f_root, freevar, lb, v, 's',
+ IR_COND_GE, false);
+
+ CG_outputRepr *ub =
+ static_cast<IR_Loop *>(itn->content)->upper_bound();
+ IR_CONDITION_TYPE cond =
+ static_cast<IR_Loop *>(itn->content)->stop_cond();
+ if (cond == IR_COND_LT || cond == IR_COND_LE)
+ exp2formula(ir, r, f_root, freevar, ub, v,
+ 's', cond, false);
+
+
+ }
+ }
+ */
}
}
-
+
r.setup_names();
r.simplify();
-
+
+ // THIS IS MISSING IN PROTONU's
+ for (int j = 0; j < insp_lb.size(); j++) {
+
+ std::string lb = insp_lb[j] + "_";
+ std::string ub = lb + "_";
+
+ Global_Var_ID u, l;
+ bool found_ub = false;
+ bool found_lb = false;
+ for (DNF_Iterator di(copy(r).query_DNF()); di; di++)
+ for (Constraint_Iterator ci = (*di)->constraints(); ci; ci++)
+
+ for (Constr_Vars_Iter cvi(*ci); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ if (v->kind() == Global_Var)
+ if (v->get_global_var()->arity() > 0) {
+
+ std::string name =
+ v->get_global_var()->base_name();
+ if (name == lb) {
+ l = v->get_global_var();
+ found_lb = true;
+ } else if (name == ub) {
+ u = v->get_global_var();
+ found_ub = true;
+ }
+ }
+
+ }
+
+ if (found_lb && found_ub) {
+ Relation known_(copy(r).n_set());
+ known_.copy_names(copy(r));
+ known_.setup_names();
+ Variable_ID index_lb = known_.get_local(l, Input_Tuple);
+ Variable_ID index_ub = known_.get_local(u, Input_Tuple);
+ F_And *fr = known_.add_and();
+ GEQ_Handle g = fr->add_GEQ();
+ g.update_coef(index_ub, 1);
+ g.update_coef(index_lb, -1);
+ g.update_const(-1);
+ addKnown(known_);
+
+ }
+
+ }
+
+
+ fprintf(stderr, "loop.cc L441 insert the statement\n");
// insert the statement
CG_outputBuilder *ocg = ir->builder();
std::vector<CG_outputRepr *> reverse_expr;
@@ -314,51 +786,96 @@ bool Loop::init_loop(std::vector<ir_tree_node *> &ir_tree,
repl = ocg->CreateMinus(NULL, repl);
reverse_expr.push_back(repl);
}
+ fprintf(stderr, "loop.cc before extract\n");
CG_outputRepr *code =
static_cast<IR_Block *>(ir_stmt[loc]->content)->extract();
+ fprintf(stderr, "code = ocg->CreateSubstitutedStmt(...)\n");
+ ((CG_chillRepr *)code)->Dump(); fflush(stdout);
+
code = ocg->CreateSubstitutedStmt(0, code, vars_to_be_reversed,
reverse_expr);
+ fprintf(stderr, "stmt\n");
+ ((CG_chillRepr *)code)->Dump(); fflush(stdout);
+
stmt[loc].code = code;
stmt[loc].IS = r;
+
+ //Anand: Add Information on uninterpreted function constraints to
+ //Known relation
+
+ fprintf(stderr, "loop.cc stmt[%d].loop_level has size n_dim %d\n", loc, n_dim);
+
stmt[loc].loop_level = std::vector<LoopLevel>(n_dim);
stmt[loc].ir_stmt_node = ir_stmt[loc];
- for (int i = 0; i < n_dim; i++) {
- stmt[loc].loop_level[i].type = LoopLevelOriginal;
- stmt[loc].loop_level[i].payload = i;
- stmt[loc].loop_level[i].parallel_level = 0;
+ stmt[loc].has_inspector = false;
+ fprintf(stderr, "for int i < n_dim(%d)\n", n_dim);
+ for (int ii = 0; ii < n_dim; ii++) {
+ stmt[loc].loop_level[ii].type = LoopLevelOriginal;
+ stmt[loc].loop_level[ii].payload = ii;
+ stmt[loc].loop_level[ii].parallel_level = 0;
}
-
+ fprintf(stderr, "whew\n");
+
stmt_nesting_level[loc] = -1;
}
+ dump();
+ fprintf(stderr, " loop.cc Loop::init_loop() END\n\n");
return true;
}
-Loop::Loop(const IR_Control *control) {
+
+Loop::Loop(const IR_Control *control) {
+
+ fprintf(stderr, "\nLoop::Loop(const IR_Control *control)\n");
+ fprintf(stderr, "control type is %d ", control->type());
+ echocontroltype(control);
+
last_compute_cgr_ = NULL;
last_compute_cg_ = NULL;
+ fprintf(stderr, "2set last_compute_cg_ = NULL; \n");
- ir = const_cast<IR_Code *>(control->ir_);
+ ir = const_cast<IR_Code *>(control->ir_); // point to the CHILL IR that this loop came from
+ if (ir == 0) {
+ fprintf(stderr, "ir gotten from control = 0x%x\n", (long)ir);
+ fprintf(stderr, "loop.cc GONNA DIE SOON *******************************\n\n");
+ }
+
init_code = NULL;
cleanup_code = NULL;
tmp_loop_var_name_counter = 1;
overflow_var_name_counter = 1;
known = Relation::True(0);
-
+
+ fprintf(stderr, "in Loop::Loop, calling build_ir_tree()\n");
+ fprintf(stderr, "\nloop.cc, Loop::Loop() about to clone control\n");
ir_tree = build_ir_tree(control->clone(), NULL);
+ //fprintf(stderr,"in Loop::Loop. ir_tree has %ld parts\n", ir_tree.size());
+
+ // std::vector<ir_tree_node *> ir_stmt;
+ //fprintf(stderr, "loop.cc after build_ir_tree() %ld statements\n", stmt.size());
+
+ int count = 0;
+ //fprintf(stderr, "before init_loops, %d freevar\n", freevar.size());
+ //fprintf(stderr, "count %d\n", count++);
+ //fprintf(stderr, "loop.cc before init_loop, %ld statements\n", stmt.size());
while (!init_loop(ir_tree, ir_stmt)) {
+ //fprintf(stderr, "count %d\n", count++);
}
-
+ fprintf(stderr, "after init_loop, %d freevar\n", (int)freevar.size());
+
+
+ fprintf(stderr, "loop.cc after init_loop, %d statements\n", (int)stmt.size());
for (int i = 0; i < stmt.size(); i++) {
std::map<int, CG_outputRepr*>::iterator it = replace.find(i);
-
+
if (it != replace.end())
stmt[i].code = it->second;
else
stmt[i].code = stmt[i].code;
}
-
+
if (stmt.size() != 0)
dep = DependenceGraph(stmt[0].IS.n_set());
else
@@ -366,82 +883,194 @@ Loop::Loop(const IR_Control *control) {
// init the dependence graph
for (int i = 0; i < stmt.size(); i++)
dep.insert();
-
- for (int i = 0; i < stmt.size(); i++)
+
+ fprintf(stderr, "this really REALLY needs some comments\n");
+ // this really REALLY needs some comments
+ for (int i = 0; i < stmt.size(); i++) {
+ fprintf(stderr, "i %d\n", i);
+ stmt[i].reduction = 0; // Manu -- initialization
for (int j = i; j < stmt.size(); j++) {
+ fprintf(stderr, "j %d\n", j);
std::pair<std::vector<DependenceVector>,
- std::vector<DependenceVector> > dv = test_data_dependences(
- ir, stmt[i].code, stmt[i].IS, stmt[j].code, stmt[j].IS,
- freevar, index, stmt_nesting_level_[i],
- stmt_nesting_level_[j]);
-
+ std::vector<DependenceVector> > dv = test_data_dependences(
+ ir,
+ stmt[i].code,
+ stmt[i].IS,
+ stmt[j].code,
+ stmt[j].IS,
+ freevar,
+ index,
+ stmt_nesting_level_[i],
+ stmt_nesting_level_[j],
+ uninterpreted_symbols[ i ],
+ uninterpreted_symbols_stringrepr[ i ]);
+
+ fprintf(stderr, "dv.first.size() %d\n", (int)dv.first.size());
for (int k = 0; k < dv.first.size(); k++) {
+ fprintf(stderr, "k1 %d\n", k);
if (is_dependence_valid(ir_stmt[i], ir_stmt[j], dv.first[k],
true))
dep.connect(i, j, dv.first[k]);
else {
dep.connect(j, i, dv.first[k].reverse());
}
-
+
}
- for (int k = 0; k < dv.second.size(); k++)
+
+ for (int k = 0; k < dv.second.size(); k++) {
+ fprintf(stderr, "k2 %d\n", k);
if (is_dependence_valid(ir_stmt[j], ir_stmt[i], dv.second[k],
false))
dep.connect(j, i, dv.second[k]);
else {
dep.connect(i, j, dv.second[k].reverse());
}
+ }
}
-
-
+ }
+
+ fprintf(stderr, "\n\n*** LOTS OF REDUCTIONS ***\n\n");
+
+ // TODO: Reduction check
+ // Manu:: Initial implementation / algorithm
+ std::set<int> reducCand = std::set<int>();
+ std::vector<int> canReduce = std::vector<int>();
+ fprintf(stderr, "\ni range %d\n", stmt.size());
+ for (int i = 0; i < stmt.size(); i++) {
+ fprintf(stderr, "i %d\n", i);
+ if (!dep.hasEdge(i, i)) {
+ continue;
+ }
+ fprintf(stderr, "dep.hasEdge(%d, %d)\n", i, i);
+
+ // for each statement check if it has all the three dependences (RAW, WAR, WAW)
+ // If there is such a statement, it is a reduction candidate. Mark all reduction candidates.
+ std::vector<DependenceVector> tdv = dep.getEdge(i, i);
+ fprintf(stderr, "tdv size %d\n", tdv.size());
+ for (int j = 0; j < tdv.size(); j++) {
+ fprintf(stderr, "ij %d %d\n", i, j);
+ if (tdv[j].is_reduction_cand) {
+ fprintf(stderr, "reducCand.insert( %d )\n", i);
+ reducCand.insert(i);
+ }
+ }
+ }
+
+ fprintf(stderr, "loop.cc reducCand.size() %d\n", reducCand.size());
+ bool reduc;
+ std::set<int>::iterator it;
+ int counter = 0;
+ for (it = reducCand.begin(); it != reducCand.end(); it++) {
+ fprintf(stderr, "counter %d\n", counter);
+ reduc = true;
+ for (int j = 0; j < stmt.size(); j++) {
+ fprintf(stderr, "j %d\n", j);
+ if ((*it != j)
+ && (stmt_nesting_level_[*it] < stmt_nesting_level_[j])) {
+ if (dep.hasEdge(*it, j) || dep.hasEdge(j, *it)) {
+ fprintf(stderr, "counter %d j %d reduc = false\n", counter, j);
+ reduc = false;
+ break;
+ }
+ }
+ counter += 1;
+ }
+
+ if (reduc) {
+ fprintf(stderr, "canReduce.push_back()\n");
+ canReduce.push_back(*it);
+ stmt[*it].reduction = 2; // First, assume that reduction is possible with some processing
+ }
+ }
+
+
+ // If reduction is possible without processing, update the value of the reduction variable to 1
+ fprintf(stderr, "loop.cc canReduce.size() %d\n", canReduce.size());
+ for (int i = 0; i < canReduce.size(); i++) {
+ // Here, assuming that stmtType returns 1 when there is a single statement within stmt[i]
+ if (stmtType(ir, stmt[canReduce[i]].code) == 1) {
+ stmt[canReduce[i]].reduction = 1;
+ IR_OPERATION_TYPE opType;
+ opType = getReductionOperator(ir, stmt[canReduce[i]].code);
+ stmt[canReduce[i]].reductionOp = opType;
+ }
+ }
+
+ // printing out stuff for debugging
+
+ if (DEP_DEBUG) {
+ std::cout << "STATEMENTS THAT CAN BE REDUCED: \n";
+ for (int i = 0; i < canReduce.size(); i++) {
+ std::cout << "------- " << canReduce[i] << " ------- "
+ << stmt[canReduce[i]].reduction << "\n";
+ ir->printStmt(stmt[canReduce[i]].code); // Manu
+ if (stmt[canReduce[i]].reductionOp == IR_OP_PLUS)
+ std::cout << "Reduction type:: + \n";
+ else if (stmt[canReduce[i]].reductionOp == IR_OP_MINUS)
+ std::cout << "Reduction type:: - \n";
+ else if (stmt[canReduce[i]].reductionOp == IR_OP_MULTIPLY)
+ std::cout << "Reduction type:: * \n";
+ else if (stmt[canReduce[i]].reductionOp == IR_OP_DIVIDE)
+ std::cout << "Reduction type:: / \n";
+ else
+ std::cout << "Unknown reduction type\n";
+ }
+ }
+ // cleanup the IR tree
+
+ fprintf(stderr, "init dumb transformation relations\n");
// init dumb transformation relations e.g. [i, j] -> [ 0, i, 0, j, 0]
for (int i = 0; i < stmt.size(); i++) {
int n = stmt[i].IS.n_set();
stmt[i].xform = Relation(n, 2 * n + 1);
F_And *f_root = stmt[i].xform.add_and();
-
+
for (int j = 1; j <= n; j++) {
EQ_Handle h = f_root->add_EQ();
h.update_coef(stmt[i].xform.output_var(2 * j), 1);
h.update_coef(stmt[i].xform.input_var(j), -1);
}
-
+
for (int j = 1; j <= 2 * n + 1; j += 2) {
EQ_Handle h = f_root->add_EQ();
h.update_coef(stmt[i].xform.output_var(j), 1);
}
stmt[i].xform.simplify();
}
-
+ //fprintf(stderr, "done with dumb\n");
+
if (stmt.size() != 0)
num_dep_dim = stmt[0].IS.n_set();
else
num_dep_dim = 0;
-// Debug output
-// for (int i = 0; i < stmt.size(); i++) {
-// std::cout << i << ": ";
-// stmt[i].xform.print();
-// stmt[i].IS.print();
-// std::cout << std::endl;
-//
-// }
+ // debug
+ /*for (int i = 0; i < stmt.size(); i++) {
+ std::cout << i << ": ";
+ //stmt[i].xform.print();
+ stmt[i].IS.print();
+ std::cout << std::endl;
+
+ }*/
+ //end debug
+ fprintf(stderr, " at bottom of Loop::Loop, printCode\n");
+ printCode(); // this dies TODO figure out why
}
Loop::~Loop() {
-
+
delete last_compute_cgr_;
delete last_compute_cg_;
-
+
for (int i = 0; i < stmt.size(); i++)
if (stmt[i].code != NULL) {
stmt[i].code->clear();
delete stmt[i].code;
}
-
+
for (int i = 0; i < ir_tree.size(); i++)
delete ir_tree[i];
-
+
if (init_code != NULL) {
init_code->clear();
delete init_code;
@@ -452,13 +1081,16 @@ Loop::~Loop() {
}
}
+
+
+
int Loop::get_dep_dim_of(int stmt_num, int level) const {
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invaid statement " + to_string(stmt_num));
-
+
if (level < 1 || level > stmt[stmt_num].loop_level.size())
return -1;
-
+
int trip_count = 0;
while (true) {
switch (stmt[stmt_num].loop_level[level - 1].type) {
@@ -469,36 +1101,35 @@ int Loop::get_dep_dim_of(int stmt_num, int level) const {
if (level < 1)
return -1;
if (level > stmt[stmt_num].loop_level.size())
- throw loop_error(
- "incorrect loop level information for statement "
- + to_string(stmt_num));
+ throw loop_error("incorrect loop level information for statement "
+ + to_string(stmt_num));
break;
default:
throw loop_error(
- "unknown loop level information for statement "
- + to_string(stmt_num));
+ "unknown loop level information for statement "
+ + to_string(stmt_num));
}
trip_count++;
if (trip_count >= stmt[stmt_num].loop_level.size())
throw loop_error(
- "incorrect loop level information for statement "
- + to_string(stmt_num));
+ "incorrect loop level information for statement "
+ + to_string(stmt_num));
}
}
int Loop::get_last_dep_dim_before(int stmt_num, int level) const {
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invaid statement " + to_string(stmt_num));
-
+
if (level < 1)
return -1;
if (level > stmt[stmt_num].loop_level.size())
level = stmt[stmt_num].loop_level.size() + 1;
-
+
for (int i = level - 1; i >= 1; i--)
if (stmt[stmt_num].loop_level[i - 1].type == LoopLevelOriginal)
return stmt[stmt_num].loop_level[i - 1].payload;
-
+
return -1;
}
@@ -530,53 +1161,96 @@ void Loop::print_internal_loop_structure() const {
}
}
+void Loop::debugRelations() const {
+ const int m = stmt.size();
+ {
+ std::vector<Relation> IS(m);
+ std::vector<Relation> xforms(m);
+
+ for (int i = 0; i < m; i++) {
+ IS[i] = stmt[i].IS;
+ xforms[i] = stmt[i].xform; // const stucks
+ }
+
+ printf("\nxforms:\n");
+ for (int i = 0; i < m; i++) { xforms[i].print(); printf("\n"); }
+ printf("\nIS:\n");
+ for (int i = 0; i < m; i++) { IS[i].print(); printf("\n"); }
+ fflush(stdout);
+ }
+}
+
+
CG_outputRepr *Loop::getCode(int effort) const {
+ fprintf(stderr,"\nloop.cc Loop::getCode( effort %d )\n", effort );
+
const int m = stmt.size();
if (m == 0)
return NULL;
const int n = stmt[0].xform.n_out();
-
+
if (last_compute_cg_ == NULL) {
+ fprintf(stderr, "Loop::getCode() last_compute_cg_ == NULL\n");
+
std::vector<Relation> IS(m);
std::vector<Relation> xforms(m);
for (int i = 0; i < m; i++) {
IS[i] = stmt[i].IS;
xforms[i] = stmt[i].xform;
}
+
+ debugRelations();
+
+
Relation known = Extend_Set(copy(this->known), n - this->known.n_set());
-
+ printf("\nknown:\n"); known.print(); printf("\n\n"); fflush(stdout);
+
last_compute_cg_ = new CodeGen(xforms, IS, known);
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
}
+ else {
+ fprintf(stderr, "Loop::getCode() last_compute_cg_ NOT NULL\n");
+ }
+
if (last_compute_cgr_ == NULL || last_compute_effort_ != effort) {
delete last_compute_cgr_;
last_compute_cgr_ = last_compute_cg_->buildAST(effort);
last_compute_effort_ = effort;
}
-
+
std::vector<CG_outputRepr *> stmts(m);
+ fprintf(stderr, "%d stmts\n", m);
for (int i = 0; i < m; i++)
stmts[i] = stmt[i].code;
CG_outputBuilder *ocg = ir->builder();
- CG_outputRepr *repr = last_compute_cgr_->printRepr(ocg, stmts);
+ fprintf(stderr, "calling last_compute_cgr_->printRepr()\n");
+ CG_outputRepr *repr = last_compute_cgr_->printRepr(ocg, stmts,
+ uninterpreted_symbols);
+
if (init_code != NULL)
repr = ocg->StmtListAppend(init_code->clone(), repr);
if (cleanup_code != NULL)
repr = ocg->StmtListAppend(repr, cleanup_code->clone());
-
+
+ fprintf(stderr,"\nloop.cc Loop::getCode( effort %d ) DONE\n", effort );
return repr;
}
+
+
+
void Loop::printCode(int effort) const {
+ fprintf(stderr,"\nloop.cc Loop::printCode( effort %d )\n", effort );
const int m = stmt.size();
if (m == 0)
return;
const int n = stmt[0].xform.n_out();
-
+
if (last_compute_cg_ == NULL) {
+ fprintf(stderr, "Loop::printCode(), last_compute_cg_ == NULL\n");
std::vector<Relation> IS(m);
std::vector<Relation> xforms(m);
for (int i = 0; i < m; i++) {
@@ -584,19 +1258,22 @@ void Loop::printCode(int effort) const {
xforms[i] = stmt[i].xform;
}
Relation known = Extend_Set(copy(this->known), n - this->known.n_set());
-
+
last_compute_cg_ = new CodeGen(xforms, IS, known);
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
}
-
+ else fprintf(stderr, "Loop::printCode(), last_compute_cg_ NOT NULL\n");
+
if (last_compute_cgr_ == NULL || last_compute_effort_ != effort) {
delete last_compute_cgr_;
last_compute_cgr_ = last_compute_cg_->buildAST(effort);
last_compute_effort_ = effort;
}
-
- std::string repr = last_compute_cgr_->printString();
+
+ std::string repr = last_compute_cgr_->printString(
+ uninterpreted_symbols_stringrepr);
+ fprintf(stderr, "leaving Loop::printCode()\n");
std::cout << repr << std::endl;
}
@@ -620,66 +1297,59 @@ void Loop::printDependenceGraph() const {
}
}
-Relation Loop::getNewIS(int stmt_num) const {
- Relation result;
-
- if (stmt[stmt_num].xform.is_null()) {
- Relation known = Extend_Set(copy(this->known),
- stmt[stmt_num].IS.n_set() - this->known.n_set());
- result = Intersection(copy(stmt[stmt_num].IS), known);
- } else {
- Relation known = Extend_Set(copy(this->known),
- stmt[stmt_num].xform.n_out() - this->known.n_set());
- result = Intersection(
- Range(
- Restrict_Domain(copy(stmt[stmt_num].xform),
- copy(stmt[stmt_num].IS))), known);
- }
-
- result.simplify(2, 4);
-
- return result;
-}
-
std::vector<Relation> Loop::getNewIS() const {
const int m = stmt.size();
-
+
std::vector<Relation> new_IS(m);
for (int i = 0; i < m; i++)
new_IS[i] = getNewIS(i);
-
+
return new_IS;
}
+// pragmas are tied to loops only ???
void Loop::pragma(int stmt_num, int level, const std::string &pragmaText) {
- // check sanity of parameters
- if(stmt_num < 0)
- throw std::invalid_argument("invalid statement " + to_string(stmt_num));
-
- CG_outputBuilder *ocg = ir->builder();
- CG_outputRepr *code = stmt[stmt_num].code;
- ocg->CreatePragmaAttribute(code, level, pragmaText);
+ // check sanity of parameters
+ if(stmt_num < 0)
+ throw std::invalid_argument("invalid statement " + to_string(stmt_num));
+
+ CG_outputBuilder *ocg = ir->builder();
+ CG_outputRepr *code = stmt[stmt_num].code;
+ ocg->CreatePragmaAttribute(code, level, pragmaText);
}
-void Loop::prefetch(int stmt_num, int level, const std::string &arrName, int hint) {
- // check sanity of parameters
- if(stmt_num < 0)
- throw std::invalid_argument("invalid statement " + to_string(stmt_num));
- CG_outputBuilder *ocg = ir->builder();
- CG_outputRepr *code = stmt[stmt_num].code;
- ocg->CreatePrefetchAttribute(code, level, arrName, hint);
+/*
+ void Loop::prefetch(int stmt_num, int level, const std::string &arrName, const std::string &indexName, int offset, int hint) {
+ // check sanity of parameters
+ if(stmt_num < 0)
+ throw std::invalid_argument("invalid statement " + to_string(stmt_num));
+
+ CG_outputBuilder *ocg = ir->builder();
+ CG_outputRepr *code = stmt[stmt_num].code;
+ ocg->CreatePrefetchAttribute(code, level, arrName, indexName, int offset, hint);
+ }
+*/
+
+void Loop::prefetch(int stmt_num, int level, const std::string &arrName, int hint) {
+ // check sanity of parameters
+ if(stmt_num < 0)
+ throw std::invalid_argument("invalid statement " + to_string(stmt_num));
+
+ CG_outputBuilder *ocg = ir->builder();
+ CG_outputRepr *code = stmt[stmt_num].code;
+ ocg->CreatePrefetchAttribute(code, level, arrName, hint);
}
std::vector<int> Loop::getLexicalOrder(int stmt_num) const {
assert(stmt_num < stmt.size());
-
+
const int n = stmt[stmt_num].xform.n_out();
std::vector<int> lex(n, 0);
-
+
for (int i = 0; i < n; i += 2)
lex[i] = get_const(stmt[stmt_num].xform, i, Output_Var);
-
+
return lex;
}
@@ -688,13 +1358,13 @@ std::vector<int> Loop::getLexicalOrder(int stmt_num) const {
std::set<int> Loop::getSubLoopNest(int stmt_num, int level) const {
assert(stmt_num >= 0 && stmt_num < stmt.size());
assert(level > 0 && level <= stmt[stmt_num].loop_level.size());
-
+
std::set<int> working;
for (int i = 0; i < stmt.size(); i++)
if (const_cast<Loop *>(this)->stmt[i].IS.is_upper_bound_satisfiable()
&& stmt[i].loop_level.size() >= level)
working.insert(i);
-
+
for (int i = 1; i <= level; i++) {
int a = getLexicalOrder(stmt_num, i);
for (std::set<int>::iterator j = working.begin(); j != working.end();) {
@@ -705,14 +1375,14 @@ std::set<int> Loop::getSubLoopNest(int stmt_num, int level) const {
++j;
}
}
-
+
return working;
}
int Loop::getLexicalOrder(int stmt_num, int level) const {
assert(stmt_num >= 0 && stmt_num < stmt.size());
assert(level > 0 && level <= stmt[stmt_num].loop_level.size()+1);
-
+
Relation &r = const_cast<Loop *>(this)->stmt[stmt_num].xform;
for (EQ_Iterator e(r.single_conjunct()->EQs()); e; e++)
if (abs((*e).get_coef(r.output_var(2 * level - 1))) == 1) {
@@ -727,15 +1397,15 @@ int Loop::getLexicalOrder(int stmt_num, int level) const {
return (*e).get_coef(r.output_var(2 * level - 1)) > 0 ? -t : t;
}
}
-
+
throw loop_error(
- "can't find lexical order for statement " + to_string(stmt_num)
- + "'s loop level " + to_string(level));
+ "can't find lexical order for statement " + to_string(stmt_num)
+ + "'s loop level " + to_string(level));
}
std::set<int> Loop::getStatements(const std::vector<int> &lex, int dim) const {
const int m = stmt.size();
-
+
std::set<int> same_loops;
for (int i = 0; i < m; i++) {
if (dim < 0)
@@ -749,32 +1419,32 @@ std::set<int> Loop::getStatements(const std::vector<int> &lex, int dim) const {
if (j > dim)
same_loops.insert(i);
}
-
+
}
-
+
return same_loops;
}
void Loop::shiftLexicalOrder(const std::vector<int> &lex, int dim, int amount) {
const int m = stmt.size();
-
+
if (amount == 0)
return;
-
+
for (int i = 0; i < m; i++) {
std::vector<int> lex2 = getLexicalOrder(i);
-
+
bool need_shift = true;
-
+
for (int j = 0; j < dim; j++)
if (lex2[j] != lex[j]) {
need_shift = false;
break;
}
-
+
if (!need_shift)
continue;
-
+
if (amount > 0) {
if (lex2[dim] < lex[dim])
continue;
@@ -782,14 +1452,14 @@ void Loop::shiftLexicalOrder(const std::vector<int> &lex, int dim, int amount) {
if (lex2[dim] > lex[dim])
continue;
}
-
+
assign_const(stmt[i].xform, dim, lex2[dim] + amount);
}
}
std::vector<std::set<int> > Loop::sort_by_same_loops(std::set<int> active,
int level) {
-
+
std::set<int> not_nested_at_this_level;
std::map<ir_tree_node*, std::set<int> > sorted_by_loop;
std::map<int, std::set<int> > sorted_by_lex_order;
@@ -797,73 +1467,79 @@ std::vector<std::set<int> > Loop::sort_by_same_loops(std::set<int> active,
bool lex_order_already_set = false;
for (std::set<int>::iterator it = active.begin(); it != active.end();
it++) {
-
+
if (stmt[*it].ir_stmt_node == NULL)
lex_order_already_set = true;
}
-
+
if (lex_order_already_set) {
-
+
for (std::set<int>::iterator it = active.begin(); it != active.end();
it++) {
std::map<int, std::set<int> >::iterator it2 =
sorted_by_lex_order.find(
- get_const(stmt[*it].xform, 2 * (level - 1),
- Output_Var));
-
+ get_const(stmt[*it].xform, 2 * (level - 1),
+ Output_Var));
+
if (it2 != sorted_by_lex_order.end())
it2->second.insert(*it);
else {
-
+
std::set<int> to_insert;
-
+
to_insert.insert(*it);
-
+
sorted_by_lex_order.insert(
- std::pair<int, std::set<int> >(
- get_const(stmt[*it].xform, 2 * (level - 1),
- Output_Var), to_insert));
-
+ std::pair<int, std::set<int> >(
+ get_const(stmt[*it].xform, 2 * (level - 1),
+ Output_Var), to_insert));
+
}
-
+
}
-
+
for (std::map<int, std::set<int> >::iterator it2 =
sorted_by_lex_order.begin(); it2 != sorted_by_lex_order.end();
it2++)
to_return.push_back(it2->second);
-
+
} else {
-
+
for (std::set<int>::iterator it = active.begin(); it != active.end();
it++) {
-
+
ir_tree_node* itn = stmt[*it].ir_stmt_node;
itn = itn->parent;
- while ((itn != NULL) && (itn->payload != level - 1))
+ //while (itn->content->type() != IR_CONTROL_LOOP && itn != NULL)
+ // itn = itn->parent;
+
+ while ((itn != NULL) && (itn->payload != level - 1)) {
itn = itn->parent;
-
+ while (itn != NULL && itn->content->type() != IR_CONTROL_LOOP )
+ itn = itn->parent;
+ }
+
if (itn == NULL)
not_nested_at_this_level.insert(*it);
else {
std::map<ir_tree_node*, std::set<int> >::iterator it2 =
sorted_by_loop.find(itn);
-
+
if (it2 != sorted_by_loop.end())
it2->second.insert(*it);
else {
std::set<int> to_insert;
-
+
to_insert.insert(*it);
-
+
sorted_by_loop.insert(
- std::pair<ir_tree_node*, std::set<int> >(itn,
- to_insert));
-
+ std::pair<ir_tree_node*, std::set<int> >(itn,
+ to_insert));
+
}
-
+
}
-
+
}
if (not_nested_at_this_level.size() > 0) {
for (std::set<int>::iterator it = not_nested_at_this_level.begin();
@@ -871,7 +1547,7 @@ std::vector<std::set<int> > Loop::sort_by_same_loops(std::set<int> active,
std::set<int> temp;
temp.insert(*it);
to_return.push_back(temp);
-
+
}
}
for (std::map<ir_tree_node*, std::set<int> >::iterator it2 =
@@ -881,37 +1557,46 @@ std::vector<std::set<int> > Loop::sort_by_same_loops(std::set<int> active,
return to_return;
}
-void update_successors(int n, int node_num[], int cant_fuse_with[],
- Graph<std::set<int>, bool> &g, std::list<int> &work_list) {
-
+void update_successors(int n,
+ int node_num[],
+ int cant_fuse_with[],
+ Graph<std::set<int>, bool> &g,
+ std::list<int> &work_list,
+ std::list<bool> &type_list,
+ std::vector<bool> types) {
+
std::set<int> disconnect;
for (Graph<std::set<int>, bool>::EdgeList::iterator i =
g.vertex[n].second.begin(); i != g.vertex[n].second.end(); i++) {
int m = i->first;
-
+
if (node_num[m] != -1)
throw loop_error("Graph input for fusion has cycles not a DAG!!");
-
+
std::vector<bool> check_ = g.getEdge(n, m);
-
+
bool has_bad_edge_path = false;
for (int i = 0; i < check_.size(); i++)
if (!check_[i]) {
has_bad_edge_path = true;
break;
}
- if (has_bad_edge_path)
- cant_fuse_with[m] = std::max(cant_fuse_with[m], node_num[n]);
- else
+ if (!types[m]) {
cant_fuse_with[m] = std::max(cant_fuse_with[m], cant_fuse_with[n]);
+ } else {
+ if (has_bad_edge_path)
+ cant_fuse_with[m] = std::max(cant_fuse_with[m], node_num[n]);
+ else
+ cant_fuse_with[m] = std::max(cant_fuse_with[m], cant_fuse_with[n]);
+ }
disconnect.insert(m);
}
-
-
+
+
for (std::set<int>::iterator i = disconnect.begin(); i != disconnect.end();
i++) {
g.disconnect(n, *i);
-
+
bool no_incoming_edges = true;
for (int j = 0; j < g.vertex.size(); j++)
if (j != *i)
@@ -919,23 +1604,44 @@ void update_successors(int n, int node_num[], int cant_fuse_with[],
no_incoming_edges = false;
break;
}
-
-
- if (no_incoming_edges)
+
+ if (no_incoming_edges) {
work_list.push_back(*i);
+ type_list.push_back(types[*i]);
+ }
}
+}
+
+
+int Loop::getMinLexValue(std::set<int> stmts, int level) {
+
+ int min;
+
+ std::set<int>::iterator it = stmts.begin();
+ min = getLexicalOrder(*it, level);
+
+ for (; it != stmts.end(); it++) {
+ int curr = getLexicalOrder(*it, level);
+ if (curr < min)
+ min = curr;
+ }
+
+ return min;
}
+
+
+
Graph<std::set<int>, bool> Loop::construct_induced_graph_at_level(
- std::vector<std::set<int> > s, DependenceGraph dep, int dep_dim) {
+ std::vector<std::set<int> > s, DependenceGraph dep, int dep_dim) {
Graph<std::set<int>, bool> g;
-
+
for (int i = 0; i < s.size(); i++)
g.insert(s[i]);
-
+
for (int i = 0; i < s.size(); i++) {
-
+
for (int j = i + 1; j < s.size(); j++) {
bool has_true_edge_i_to_j = false;
bool has_true_edge_j_to_i = false;
@@ -943,32 +1649,32 @@ Graph<std::set<int>, bool> Loop::construct_induced_graph_at_level(
bool is_connected_j_to_i = false;
for (std::set<int>::iterator ii = s[i].begin(); ii != s[i].end();
ii++) {
-
+
for (std::set<int>::iterator jj = s[j].begin();
jj != s[j].end(); jj++) {
-
+
std::vector<DependenceVector> dvs = dep.getEdge(*ii, *jj);
for (int k = 0; k < dvs.size(); k++)
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& dvs[k].has_been_carried_at(dep_dim))) {
-
+
if (dvs[k].is_data_dependence()
&& dvs[k].has_negative_been_carried_at(
- dep_dim)) {
+ dep_dim)) {
//g.connect(i, j, false);
is_connected_i_to_j = true;
break;
} else {
//g.connect(i, j, true);
-
+
has_true_edge_i_to_j = true;
//break
}
}
-
+
//if (is_connected)
-
+
// break;
// if (has_true_edge_i_to_j && !is_connected_i_to_j)
// g.connect(i, j, true);
@@ -977,142 +1683,226 @@ Graph<std::set<int>, bool> Loop::construct_induced_graph_at_level(
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& dvs[k].has_been_carried_at(dep_dim))) {
-
+
if (is_connected_i_to_j || has_true_edge_i_to_j)
throw loop_error(
- "Graph input for fusion has cycles not a DAG!!");
-
+ "Graph input for fusion has cycles not a DAG!!");
+
if (dvs[k].is_data_dependence()
&& dvs[k].has_negative_been_carried_at(
- dep_dim)) {
+ dep_dim)) {
+ //g.connect(i, j, false);
is_connected_j_to_i = true;
break;
} else {
+ //g.connect(i, j, true);
+
has_true_edge_j_to_i = true;
+ //break;
}
}
+
+ // if (is_connected)
+ //break;
+ // if (is_connected)
+ //break;
}
+
+ //if (is_connected)
+ // break;
}
-
-
+
+
if (is_connected_i_to_j)
g.connect(i, j, false);
else if (has_true_edge_i_to_j)
g.connect(i, j, true);
-
+
if (is_connected_j_to_i)
g.connect(j, i, false);
else if (has_true_edge_j_to_i)
g.connect(j, i, true);
-
-
+
}
}
return g;
}
-std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g) {
- bool roots[g.vertex.size()];
+std::vector<std::set<int> > Loop::typed_fusion(Graph<std::set<int>, bool> g,
+ std::vector<bool> &types) {
+
+ bool roots[g.vertex.size()];
+
for (int i = 0; i < g.vertex.size(); i++)
roots[i] = true;
-
+
for (int i = 0; i < g.vertex.size(); i++)
for (int j = i + 1; j < g.vertex.size(); j++) {
-
+
if (g.hasEdge(i, j))
roots[j] = false;
-
+
if (g.hasEdge(j, i))
roots[i] = false;
-
+
}
-
+
std::list<int> work_list;
+ std::list<bool> type_list;
int cant_fuse_with[g.vertex.size()];
+ int fused = 0;
+ int lastfused = 0;
+ int lastnum = 0;
std::vector<std::set<int> > s;
//Each Fused set's representative node
-
+
int node_to_fused_nodes[g.vertex.size()];
int node_num[g.vertex.size()];
+ int next[g.vertex.size()];
+
for (int i = 0; i < g.vertex.size(); i++) {
- if (roots[i] == true)
+ if (roots[i] == true) {
work_list.push_back(i);
+ type_list.push_back(types[i]);
+ }
cant_fuse_with[i] = 0;
node_to_fused_nodes[i] = 0;
node_num[i] = -1;
+ next[i] = 0;
}
+
+
// topological sort according to chun's permute algorithm
+ // std::vector<std::set<int> > s = g.topoSort();
std::vector<std::set<int> > s2 = g.topoSort();
if (work_list.empty() || (s2.size() != g.vertex.size())) {
+
std::cout << s2.size() << "\t" << g.vertex.size() << std::endl;
throw loop_error("Input for fusion not a DAG!!");
+
+
}
int fused_nodes_counter = 0;
while (!work_list.empty()) {
int n = work_list.front();
+ bool type = type_list.front();
+ //int n_ = g.vertex[n].first;
work_list.pop_front();
+ type_list.pop_front();
int node;
- if (cant_fuse_with[n] == 0)
+ /*if (cant_fuse_with[n] == 0)
node = 0;
- else
+ else
node = cant_fuse_with[n];
-
- if ((fused_nodes_counter != 0) && (node != fused_nodes_counter)) {
- int rep_node = node_to_fused_nodes[node];
- node_num[n] = node_num[rep_node];
-
- try {
- update_successors(n, node_num, cant_fuse_with, g, work_list);
- } catch (const loop_error &e) {
-
- throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
-
+ */
+ int p;
+ if (type) {
+ //if ((fused_nodes_counter != 0) && (node != fused_nodes_counter)) {
+ if (cant_fuse_with[n] == 0)
+ p = fused;
+ else
+ p = next[cant_fuse_with[n]];
+
+ if (p != 0) {
+ int rep_node = node_to_fused_nodes[p];
+ node_num[n] = node_num[rep_node];
+
+ try {
+ update_successors(n, node_num, cant_fuse_with, g, work_list,
+ type_list, types);
+ } catch (const loop_error &e) {
+
+ throw loop_error(
+ "statements cannot be fused together due to negative dependence");
+
+ }
+ for (std::set<int>::iterator it = g.vertex[n].first.begin();
+ it != g.vertex[n].first.end(); it++)
+ s[node_num[n] - 1].insert(*it);
+ } else {
+ //std::set<int> new_node;
+ //new_node.insert(n_);
+ s.push_back(g.vertex[n].first);
+ lastnum = lastnum + 1;
+ node_num[n] = lastnum;
+ node_to_fused_nodes[node_num[n]] = n;
+
+ if (lastfused == 0) {
+ fused = lastnum;
+ lastfused = fused;
+ } else {
+ next[lastfused] = lastnum;
+ lastfused = lastnum;
+
+ }
+
+ try {
+ update_successors(n, node_num, cant_fuse_with, g, work_list,
+ type_list, types);
+ } catch (const loop_error &e) {
+
+ throw loop_error(
+ "statements cannot be fused together due to negative dependence");
+
+ }
+ fused_nodes_counter++;
}
- for (std::set<int>::iterator it = g.vertex[n].first.begin();
- it != g.vertex[n].first.end(); it++)
- s[node].insert(*it);
+
} else {
s.push_back(g.vertex[n].first);
- node_to_fused_nodes[node] = n;
- node_num[n] = ++node;
+ lastnum = lastnum + 1;
+ node_num[n] = lastnum;
+ node_to_fused_nodes[node_num[n]] = n;
+
try {
- update_successors(n, node_num, cant_fuse_with, g, work_list);
+ update_successors(n, node_num, cant_fuse_with, g, work_list,
+ type_list, types);
} catch (const loop_error &e) {
-
+
throw loop_error(
- "statements cannot be fused together due to negative dependence");
-
-
+ "statements cannot be fused together due to negative dependence");
+
}
- fused_nodes_counter++;
+ //fused_nodes_counter++;
+
}
+
}
-
+
return s;
}
+
+
+
void Loop::setLexicalOrder(int dim, const std::set<int> &active,
int starting_order, std::vector<std::vector<std::string> > idxNames) {
+ fprintf(stderr, "Loop::setLexicalOrder() %d idxNames active size %d starting_order %d\n", idxNames.size(), active.size(), starting_order);
if (active.size() == 0)
return;
+ for (int i=0; i< idxNames.size(); i++) {
+ std::vector<std::string> what = idxNames[i];
+ for (int j=0; j<what.size(); j++) {
+ fprintf(stderr, "%2d %2d %s\n", i,j, what[j].c_str());
+ }
+ }
+
// check for sanity of parameters
if (dim < 0 || dim % 2 != 0)
throw std::invalid_argument(
- "invalid constant loop level to set lexicographical order");
+ "invalid constant loop level to set lexicographical order");
std::vector<int> lex;
int ref_stmt_num;
for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
if ((*i) < 0 || (*i) >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(*i));
+ "invalid statement number " + to_string(*i));
if (dim >= stmt[*i].xform.n_out())
throw std::invalid_argument(
- "invalid constant loop level to set lexicographical order");
+ "invalid constant loop level to set lexicographical order");
if (i == active.begin()) {
lex = getLexicalOrder(*i);
ref_stmt_num = *i;
@@ -1121,11 +1911,11 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
for (int j = 0; j < dim; j += 2)
if (lex[j] != lex2[j])
throw std::invalid_argument(
- "statements are not in the same sub loop nest");
+ "statements are not in the same sub loop nest");
}
}
-
- // sepearate statements by current loop level types
+
+ // separate statements by current loop level types
int level = (dim + 2) / 2;
std::map<std::pair<LoopLevelType, int>, std::set<int> > active_by_level_type;
std::set<int> active_by_no_level;
@@ -1134,10 +1924,10 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
active_by_no_level.insert(*i);
else
active_by_level_type[std::make_pair(
- stmt[*i].loop_level[level - 1].type,
- stmt[*i].loop_level[level - 1].payload)].insert(*i);
+ stmt[*i].loop_level[level - 1].type,
+ stmt[*i].loop_level[level - 1].payload)].insert(*i);
}
-
+
// further separate statements due to control dependences
std::vector<std::set<int> > active_by_level_type_splitted;
for (std::map<std::pair<LoopLevelType, int>, std::set<int> >::iterator i =
@@ -1164,16 +1954,16 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
}
if (controlled.size() != 0 && not_controlled.size() != 0) {
active_by_level_type_splitted.erase(
- active_by_level_type_splitted.begin() + j);
+ active_by_level_type_splitted.begin() + j);
active_by_level_type_splitted.push_back(controlled);
active_by_level_type_splitted.push_back(not_controlled);
}
}
-
+
// set lexical order separating loops with different loop types first
if (active_by_level_type_splitted.size() + active_by_no_level.size() > 1) {
int dep_dim = get_last_dep_dim_before(ref_stmt_num, level) + 1;
-
+
Graph<std::set<int>, Empty> g;
for (std::vector<std::set<int> >::iterator i =
active_by_level_type_splitted.begin();
@@ -1198,7 +1988,7 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& !dvs[k].has_been_carried_before(
- dep_dim))) {
+ dep_dim))) {
g.connect(i, j);
connected = true;
break;
@@ -1222,7 +2012,7 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
if (dvs[k].is_control_dependence()
|| (dvs[k].is_data_dependence()
&& !dvs[k].has_been_carried_before(
- dep_dim))) {
+ dep_dim))) {
g.connect(j, i);
connected = true;
break;
@@ -1234,13 +2024,13 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
break;
}
}
-
+
std::vector<std::set<int> > s = g.topoSort();
if (s.size() != g.vertex.size())
throw loop_error(
- "cannot separate statements with different loop types at loop level "
- + to_string(level));
-
+ "cannot separate statements with different loop types at loop level "
+ + to_string(level));
+
// assign lexical order
int order = starting_order;
for (int i = 0; i < s.size(); i++) {
@@ -1252,19 +2042,20 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
for (int j = dim + 2; j < stmt[cur_stmt].xform.n_out(); j += 2)
assign_const(stmt[cur_stmt].xform, j, 0);
order++;
- } else {
+ } else { // recurse !
+ fprintf(stderr, "Loop:setLexicalOrder() recursing\n");
setLexicalOrder(dim, cur_scc, order, idxNames);
order += sz;
}
}
}
- // set lexical order seperating single iteration statements and loops
- else {
+ else { // set lexical order separating single iteration statements and loops
+
std::set<int> true_singles;
std::set<int> nonsingles;
std::map<coef_t, std::set<int> > fake_singles;
std::set<int> fake_singles_;
-
+
// sort out statements that do not require loops
for (std::set<int>::iterator i = active.begin(); i != active.end();
i++) {
@@ -1282,7 +2073,7 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
fake_singles_.insert(*i);
try {
fake_singles[get_const(cur_IS, dim + 1, Set_Var)].insert(
- *i);
+ *i);
} catch (const std::exception &e) {
fake_singles[posInfinity].insert(*i);
}
@@ -1290,58 +2081,199 @@ void Loop::setLexicalOrder(int dim, const std::set<int> &active,
} else
nonsingles.insert(*i);
}
-
-
+
+
// split nonsingles forcibly according to negative dependences present (loop unfusible)
int dep_dim = get_dep_dim_of(ref_stmt_num, level);
-
+
if (dim < stmt[ref_stmt_num].xform.n_out() - 1) {
-
+
+ bool dummy_level_found = false;
+
std::vector<std::set<int> > s;
-
+
s = sort_by_same_loops(active, level);
bool further_levels_exist = false;
-
+
if (!idxNames.empty())
if (level <= idxNames[ref_stmt_num].size())
if (idxNames[ref_stmt_num][level - 1].length() == 0) {
- // Dummy level found
+ // && s.size() == 1) {
int order1 = 0;
-
+ dummy_level_found = true;
+
for (int i = level; i < idxNames[ref_stmt_num].size();
i++)
if (idxNames[ref_stmt_num][i].length() > 0)
further_levels_exist = true;
-
+
}
-
+
+ //if (!dummy_level_found) {
+
if (s.size() > 1) {
-
+
+ std::vector<bool> types;
+ for (int i = 0; i < s.size(); i++)
+ types.push_back(true);
+
Graph<std::set<int>, bool> g = construct_induced_graph_at_level(
- s, dep, dep_dim);
- s = typed_fusion(g);
+ s, dep, dep_dim);
+ s = typed_fusion(g, types);
}
- int order = 0;
+ int order = starting_order;
for (int i = 0; i < s.size(); i++) {
-
+
for (std::set<int>::iterator it = s[i].begin();
- it != s[i].end(); it++)
+ it != s[i].end(); it++) {
assign_const(stmt[*it].xform, dim, order);
-
- if ((dim + 2) <= (stmt[ref_stmt_num].xform.n_out() - 1))
+ stmt[*it].xform.simplify();
+ }
+
+ if ((dim + 2) <= (stmt[ref_stmt_num].xform.n_out() - 1)) { // recurse !
+ fprintf(stderr, "Loop:setLexicalOrder() recursing\n");
setLexicalOrder(dim + 2, s[i], order, idxNames);
-
+ }
+
order++;
}
+ //}
+ /* else {
+
+ int order1 = 0;
+ int order = 0;
+ for (std::set<int>::iterator i = active.begin();
+ i != active.end(); i++) {
+ if (!further_levels_exist)
+ assign_const(stmt[*i].xform, dim, order1++);
+ else
+ assign_const(stmt[*i].xform, dim, order1);
+
+ }
+
+ if ((dim + 2) <= (stmt[ref_stmt_num].xform.n_out() - 1) && further_levels_exist)
+ setLexicalOrder(dim + 2, active, order, idxNames);
+ }
+ */
} else {
int dummy_order = 0;
for (std::set<int>::iterator i = active.begin(); i != active.end();
- i++)
+ i++) {
assign_const(stmt[*i].xform, dim, dummy_order++);
+ stmt[*i].xform.simplify();
+ }
+ }
+ /*for (int i = 0; i < g2.vertex.size(); i++)
+ for (int j = i+1; j < g2.vertex.size(); j++) {
+ std::vector<DependenceVector> dvs = dep.getEdge(g2.vertex[i].first, g2.vertex[j].first);
+ for (int k = 0; k < dvs.size(); k++)
+ if (dvs[k].is_control_dependence() ||
+ (dvs[k].is_data_dependence() && dvs[k].has_negative_been_carried_at(dep_dim))) {
+ g2.connect(i, j);
+ break;
+ }
+ dvs = dep.getEdge(g2.vertex[j].first, g2.vertex[i].first);
+ for (int k = 0; k < dvs.size(); k++)
+ if (dvs[k].is_control_dependence() ||
+ (dvs[k].is_data_dependence() && dvs[k].has_negative_been_carried_at(dep_dim))) {
+ g2.connect(j, i);
+ break;
+ }
+ }
+
+ std::vector<std::set<int> > s2 = g2.packed_topoSort();
+
+ std::vector<std::set<int> > splitted_nonsingles;
+ for (int i = 0; i < s2.size(); i++) {
+ std::set<int> cur_scc;
+ for (std::set<int>::iterator j = s2[i].begin(); j != s2[i].end(); j++)
+ cur_scc.insert(g2.vertex[*j].first);
+ splitted_nonsingles.push_back(cur_scc);
+ }
+ */
+ //convert to dependence graph for grouped statements
+ //dep_dim = get_last_dep_dim_before(ref_stmt_num, level) + 1;
+ /*int order = 0;
+ for (std::set<int>::iterator j = active.begin(); j != active.end();
+ j++) {
+ std::set<int> continuous;
+ std::cout<< active.size()<<std::endl;
+ while (nonsingles.find(*j) != nonsingles.end() && j != active.end()) {
+ continuous.insert(*j);
+ j++;
+ }
+
+ printf("continuous size is %d\n", continuous.size());
+
+
+
+ if (continuous.size() > 0) {
+ std::vector<std::set<int> > s = typed_fusion(continuous, dep,
+ dep_dim);
+
+ for (int i = 0; i < s.size(); i++) {
+ for (std::set<int>::iterator l = s[i].begin();
+ l != s[i].end(); l++) {
+ assign_const(stmt[*l].xform, dim + 2, order);
+ setLexicalOrder(dim + 2, s[i]);
+ }
+ order++;
+ }
+ }
+
+ if (j != active.end()) {
+ assign_const(stmt[*j].xform, dim + 2, order);
+
+ for (int k = dim + 4; k < stmt[*j].xform.n_out(); k += 2)
+ assign_const(stmt[*j].xform, k, 0);
+ order++;
+ }
+
+ if( j == active.end())
+ break;
+ }
+ */
+
+
+ // assign lexical order
+ /*int order = starting_order;
+ for (int i = 0; i < s.size(); i++) {
+ // translate each SCC into original statements
+ std::set<int> cur_scc;
+ for (std::set<int>::iterator j = s[i].begin(); j != s[i].end(); j++)
+ copy(s[i].begin(), s[i].end(),
+ inserter(cur_scc, cur_scc.begin()));
+
+ // now assign the constant
+ for (std::set<int>::iterator j = cur_scc.begin();
+ j != cur_scc.end(); j++)
+ assign_const(stmt[*j].xform, dim, order);
+
+ if (cur_scc.size() > 1)
+ setLexicalOrder(dim + 2, cur_scc);
+ else if (cur_scc.size() == 1) {
+ int cur_stmt = *(cur_scc.begin());
+ for (int j = dim + 2; j < stmt[cur_stmt].xform.n_out(); j += 2)
+ assign_const(stmt[cur_stmt].xform, j, 0);
+ }
+
+ if (cur_scc.size() > 0)
+ order++;
+ }
+ */
+ }
+
+ fprintf(stderr, "LEAVING Loop::setLexicalOrder() %d idxNames\n", idxNames.size());
+ for (int i=0; i< idxNames.size(); i++) {
+ std::vector<std::string> what = idxNames[i];
+ for (int j=0; j<what.size(); j++) {
+ fprintf(stderr, "%2d %2d %s\n", i,j, what[j].c_str());
}
}
}
+
+
void Loop::apply_xform() {
std::set<int> active;
for (int i = 0; i < stmt.size(); i++)
@@ -1350,56 +2282,206 @@ void Loop::apply_xform() {
}
void Loop::apply_xform(int stmt_num) {
+ fprintf(stderr, "apply_xform( %d )\n", stmt_num);
std::set<int> active;
active.insert(stmt_num);
apply_xform(active);
}
void Loop::apply_xform(std::set<int> &active) {
+ fflush(stdout);
+ fprintf(stderr, "loop.cc apply_xform( set )\n");
+
int max_n = 0;
-
- CG_outputBuilder *ocg = ir->builder();
+
+ omega::CG_outputBuilder *ocg = ir->builder();
for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
int n = stmt[*i].loop_level.size();
if (n > max_n)
max_n = n;
-
+
std::vector<int> lex = getLexicalOrder(*i);
-
- Relation mapping(2 * n + 1, n);
- F_And *f_root = mapping.add_and();
+
+ omega::Relation mapping(2 * n + 1, n);
+ omega::F_And *f_root = mapping.add_and();
for (int j = 1; j <= n; j++) {
- EQ_Handle h = f_root->add_EQ();
+ omega::EQ_Handle h = f_root->add_EQ();
h.update_coef(mapping.output_var(j), 1);
h.update_coef(mapping.input_var(2 * j), -1);
}
- mapping = Composition(mapping, stmt[*i].xform);
+ mapping = omega::Composition(mapping, stmt[*i].xform);
mapping.simplify();
-
+
// match omega input/output variables to variable names in the code
for (int j = 1; j <= stmt[*i].IS.n_set(); j++)
mapping.name_input_var(j, stmt[*i].IS.set_var(j)->name());
for (int j = 1; j <= n; j++)
mapping.name_output_var(j,
tmp_loop_var_name_prefix
- + to_string(tmp_loop_var_name_counter + j - 1));
+ + omega::to_string(
+ tmp_loop_var_name_counter + j - 1));
mapping.setup_names();
-
- Relation known = Extend_Set(copy(this->known),
- mapping.n_out() - this->known.n_set());
+ mapping.print(); // "{[I] -> [_t1] : I = _t1 }
+ fflush(stdout);
+
+ omega::Relation known = Extend_Set(copy(this->known),
+ mapping.n_out() - this->known.n_set());
+ //stmt[*i].code = outputStatement(ocg, stmt[*i].code, 0, mapping, known, std::vector<CG_outputRepr *>(mapping.n_out(), NULL));
+
+ omega::CG_outputBuilder *ocgr = ir->builder();
+
+
+ //this is probably CG_chillBuilder;
+
+ omega::CG_stringBuilder *ocgs = new omega::CG_stringBuilder;
+ if (uninterpreted_symbols[*i].size() == 0) {
+
+
+ std::set<std::string> globals;
+
+ for (omega::DNF_Iterator di(stmt[*i].IS.query_DNF()); di; di++) {
+
+ for (omega::Constraint_Iterator e(*di); e; e++) {
+ for (omega::Constr_Vars_Iter cvi(*e); cvi; cvi++) {
+ omega::Variable_ID v = cvi.curr_var();
+ if (v->kind() == omega::Global_Var
+ && v->get_global_var()->arity() > 0
+ && globals.find(v->name()) == globals.end()) {
+ omega::Global_Var_ID g = v->get_global_var();
+ globals.insert(v->name());
+ std::vector<omega::CG_outputRepr *> reprs;
+ std::vector<omega::CG_outputRepr *> reprs2;
+
+ for (int l = 1; l <= g->arity(); l++) {
+ omega::CG_outputRepr *temp = ocgr->CreateIdent(
+ stmt[*i].IS.set_var(l)->name());
+ omega::CG_outputRepr *temp2 = ocgs->CreateIdent(
+ stmt[*i].IS.set_var(l)->name());
+
+ reprs.push_back(temp);
+ reprs2.push_back(temp2);
+ }
+ uninterpreted_symbols[*i].insert(
+ std::pair<std::string,
+ std::vector<omega::CG_outputRepr *> >(
+ v->get_global_var()->base_name(),
+ reprs));
+ uninterpreted_symbols_stringrepr[*i].insert(
+ std::pair<std::string,
+ std::vector<omega::CG_outputRepr *> >(
+ v->get_global_var()->base_name(),
+ reprs2));
+ }
+ }
+ }
+ }
+ }
+
std::vector<std::string> loop_vars;
- for (int j = 1; j <= stmt[*i].IS.n_set(); j++)
+ for (int j = 1; j <= stmt[*i].IS.n_set(); j++) {
loop_vars.push_back(stmt[*i].IS.set_var(j)->name());
+ }
+ for (int j = 0; j<loop_vars.size(); j++) {
+ fprintf(stderr, "loop vars %d %s\n", j, loop_vars[j].c_str());
+ }
std::vector<CG_outputRepr *> subs = output_substitutions(ocg,
Inverse(copy(mapping)),
- std::vector<std::pair<CG_outputRepr *, int> >(mapping.n_out(),
- std::make_pair(static_cast<CG_outputRepr *>(NULL), 0)));
+ std::vector<std::pair<CG_outputRepr *, int> >(
+ mapping.n_out(),
+ std::make_pair(
+ static_cast<CG_outputRepr *>(NULL), 0)),
+ uninterpreted_symbols[*i]);
+
+ std::vector<CG_outputRepr *> subs2;
+ for (int l = 0; l < subs.size(); l++)
+ subs2.push_back(subs[l]->clone());
+
+ fprintf(stderr, "%d uninterpreted symbols\n", (int)uninterpreted_symbols.size());
+ for (int j = 0; j<loop_vars.size(); j++) {
+ fprintf(stderr, "loop vars %d %s\n", j, loop_vars[j].c_str());
+ }
+
+
+ int count = 0;
+ for (std::map<std::string, std::vector<CG_outputRepr *> >::iterator it =
+ uninterpreted_symbols[*i].begin();
+ it != uninterpreted_symbols[*i].end(); it++) {
+ fprintf(stderr, "\ncount %d\n", count);
+
+ std::vector<CG_outputRepr *> reprs_ = it->second;
+ fprintf(stderr, "%d reprs_\n", (int)reprs_.size());
+
+ std::vector<CG_outputRepr *> reprs_2;
+ for (int k = 0; k < reprs_.size(); k++) {
+ fprintf(stderr, "k %d\n", k);
+ std::vector<CG_outputRepr *> subs;
+ for (int l = 0; l < subs2.size(); l++) {
+ fprintf(stderr, "l %d\n", l);
+ subs.push_back(subs2[l]->clone());
+ }
+
+ fprintf(stderr, "clone\n");
+ CG_outputRepr *c = reprs_[k]->clone();
+ c->dump(); fflush(stdout);
+
+ fprintf(stderr, "createsub\n");
+ CG_outputRepr *s = ocgr->CreateSubstitutedStmt(0, c,
+ loop_vars, subs, true);
+
+ fprintf(stderr, "push back\n");
+ reprs_2.push_back( s );
+
+ }
+
+ it->second = reprs_2;
+ count++;
+ fprintf(stderr, "bottom\n");
+ }
+
+ std::vector<CG_outputRepr *> subs3 = output_substitutions(
+ ocgs, Inverse(copy(mapping)),
+ std::vector<std::pair<CG_outputRepr *, int> >(
+ mapping.n_out(),
+ std::make_pair(
+ static_cast<CG_outputRepr *>(NULL), 0)),
+ uninterpreted_symbols_stringrepr[*i]);
+
+ for (std::map<std::string, std::vector<CG_outputRepr *> >::iterator it =
+ uninterpreted_symbols_stringrepr[*i].begin();
+ it != uninterpreted_symbols_stringrepr[*i].end(); it++) {
+
+ std::vector<CG_outputRepr *> reprs_ = it->second;
+ std::vector<CG_outputRepr *> reprs_2;
+ for (int k = 0; k < reprs_.size(); k++) {
+ std::vector<CG_outputRepr *> subs;
+ /* for (int l = 0; l < subs3.size(); l++)
+ subs.push_back(subs3[l]->clone());
+ reprs_2.push_back(
+ ocgs->CreateSubstitutedStmt(0, reprs_[k]->clone(),
+ loop_vars, subs));
+ */
+ reprs_2.push_back(subs3[k]->clone());
+ }
+
+ it->second = reprs_2;
+
+ }
+
+
+ fprintf(stderr, "loop.cc stmt[*i].code =\n");
+ //stmt[*i].code->dump();
+ //fprintf(stderr, "\n");
stmt[*i].code = ocg->CreateSubstitutedStmt(0, stmt[*i].code, loop_vars,
subs);
- stmt[*i].IS = Range(Restrict_Domain(mapping, stmt[*i].IS));
+ //fprintf(stderr, "loop.cc substituted code =\n");
+ //stmt[*i].code->dump();
+ //fprintf(stderr, "\n");
+
+ stmt[*i].IS = omega::Range(Restrict_Domain(mapping, stmt[*i].IS));
stmt[*i].IS.simplify();
-
+
// replace original transformation relation with straight 1-1 mapping
+ //fprintf(stderr, "replace original transformation relation with straight 1-1 mapping\n");
mapping = Relation(n, 2 * n + 1);
f_root = mapping.add_and();
for (int j = 1; j <= n; j++) {
@@ -1413,29 +2495,46 @@ void Loop::apply_xform(std::set<int> &active) {
h.update_const(-lex[j - 1]);
}
stmt[*i].xform = mapping;
+
+ //fprintf(stderr, "\ncode is: \n");
+ //stmt[*i].code->dump();
+ //fprintf(stderr, "\n\n");
+
}
-
+
tmp_loop_var_name_counter += max_n;
+ fflush(stdout);
+ fprintf(stderr, "loop.cc LEAVING apply_xform( set )\n\n");
+ //for (std::set<int>::iterator i = active.begin(); i != active.end(); i++) {
+ // fprintf(stderr, "\nloop.cc stmt[i].code =\n");
+ // stmt[*i].code->dump();
+ // fprintf(stderr, "\n\n");
+ //}
+
}
-void Loop::addKnown(const Relation &cond) {
+
+
+void Loop::addKnown(const Relation &cond) {
+
// invalidate saved codegen computation
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
delete last_compute_cg_;
last_compute_cg_ = NULL;
-
+ fprintf(stderr, "Loop::addKnown(), SETTING last_compute_cg_ = NULL\n");
+
int n1 = this->known.n_set();
-
+
Relation r = copy(cond);
int n2 = r.n_set();
-
+
if (n1 < n2)
this->known = Extend_Set(this->known, n2 - n1);
else if (n1 > n2)
r = Extend_Set(r, n1 - n2);
-
+
this->known = Intersection(this->known, r);
}
@@ -1443,11 +2542,11 @@ void Loop::removeDependence(int stmt_num_from, int stmt_num_to) {
// check for sanity of parameters
if (stmt_num_from >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(stmt_num_from));
+ "invalid statement number " + to_string(stmt_num_from));
if (stmt_num_to >= stmt.size())
throw std::invalid_argument(
- "invalid statement number " + to_string(stmt_num_to));
-
+ "invalid statement number " + to_string(stmt_num_to));
+
dep.disconnect(stmt_num_from, stmt_num_to);
}
@@ -1482,16 +2581,16 @@ void Loop::dump() const {
bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
if (stmt.size() == 0)
return true;
-
+
// check for sanity of parameters
for (int i = 0; i < stmt.size(); i++) {
if (stmt[i].loop_level.size() != num_dep_dim)
throw std::invalid_argument(
- "nonsingular loop transformations must be applied to original perfect loop nest");
+ "nonsingular loop transformations must be applied to original perfect loop nest");
for (int j = 0; j < stmt[i].loop_level.size(); j++)
if (stmt[i].loop_level[j].type != LoopLevelOriginal)
throw std::invalid_argument(
- "nonsingular loop transformations must be applied to original perfect loop nest");
+ "nonsingular loop transformations must be applied to original perfect loop nest");
}
if (T.size() != num_dep_dim)
throw std::invalid_argument("invalid transformation matrix");
@@ -1503,6 +2602,8 @@ bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
last_compute_cgr_ = NULL;
delete last_compute_cg_;
last_compute_cg_ = NULL;
+ fprintf(stderr, "Loop::nonsingular(), SETTING last_compute_cg_ = NULL\n");
+
// build relation from matrix
Relation mapping(2 * num_dep_dim + 1, 2 * num_dep_dim + 1);
F_And *f_root = mapping.add_and();
@@ -1520,11 +2621,11 @@ bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
h.update_coef(mapping.output_var(i), -1);
h.update_coef(mapping.input_var(i), 1);
}
-
+
// update transformation relations
for (int i = 0; i < stmt.size(); i++)
stmt[i].xform = Composition(copy(mapping), stmt[i].xform);
-
+
// update dependence graph
for (int i = 0; i < dep.vertex.size(); i++)
for (DependenceGraph::EdgeList::iterator j =
@@ -1539,7 +2640,7 @@ bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
case DEP_W2W:
case DEP_R2R: {
std::vector<coef_t> lbounds(num_dep_dim), ubounds(
- num_dep_dim);
+ num_dep_dim);
for (int p = 0; p < num_dep_dim; p++) {
coef_t lb = 0;
coef_t ub = 0;
@@ -1579,7 +2680,7 @@ bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
}
dv.lbounds = lbounds;
dv.ubounds = ubounds;
-
+
break;
}
default:
@@ -1588,13 +2689,13 @@ bool Loop::nonsingular(const std::vector<std::vector<int> > &T) {
}
j->second = dvs;
}
-
+
// set constant loop values
std::set<int> active;
for (int i = 0; i < stmt.size(); i++)
active.insert(i);
setLexicalOrder(0, active);
-
+
return true;
}
@@ -1612,7 +2713,7 @@ bool Loop::is_dependence_valid_based_on_lex_order(int i, int j,
last_dim = last_dim / 2;
if (last_dim == 0)
return true;
-
+
for (int i = 0; i < last_dim; i++) {
if (dv.lbounds[i] > 0)
return true;
@@ -1622,8 +2723,1713 @@ bool Loop::is_dependence_valid_based_on_lex_order(int i, int j,
}
if (before)
return true;
-
+
return false;
+
+}
+
+// Manu:: reduction operation
+
+void Loop::scalar_expand(int stmt_num, const std::vector<int> &levels,
+ std::string arrName, int memory_type, int padding_alignment,
+ int assign_then_accumulate, int padding_stride) {
+
+ //std::cout << "In scalar_expand function: " << stmt_num << ", " << arrName << "\n";
+ //std::cout.flush();
+
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+ // check for sanity of parameters
+ bool found_non_constant_size_dimension = false;
+
+ if (stmt_num < 0 || stmt_num >= stmt.size())
+ throw std::invalid_argument(
+ "invalid statement number " + to_string(stmt_num));
+ //Anand: adding check for privatized levels
+ //if (arrName != "RHS")
+ // throw std::invalid_argument(
+ // "invalid 3rd argument: only 'RHS' supported " + arrName);
+ for (int i = 0; i < levels.size(); i++) {
+ if (levels[i] <= 0 || levels[i] > stmt[stmt_num].loop_level.size())
+ throw std::invalid_argument(
+ "1invalid loop level " + to_string(levels[i]));
+
+ if (i > 0) {
+ if (levels[i] < levels[i - 1])
+ throw std::invalid_argument(
+ "loop levels must be in ascending order");
+ }
+ }
+ //end --adding check for privatized levels
+
+ delete last_compute_cgr_;
+ last_compute_cgr_ = NULL;
+ delete last_compute_cg_;
+ last_compute_cg_ = NULL;
+ fprintf(stderr, "Loop::scalar_expand(), SETTING last_compute_cg_ = NULL\n");
+
+ fprintf(stderr, "\nloop.cc finding array accesses in stmt %d of the code\n",stmt_num );
+ std::vector<IR_ArrayRef *> access = ir->FindArrayRef(stmt[stmt_num].code);
+ fprintf(stderr, "loop.cc L2726 %d access\n", access.size());
+
+ IR_ArraySymbol *sym = NULL;
+ fprintf(stderr, "arrName %s\n", arrName.c_str());
+ if (arrName == "RHS") {
+ fprintf(stderr, "sym RHS\n");
+ sym = access[0]->symbol();
+ }
+ else {
+ fprintf(stderr, "looking for array %s in access\n", arrName.c_str());
+ for (int k = 0; k < access.size(); k++) { // BUH
+
+ //fprintf(stderr, "access[%d] = %s ", k, access[k]->getTypeString()); access[k]->print(0,stderr); fprintf(stderr, "\n");
+
+ std::string name = access[k]->symbol()->name();
+ //fprintf(stderr, "comparing %s to %s\n", name.c_str(), arrName.c_str());
+
+ if (access[k]->symbol()->name() == arrName) {
+ fprintf(stderr, "found it sym access[ k=%d ]\n", k);
+ sym = access[k]->symbol();
+ }
+ }
+ }
+ if (!sym) fprintf(stderr, "DIDN'T FIND IT\n");
+ fprintf(stderr, "sym %p\n", sym);
+
+ // collect array references by name
+ std::vector<int> lex = getLexicalOrder(stmt_num);
+ int dim = 2 * levels[levels.size() - 1] - 1;
+ std::set<int> same_loop = getStatements(lex, dim - 1);
+
+ //Anand: shifting this down
+ // assign_const(stmt[newStmt_num].xform, 2*level+1, 1);
+
+ // std::cout << " before temp array name \n ";
+ // create a temporary variable
+ IR_Symbol *tmp_sym;
+
+ // get the loop upperbound, that would be the size of the temp array.
+ omega::coef_t lb[levels.size()], ub[levels.size()], size[levels.size()];
+
+ //Anand Adding apply xform so that tiled loop bounds are reflected
+ fprintf(stderr, "Adding apply xform so that tiled loop bounds are reflected\n");
+ apply_xform(same_loop);
+ fprintf(stderr, "loop.cc, back from apply_xform()\n");
+
+ //Anand commenting out the folowing 4 lines
+ /* copy(stmt[stmt_num].IS).query_variable_bounds(
+ copy(stmt[stmt_num].IS).set_var(level), lb, ub);
+ std::cout << "Upper Bound = " << ub << "\n";
+ std::cout << "lower Bound = " << lb << "\n";
+ */
+ // testing testing -- Manu ////////////////////////////////////////////////
+ /*
+ // int n_dim = sym->n_dim();
+ // std::cout << "------- n_dim ----------- " << n_dim << "\n";
+ std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(stmt[stmt_num].IS, stmt[stmt_num].IS.set_var(level));
+ omega::coef_t index_stride;
+ if (result.second != NULL) {
+ index_stride = abs(result.first.get_coef(result.second))/gcd(abs(result.first.get_coef(result.second)), abs(result.first.get_coef(stmt[stmt_num].IS.set_var(level))));
+ std::cout << "simplest_stride :: " << index_stride << ", " << result.first.get_coef(result.second) << ", " << result.first.get_coef(stmt[stmt_num].IS.set_var(level))<< "\n";
+ }
+ Relation bound;
+ // bound = get_loop_bound(stmt[stmt_num].IS, level);
+ bound = SimpleHull(stmt[stmt_num].IS,true, true);
+ bound.print();
+
+ bound = copy(stmt[stmt_num].IS);
+ for (int i = 1; i < level; i++) {
+ bound = Project(bound, i, Set_Var);
+ std::cout << "-------------------------------\n";
+ bound.print();
+ }
+
+ bound.simplify();
+ bound.print();
+ // bound = get_loop_bound(bound, level);
+
+ copy(bound).query_variable_bounds(copy(bound).set_var(level), lb, ub);
+ std::cout << "Upper Bound = " << ub << "\n";
+ std::cout << "lower Bound = " << lb << "\n";
+
+ result = find_simplest_stride(bound, bound.set_var(level));
+ if (result.second != NULL)
+ index_stride = abs(result.first.get_coef(result.second))/gcd(abs(result.first.get_coef(result.second)), abs(result.first.get_coef(bound.set_var(level))));
+ else
+ index_stride = 1;
+ std::cout << "simplest_stride 11:: " << index_stride << "\n";
+ */
+ ////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////// copied datacopy code here /////////////////////////////////////////////
+
+ //std::cout << "In scalar_expand function 2: " << stmt_num << ", " << arrName << "\n";
+ //std::cout.flush();
+
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+
+
+ int n_dim = levels.size();
+ Relation copy_is = copy(stmt[stmt_num].IS);
+ // extract temporary array information
+ CG_outputBuilder *ocg1 = ir->builder();
+ std::vector<CG_outputRepr *> index_lb(n_dim); // initialized to NULL
+ std::vector<coef_t> index_stride(n_dim);
+ std::vector<bool> is_index_eq(n_dim, false);
+ std::vector<std::pair<int, CG_outputRepr *> > index_sz(0);
+ Relation reduced_copy_is = copy(copy_is);
+ std::vector<CG_outputRepr *> size_repr;
+ std::vector<int> size_int;
+ Relation xform = copy(stmt[stmt_num].xform);
+ for (int i = 0; i < n_dim; i++) {
+
+ dim = 2 * levels[i] - 1;
+ //Anand: Commenting out the lines below: not required
+ // if (i != 0)
+ // reduced_copy_is = Project(reduced_copy_is, level - 1 + i, Set_Var);
+ Relation bound = get_loop_bound(copy(reduced_copy_is), levels[i] - 1);
+
+ // extract stride
+ std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(bound,
+ bound.set_var(levels[i]));
+ if (result.second != NULL)
+ index_stride[i] = abs(result.first.get_coef(result.second))
+ / gcd(abs(result.first.get_coef(result.second)),
+ abs(
+ result.first.get_coef(
+ bound.set_var(levels[i]))));
+ else
+ index_stride[i] = 1;
+ // std::cout << "simplest_stride 11:: " << index_stride[i] << "\n";
+
+ // check if this array index requires loop
+ Conjunct *c = bound.query_DNF()->single_conjunct();
+ for (EQ_Iterator ei(c->EQs()); ei; ei++) {
+ if ((*ei).has_wildcards())
+ continue;
+
+ int coef = (*ei).get_coef(bound.set_var(levels[i]));
+ if (coef != 0) {
+ int sign = 1;
+ if (coef < 0) {
+ coef = -coef;
+ sign = -1;
+ }
+
+ CG_outputRepr *op = NULL;
+ for (Constr_Vars_Iter ci(*ei); ci; ci++) {
+ switch ((*ci).var->kind()) {
+ case Input_Var: {
+ if ((*ci).var != bound.set_var(levels[i]))
+ if ((*ci).coef * sign == 1)
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateIdent((*ci).var->name()));
+ else if ((*ci).coef * sign == -1)
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateIdent((*ci).var->name()));
+ else if ((*ci).coef * sign > 1) {
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(
+ abs((*ci).coef)),
+ ocg1->CreateIdent(
+ (*ci).var->name())));
+ }
+ else
+ // (*ci).coef*sign < -1
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(
+ abs((*ci).coef)),
+ ocg1->CreateIdent(
+ (*ci).var->name())));
+ break;
+ }
+ case Global_Var: {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ if ((*ci).coef * sign == 1)
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateIdent(g->base_name()));
+ else if ((*ci).coef * sign == -1)
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateIdent(g->base_name()));
+ else if ((*ci).coef * sign > 1)
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(abs((*ci).coef)),
+ ocg1->CreateIdent(g->base_name())));
+ else
+ // (*ci).coef*sign < -1
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(abs((*ci).coef)),
+ ocg1->CreateIdent(g->base_name())));
+ break;
+ }
+ default:
+ throw loop_error("unsupported array index expression");
+ }
+ }
+ if ((*ei).get_const() != 0)
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateInt(-sign * ((*ei).get_const())));
+ if (coef != 1)
+ op = ocg1->CreateIntegerFloor(op, ocg1->CreateInt(coef));
+
+ index_lb[i] = op;
+ is_index_eq[i] = true;
+ break;
+ }
+ }
+ if (is_index_eq[i])
+ continue;
+
+ // separate lower and upper bounds
+ std::vector<GEQ_Handle> lb_list, ub_list;
+ std::set<Variable_ID> excluded_floor_vars;
+ excluded_floor_vars.insert(bound.set_var(levels[i]));
+ for (GEQ_Iterator gi(c->GEQs()); gi; gi++) {
+ int coef = (*gi).get_coef(bound.set_var(levels[i]));
+ if (coef != 0 && (*gi).has_wildcards()) {
+ bool clean_bound = true;
+ GEQ_Handle h;
+ for (Constr_Vars_Iter cvi(*gi, true); gi; gi++)
+ if (!find_floor_definition(bound, (*cvi).var,
+ excluded_floor_vars).first) {
+ clean_bound = false;
+ break;
+ }
+ else
+ h= find_floor_definition(bound, (*cvi).var,
+ excluded_floor_vars).second;
+
+ if (!clean_bound)
+ continue;
+ else{
+ if (coef > 0)
+ lb_list.push_back(h);
+ else if (coef < 0)
+ ub_list.push_back(h);
+ continue;
+ }
+
+ }
+
+ if (coef > 0)
+ lb_list.push_back(*gi);
+ else if (coef < 0)
+ ub_list.push_back(*gi);
+ }
+ if (lb_list.size() == 0 || ub_list.size() == 0)
+ throw loop_error("failed to calcuate array footprint size");
+
+ // build lower bound representation
+ std::vector<CG_outputRepr *> lb_repr_list;
+ /* for (int j = 0; j < lb_list.size(); j++){
+ if(this->known.n_set() == 0)
+ lb_repr_list.push_back(output_lower_bound_repr(ocg1, lb_list[j], bound.set_var(level-1+i+1), result.first, result.second, bound, Relation::True(bound.n_set()), std::vector<std::pair<CG_outputRepr *, int> >(bound.n_set(), std::make_pair(static_cast<CG_outputRepr *>(NULL), 0))));
+ else
+ lb_repr_list.push_back(output_lower_bound_repr(ocg1, lb_list[j], bound.set_var(level-1+i+1), result.first, result.second, bound, this->known, std::vector<std::pair<CG_outputRepr *, int> >(bound.n_set(), std::make_pair(static_cast<CG_outputRepr *>(NULL), 0))));
+
+ }
+ */
+ if (lb_repr_list.size() > 1)
+ index_lb[i] = ocg1->CreateInvoke("max", lb_repr_list);
+ else if (lb_repr_list.size() == 1)
+ index_lb[i] = lb_repr_list[0];
+
+ // build temporary array size representation
+ {
+ Relation cal(copy_is.n_set(), 1);
+ F_And *f_root = cal.add_and();
+ for (int j = 0; j < ub_list.size(); j++)
+ for (int k = 0; k < lb_list.size(); k++) {
+ GEQ_Handle h = f_root->add_GEQ();
+
+ for (Constr_Vars_Iter ci(ub_list[j]); ci; ci++) {
+ switch ((*ci).var->kind()) {
+ case Input_Var: {
+ int pos = (*ci).var->get_position();
+ h.update_coef(cal.input_var(pos), (*ci).coef);
+ break;
+ }
+ case Global_Var: {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ Variable_ID v;
+ if (g->arity() == 0)
+ v = cal.get_local(g);
+ else
+ v = cal.get_local(g, (*ci).var->function_of());
+ h.update_coef(v, (*ci).coef);
+ break;
+ }
+ default:
+ throw loop_error(
+ "cannot calculate temporay array size statically");
+ }
+ }
+ h.update_const(ub_list[j].get_const());
+
+ for (Constr_Vars_Iter ci(lb_list[k]); ci; ci++) {
+ switch ((*ci).var->kind()) {
+ case Input_Var: {
+ int pos = (*ci).var->get_position();
+ h.update_coef(cal.input_var(pos), (*ci).coef);
+ break;
+ }
+ case Global_Var: {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ Variable_ID v;
+ if (g->arity() == 0)
+ v = cal.get_local(g);
+ else
+ v = cal.get_local(g, (*ci).var->function_of());
+ h.update_coef(v, (*ci).coef);
+ break;
+ }
+ default:
+ throw loop_error(
+ "cannot calculate temporay array size statically");
+ }
+ }
+ h.update_const(lb_list[k].get_const());
+
+ h.update_const(1);
+ h.update_coef(cal.output_var(1), -1);
+ }
+
+ cal = Restrict_Domain(cal, copy(copy_is));
+ for (int j = 1; j <= cal.n_inp(); j++) {
+ cal = Project(cal, j, Input_Var);
+ }
+ cal.simplify();
+
+ // pad temporary array size
+ // TODO: for variable array size, create padding formula
+ //int padding_stride = 0;
+ Conjunct *c = cal.query_DNF()->single_conjunct();
+ bool is_index_bound_const = false;
+ if (padding_stride != 0 && i == n_dim - 1) {
+ //size = (size + index_stride[i] - 1) / index_stride[i];
+ size_repr.push_back(ocg1->CreateInt(padding_stride));
+ } else {
+ for (GEQ_Iterator gi(c->GEQs()); gi && !is_index_bound_const;
+ gi++)
+ if ((*gi).is_const(cal.output_var(1))) {
+ coef_t size = (*gi).get_const()
+ / (-(*gi).get_coef(cal.output_var(1)));
+
+ if (padding_alignment > 1 && i == n_dim - 1) { // align to boundary for data packing
+ int residue = size % padding_alignment;
+ if (residue)
+ size = size + padding_alignment - residue;
+ }
+
+ index_sz.push_back(
+ std::make_pair(i, ocg1->CreateInt(size)));
+ is_index_bound_const = true;
+ size_int.push_back(size);
+ size_repr.push_back(ocg1->CreateInt(size));
+
+ // std::cout << "============================== size :: "
+ // << size << "\n";
+
+ }
+
+ if (!is_index_bound_const) {
+
+ found_non_constant_size_dimension = true;
+ Conjunct *c = bound.query_DNF()->single_conjunct();
+ for (GEQ_Iterator gi(c->GEQs());
+ gi && !is_index_bound_const; gi++) {
+ int coef = (*gi).get_coef(bound.set_var(levels[i]));
+ if (coef < 0) {
+
+ size_repr.push_back(
+ ocg1->CreatePlus(
+ output_upper_bound_repr(ocg1, *gi,
+ bound.set_var(levels[i]),
+ bound,
+ std::vector<
+ std::pair<
+ CG_outputRepr *,
+ int> >(
+ bound.n_set(),
+ std::make_pair(
+ static_cast<CG_outputRepr *>(NULL),
+ 0)),
+ uninterpreted_symbols[stmt_num]),
+ ocg1->CreateInt(1)));
+
+ /*CG_outputRepr *op = NULL;
+ for (Constr_Vars_Iter ci(*gi); ci; ci++) {
+ if ((*ci).var != cal.output_var(1)) {
+ switch ((*ci).var->kind()) {
+ case Global_Var: {
+ Global_Var_ID g =
+ (*ci).var->get_global_var();
+ if ((*ci).coef == 1)
+ op = ocg1->CreatePlus(op,
+ ocg1->CreateIdent(
+ g->base_name()));
+ else if ((*ci).coef == -1)
+ op = ocg1->CreateMinus(op,
+ ocg1->CreateIdent(
+ g->base_name()));
+ else if ((*ci).coef > 1)
+ op =
+ ocg1->CreatePlus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(
+ (*ci).coef),
+ ocg1->CreateIdent(
+ g->base_name())));
+ else
+ // (*ci).coef < -1
+ op =
+ ocg1->CreateMinus(op,
+ ocg1->CreateTimes(
+ ocg1->CreateInt(
+ -(*ci).coef),
+ ocg1->CreateIdent(
+ g->base_name())));
+ break;
+ }
+ default:
+ throw loop_error(
+ "failed to generate array index bound code");
+ }
+ }
+ }
+ int c = (*gi).get_const();
+ if (c > 0)
+ op = ocg1->CreatePlus(op, ocg1->CreateInt(c));
+ else if (c < 0)
+ op = ocg1->CreateMinus(op, ocg1->CreateInt(-c));
+ */
+ /* if (padding_stride != 0) {
+ if (i == fastest_changing_dimension) {
+ coef_t g = gcd(index_stride[i], static_cast<coef_t>(padding_stride));
+ coef_t t1 = index_stride[i] / g;
+ if (t1 != 1)
+ op = ocg->CreateIntegerFloor(ocg->CreatePlus(op, ocg->CreateInt(t1-1)), ocg->CreateInt(t1));
+ coef_t t2 = padding_stride / g;
+ if (t2 != 1)
+ op = ocg->CreateTimes(op, ocg->CreateInt(t2));
+ }
+ else if (index_stride[i] != 1) {
+ op = ocg->CreateIntegerFloor(ocg->CreatePlus(op, ocg->CreateInt(index_stride[i]-1)), ocg->CreateInt(index_stride[i]));
+ }
+ }
+ */
+ //index_sz.push_back(std::make_pair(i, op));
+ //break;
+ }
+ }
+ }
+ }
+ }
+ //size[i] = ub[i];
+
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+
+ //Anand: Creating IS of new statement
+
+ //for(int l = dim; l < stmt[stmt_num].xform.n_out(); l+=2)
+ //std::cout << "In scalar_expand function 3: " << stmt_num << ", " << arrName << "\n";
+ //std::cout.flush();
+
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+
+ shiftLexicalOrder(lex, dim + 1, 1);
+ Statement s = stmt[stmt_num];
+ s.ir_stmt_node = NULL;
+ int newStmt_num = stmt.size();
+
+ fprintf(stderr, "loop.cc L3249 adding stmt %d\n", stmt.size());
+ stmt.push_back(s);
+
+ fprintf(stderr, "uninterpreted_symbols.push_back() newStmt_num %d\n", newStmt_num);
+ uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
+ stmt[newStmt_num].code = stmt[stmt_num].code->clone();
+ stmt[newStmt_num].IS = copy(stmt[stmt_num].IS);
+ stmt[newStmt_num].xform = xform;
+ stmt[newStmt_num].reduction = stmt[stmt_num].reduction;
+ stmt[newStmt_num].reductionOp = stmt[stmt_num].reductionOp;
+
+
+ //fprintf(stderr, "\nafter clone, %d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+
+
+ //assign_const(stmt[newStmt_num].xform, stmt[stmt_num].xform.n_out(), 1);//Anand: change from 2*level + 1 to stmt[stmt_num].xform.size()
+ //Anand-End creating IS of new statement
+
+ CG_outputRepr * tmpArrSz;
+ CG_outputBuilder *ocg = ir->builder();
+
+ //for(int k =0; k < levels.size(); k++ )
+ // size_repr.push_back(ocg->CreateInt(size[k]));//Anand: copying apply_xform functionality to prevent IS modification
+ //due to side effects with uninterpreted function symbols and failures in omega
+
+ //int n = stmt[stmt_num].loop_level.size();
+
+ /*Relation mapping(2 * n + 1, n);
+ F_And *f_root = mapping.add_and();
+ for (int j = 1; j <= n; j++) {
+ EQ_Handle h = f_root->add_EQ();
+ h.update_coef(mapping.output_var(j), 1);
+ h.update_coef(mapping.input_var(2 * j), -1);
+ }
+ mapping = Composition(mapping, copy(stmt[stmt_num].xform));
+ mapping.simplify();
+
+ // match omega input/output variables to variable names in the code
+ for (int j = 1; j <= stmt[stmt_num].IS.n_set(); j++)
+ mapping.name_input_var(j, stmt[stmt_num].IS.set_var(j)->name());
+ for (int j = 1; j <= n; j++)
+ mapping.name_output_var(j,
+ tmp_loop_var_name_prefix
+ + to_string(tmp_loop_var_name_counter + j - 1));
+ mapping.setup_names();
+
+ Relation size_ = omega::Range(Restrict_Domain(mapping, copy(stmt[stmt_num].IS)));
+ size_.simplify();
+ */
+
+ //Anand -commenting out tmp sym creation as symbol may have more than one dimension
+ //tmp_sym = ir->CreateArraySymbol(tmpArrSz, sym);
+ std::vector<CG_outputRepr *> lhs_index;
+ CG_outputRepr *arr_ref_repr;
+ arr_ref_repr = ocg->CreateIdent(
+ stmt[stmt_num].IS.set_var(levels[levels.size() - 1])->name());
+
+ CG_outputRepr *total_size = size_repr[0];
+ fprintf(stderr, "total_size = "); total_size->dump(); fflush(stdout);
+
+ for (int i = 1; i < size_repr.size(); i++) {
+ fprintf(stderr, "total_size now "); total_size->dump(); fflush(stdout); fprintf(stderr, " times something\n\n");
+
+ total_size = ocg->CreateTimes(total_size->clone(),
+ size_repr[i]->clone());
+
+ }
+
+ // COMMENT NEEDED
+ //fprintf(stderr, "\nloop.cc COMMENT NEEDED\n");
+ for (int k = levels.size() - 2; k >= 0; k--) {
+ CG_outputRepr *temp_repr =ocg->CreateIdent(stmt[stmt_num].IS.set_var(levels[k])->name());
+ for (int l = k + 1; l < levels.size(); l++) {
+ //fprintf(stderr, "\nloop.cc CREATETIMES\n");
+ temp_repr = ocg->CreateTimes(temp_repr->clone(),
+ size_repr[l]->clone());
+ }
+
+ //fprintf(stderr, "\nloop.cc CREATEPLUS\n");
+ arr_ref_repr = ocg->CreatePlus(arr_ref_repr->clone(),
+ temp_repr->clone());
+ }
+
+
+ //fprintf(stderr, "loop.cc, about to die\n");
+ std::vector<CG_outputRepr *> to_push;
+ to_push.push_back(total_size);
+
+ if (!found_non_constant_size_dimension) {
+ fprintf(stderr, "constant size dimension\n");
+ tmp_sym = ir->CreateArraySymbol(sym, to_push, memory_type);
+ }
+ else {
+ fprintf(stderr, "NON constant size dimension?\n");
+ //tmp_sym = ir->CreatePointerSymbol(sym, to_push);
+ tmp_sym = ir->CreatePointerSymbol(sym, to_push);
+
+ static_cast<IR_PointerSymbol *>(tmp_sym)->set_size(0, total_size); // ??
+ ptr_variables.push_back(static_cast<IR_PointerSymbol *>(tmp_sym));
+ fprintf(stderr, "ptr_variables now has %d entries\n", ptr_variables.size());
+ }
+
+ // add tmp_sym to Loop symtables ??
+
+
+ // std::cout << " temp array name == " << tmp_sym->name().c_str() << "\n";
+
+ // get loop index variable at the given "level"
+ // Relation R = omega::Range(Restrict_Domain(copy(stmt[stmt_num].xform), copy(stmt[stmt_num].IS)));
+ // stmt[stmt_num].IS.print();
+ //stmt[stmt_num].IS.
+ // std::cout << stmt[stmt_num].IS.n_set() << std::endl;
+ // std::string v = stmt[stmt_num].IS.set_var(level)->name();
+ // std::cout << "loop index variable is '" << v.c_str() << "'\n";
+
+ // create a reference for the temporary array
+ fprintf(stderr, "create a reference for the temporary array\n");
+ //std::cout << "In scalar_expand function 4: " << stmt_num << ", " << arrName << "\n";
+ //std::cout.flush();
+
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+
+
+ std::vector<CG_outputRepr *> to_push2;
+ to_push2.push_back(arr_ref_repr); // can have only one entry
+
+ //lhs_index[0] = ocg->CreateIdent(v);
+
+
+ IR_ArrayRef *tmp_array_ref;
+ IR_PointerArrayRef * tmp_ptr_array_ref; // was IR_PointerArrayref
+
+ if (!found_non_constant_size_dimension) {
+ fprintf(stderr, "constant size\n");
+
+ tmp_array_ref = ir->CreateArrayRef(
+ static_cast<IR_ArraySymbol *>(tmp_sym), to_push2);
+ }
+ else {
+ fprintf(stderr, "NON constant size\n");
+ tmp_ptr_array_ref = ir->CreatePointerArrayRef(
+ static_cast<IR_PointerSymbol *>(tmp_sym), to_push2);
+ // TODO static_cast<IR_PointerSymbol *>(tmp_sym), to_push2);
+ }
+ fflush(stdout);
+
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+
+ //std::string stemp;
+ //stemp = tmp_array_ref->name();
+ //std::cout << "Created array reference --> " << stemp.c_str() << "\n";
+
+ // get the RHS expression
+ fprintf(stderr, "get the RHS expression arrName %s\n", arrName.c_str());
+
+ CG_outputRepr *rhs;
+ if (arrName == "RHS") {
+ rhs = ir->GetRHSExpression(stmt[stmt_num].code);
+
+ std::vector<IR_ArrayRef *> symbols = ir->FindArrayRef(rhs);
+ }
+ std::set<std::string> sym_names;
+
+ //for (int i = 0; i < symbols.size(); i++)
+ // sym_names.insert(symbols[i]->symbol()->name());
+
+ fflush(stdout);
+
+ //fprintf(stderr, "\nbefore if (arrName == RHS)\n%d statements\n", stmt.size()); // problem is after here
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+ if (arrName == "RHS") {
+
+ std::vector<IR_ArrayRef *> symbols = ir->FindArrayRef(rhs);
+
+ for (int i = 0; i < symbols.size(); i++)
+ sym_names.insert(symbols[i]->symbol()->name());
+ }
+ else {
+
+ fprintf(stderr, "finding array refs in stmt_num %d\n", stmt_num);
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+ std::vector<IR_ArrayRef *> refs = ir->FindArrayRef(stmt[stmt_num].code);
+ fprintf(stderr, "\n%d refs\n", refs.size());
+
+
+ bool found = false;
+
+ for (int j = 0; j < refs.size(); j++) {
+ CG_outputRepr* to_replace;
+
+ fprintf(stderr, "j %d build new assignment statement with temporary array\n",j);
+ // build new assignment statement with temporary array
+ if (!found_non_constant_size_dimension) {
+ to_replace = tmp_array_ref->convert();
+ } else {
+ to_replace = tmp_ptr_array_ref->convert();
+ }
+ //fprintf(stderr, "to_replace %p\n", to_replace);
+ //CG_chillRepr *CR = (CG_chillRepr *) to_replace;
+ //CR->Dump();
+
+ if (refs[j]->name() == arrName) {
+ fflush(stdout);
+ fprintf(stderr, "loop.cc L353\n"); // problem is after here
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+
+ sym_names.insert(refs[j]->symbol()->name());
+
+ if (!found) {
+ if (!found_non_constant_size_dimension) {
+ fprintf(stderr, "constant size2\n");
+ omega::CG_outputRepr * t = tmp_array_ref->convert();
+ omega::CG_outputRepr * r = refs[j]->convert()->clone();
+ //CR = (CG_chillRepr *) t;
+ //CR->Dump();
+ //CR = (CG_chillRepr *) r;
+ //CR->Dump();
+
+ //fprintf(stderr, "lhs t %p lhs r %p\n", t, r);
+ stmt[newStmt_num].code =
+ ir->builder()->CreateAssignment(0,
+ t, // tmp_array_ref->convert(),
+ r); // refs[j]->convert()->clone()
+ }
+ else {
+ fprintf(stderr, "NON constant size2\n");
+ omega::CG_outputRepr * t = tmp_ptr_array_ref->convert(); // this fails
+ omega::CG_outputRepr * r = refs[j]->convert()->clone();
+
+ //omega::CG_chillRepr *CR = (omega::CG_chillRepr *) t;
+ //CR->Dump();
+ //CR = (omega::CG_chillRepr *) r;
+ //CR->Dump();
+
+ //fprintf(stderr, "lhs t %p lhs r %p\n", t, r);
+ stmt[newStmt_num].code =
+ ir->builder()->CreateAssignment(0,
+ t, // tmp_ptr_array_ref->convert(),
+ r ); // refs[j]->convert()->clone());
+ }
+ found = true;
+
+ }
+
+ // refs[j] has no parent?
+ fprintf(stderr, "replacing refs[%d]\n", j );
+ ir->ReplaceExpression(refs[j], to_replace);
+ }
+
+ }
+
+ }
+ //ToDo need to update the dependence graph
+ //Anand adding dependence graph update
+ fprintf(stderr, "adding dependence graph update\n"); // problem is before here
+ //fprintf(stderr, "\n%d statements\n", stmt.size());
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "%2d ", i);
+ // ((CG_chillRepr *)stmt[i].code)->Dump();
+ //}
+ //fprintf(stderr, "\n");
+
+ dep.insert();
+
+ //Anand:Copying Dependence checks from datacopy code, might need to be a separate function/module
+ // in the future
+
+ /*for (int i = 0; i < newStmt_num; i++) {
+ std::vector<std::vector<DependenceVector> > D;
+
+ for (DependenceGraph::EdgeList::iterator j =
+ dep.vertex[i].second.begin(); j != dep.vertex[i].second.end();
+ ) {
+ if (same_loop.find(i) != same_loop.end()
+ && same_loop.find(j->first) == same_loop.end()) {
+ std::vector<DependenceVector> dvs1, dvs2;
+ for (int k = 0; k < j->second.size(); k++) {
+ DependenceVector dv = j->second[k];
+ if (dv.sym != NULL
+ && sym_names.find(dv.sym->name()) != sym_names.end()
+ && (dv.type == DEP_R2R || dv.type == DEP_R2W))
+ dvs1.push_back(dv);
+ else
+ dvs2.push_back(dv);
+ }
+ j->second = dvs2;
+ if (dvs1.size() > 0)
+ dep.connect(newStmt_num, j->first, dvs1);
+ } else if (same_loop.find(i) == same_loop.end()
+ && same_loop.find(j->first) != same_loop.end()) {
+ std::vector<DependenceVector> dvs1, dvs2;
+ for (int k = 0; k < j->second.size(); k++) {
+ DependenceVector dv = j->second[k];
+ if (dv.sym != NULL
+ && sym_names.find(dv.sym->name()) != sym_names.end()
+ && (dv.type == DEP_R2R || dv.type == DEP_W2R))
+ dvs1.push_back(dv);
+ else
+ dvs2.push_back(dv);
+ }
+ j->second = dvs2;
+ if (dvs1.size() > 0)
+ D.push_back(dvs1);
+ }
+
+ if (j->second.size() == 0)
+ dep.vertex[i].second.erase(j++);
+ else
+ j++;
+ }
+
+ for (int j = 0; j < D.size(); j++)
+ dep.connect(i, newStmt_num, D[j]);
+ }
+ */
+ //Anand--end dependence check
+ if (arrName == "RHS") {
+
+ // build new assignment statement with temporary array
+ if (!found_non_constant_size_dimension) {
+ if (assign_then_accumulate) {
+ stmt[newStmt_num].code = ir->builder()->CreateAssignment(0,
+ tmp_array_ref->convert(), rhs);
+ fprintf(stderr, "ir->ReplaceRHSExpression( stmt_ num %d )\n", stmt_num);
+ ir->ReplaceRHSExpression(stmt[stmt_num].code, tmp_array_ref);
+ } else {
+ CG_outputRepr *temp = tmp_array_ref->convert()->clone();
+ if (ir->QueryExpOperation(stmt[stmt_num].code)
+ != IR_OP_PLUS_ASSIGNMENT)
+ throw ir_error(
+ "Statement is not a += accumulation statement");
+
+ fprintf(stderr, "replacing in a +=\n");
+ stmt[newStmt_num].code = ir->builder()->CreatePlusAssignment(0,
+ temp->clone(), rhs);
+
+ CG_outputRepr * lhs = ir->GetLHSExpression(stmt[stmt_num].code);
+
+ CG_outputRepr *assignment = ir->builder()->CreateAssignment(0,
+ lhs, temp->clone());
+ Statement init_ = stmt[newStmt_num]; // copy ??
+ init_.ir_stmt_node = NULL;
+
+ init_.code = stmt[newStmt_num].code->clone();
+ init_.IS = copy(stmt[newStmt_num].IS);
+ init_.xform = copy(stmt[newStmt_num].xform);
+ init_.has_inspector = false; // ??
+
+ Relation mapping(init_.IS.n_set(), init_.IS.n_set());
+
+ F_And *f_root = mapping.add_and();
+
+ for (int i = 1; i <= mapping.n_inp(); i++) {
+ EQ_Handle h = f_root->add_EQ();
+ //if (i < levels[0]) {
+ if (i <= levels[levels.size() - 1]) {
+ h.update_coef(mapping.input_var(i), 1);
+ h.update_coef(mapping.output_var(i), -1);
+ } else {
+ h.update_const(-1);
+ h.update_coef(mapping.output_var(i), 1);
+ }
+
+ /*else {
+ int j;
+ for (j = 0; j < levels.size(); j++)
+ if (i == levels[j])
+ break;
+
+ if (j == levels.size()) {
+
+ h.update_coef(mapping.output_var(i), 1);
+ h.update_const(-1);
+
+ } else {
+
+
+ h.update_coef(mapping.input_var(i), 1);
+ h.update_coef(mapping.output_var(i), -1);
+
+
+ }
+ */
+ //}
+ }
+
+ mapping.simplify();
+ // match omega input/output variables to variable names in the code
+ for (int j = 1; j <= init_.IS.n_set(); j++)
+ mapping.name_output_var(j, init_.IS.set_var(j)->name());
+ for (int j = 1; j <= init_.IS.n_set(); j++)
+ mapping.name_input_var(j, init_.IS.set_var(j)->name());
+
+ mapping.setup_names();
+
+ init_.IS = omega::Range(
+ omega::Restrict_Domain(mapping, init_.IS));
+ std::vector<int> lex = getLexicalOrder(newStmt_num);
+ int dim = 2 * levels[0] - 1;
+ //init_.IS.print();
+ // init_.xform.print();
+ //stmt[newStmt_num].xform.print();
+ // shiftLexicalOrder(lex, dim + 1, 1);
+ shiftLexicalOrder(lex, dim + 1, 1);
+ init_.reduction = stmt[newStmt_num].reduction;
+ init_.reductionOp = stmt[newStmt_num].reductionOp;
+
+ init_.code = ir->builder()->CreateAssignment(0, temp->clone(),
+ ir->builder()->CreateInt(0));
+
+ fprintf(stderr, "loop.cc L3693 adding stmt %d\n", stmt.size());
+ stmt.push_back(init_);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[newStmt_num]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[newStmt_num]);
+ stmt[stmt_num].code = assignment;
+ }
+ } else {
+ if (assign_then_accumulate) {
+ stmt[newStmt_num].code = ir->builder()->CreateAssignment(0,
+ tmp_ptr_array_ref->convert(), rhs);
+ ir->ReplaceRHSExpression(stmt[stmt_num].code,
+ tmp_ptr_array_ref);
+ } else {
+ CG_outputRepr *temp = tmp_ptr_array_ref->convert()->clone();
+ if (ir->QueryExpOperation(stmt[stmt_num].code)
+ != IR_OP_PLUS_ASSIGNMENT)
+ throw ir_error(
+ "Statement is not a += accumulation statement");
+ stmt[newStmt_num].code = ir->builder()->CreatePlusAssignment(0,
+ temp->clone(), rhs);
+
+ CG_outputRepr * lhs = ir->GetLHSExpression(stmt[stmt_num].code);
+
+ CG_outputRepr *assignment = ir->builder()->CreateAssignment(0,
+ lhs, temp->clone());
+
+ stmt[stmt_num].code = assignment;
+ }
+ // call function to replace rhs with temporary array
+ }
+ }
+
+ //std::cout << "End of scalar_expand function!! \n";
+
+ // if(arrName == "RHS"){
+ DependenceVector dv;
+ std::vector<DependenceVector> E;
+ dv.lbounds = std::vector<omega::coef_t>(4);
+ dv.ubounds = std::vector<omega::coef_t>(4);
+ dv.type = DEP_W2R;
+
+ for (int k = 0; k < 4; k++) {
+ dv.lbounds[k] = 0;
+ dv.ubounds[k] = 0;
+
+ }
+
+ //std::vector<IR_ArrayRef*> array_refs = ir->FindArrayRef(stmt[newStmt_num].code);
+ dv.sym = tmp_sym->clone();
+
+ E.push_back(dv);
+
+ dep.connect(newStmt_num, stmt_num, E);
+ // }
+
+}
+
+
+
+std::pair<Relation, Relation> createCSRstyleISandXFORM(CG_outputBuilder *ocg,
+ std::vector<Relation> &outer_loop_bounds, std::string index_name,
+ std::map<int, Relation> &zero_loop_bounds,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_string,
+ Loop *this_loop) {
+
+ Relation IS(outer_loop_bounds.size() + 1 + zero_loop_bounds.size());
+ Relation XFORM(outer_loop_bounds.size() + 1 + zero_loop_bounds.size(),
+ 2 * (outer_loop_bounds.size() + 1 + zero_loop_bounds.size()) + 1);
+
+ F_And * f_r_ = IS.add_and();
+ F_And * f_root = XFORM.add_and();
+
+ if (outer_loop_bounds.size() > 0) {
+ for (int it = 0; it < IS.n_set(); it++) {
+ IS.name_set_var(it + 1,
+ const_cast<Relation &>(outer_loop_bounds[0]).set_var(it + 1)->name());
+ XFORM.name_input_var(it + 1,
+ const_cast<Relation &>(outer_loop_bounds[0]).set_var(it + 1)->name());
+
+ }
+ } else if (zero_loop_bounds.size() > 0) {
+ for (int it = 0; it < IS.n_set(); it++) {
+ IS.name_set_var(it + 1,
+ const_cast<Relation &>(zero_loop_bounds.begin()->second).set_var(
+ it + 1)->name());
+ XFORM.name_input_var(it + 1,
+ const_cast<Relation &>(zero_loop_bounds.begin()->second).set_var(
+ it + 1)->name());
+
+ }
+
+ }
+
+ for (int i = 0; i < outer_loop_bounds.size(); i++)
+ IS = replace_set_var_as_another_set_var(IS, outer_loop_bounds[i], i + 1,
+ i + 1);
+
+ int count = 1;
+ for (std::map<int, Relation>::iterator i = zero_loop_bounds.begin();
+ i != zero_loop_bounds.end(); i++, count++)
+ IS = replace_set_var_as_another_set_var(IS, i->second,
+ outer_loop_bounds.size() + 1 + count, i->first);
+
+ if (outer_loop_bounds.size() > 0) {
+ Free_Var_Decl *lb = new Free_Var_Decl(index_name + "_", 1); // index_
+ Variable_ID csr_lb = IS.get_local(lb, Input_Tuple);
+
+ Free_Var_Decl *ub = new Free_Var_Decl(index_name + "__", 1); // index__
+ Variable_ID csr_ub = IS.get_local(ub, Input_Tuple);
+
+ //lower bound
+
+ F_And * f_r = IS.and_with_and();
+ GEQ_Handle lower_bound = f_r->add_GEQ();
+ lower_bound.update_coef(csr_lb, -1);
+ lower_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), 1);
+
+ //upper bound
+
+ GEQ_Handle upper_bound = f_r->add_GEQ();
+ upper_bound.update_coef(csr_ub, 1);
+ upper_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), -1);
+ upper_bound.update_const(-1);
+
+ omega::CG_stringBuilder *ocgs = new CG_stringBuilder;
+
+ std::vector<omega::CG_outputRepr *> reprs;
+ std::vector<omega::CG_outputRepr *> reprs2;
+
+ std::vector<omega::CG_outputRepr *> reprs3;
+ std::vector<omega::CG_outputRepr *> reprs4;
+
+ reprs.push_back(
+ ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+ reprs2.push_back(
+ ocgs->CreateIdent(
+ IS.set_var(outer_loop_bounds.size())->name()));
+ uninterpreted_symbols.insert(
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "_", reprs));
+ uninterpreted_symbols_string.insert(
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "_", reprs2));
+
+ std::string arg = "(" + IS.set_var(outer_loop_bounds.size())->name()
+ + ")";
+ std::vector< std::string > argvec;
+ argvec.push_back( arg );
+
+ CG_outputRepr *repr = ocg->CreateArrayRefExpression(index_name,
+ ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+
+ //fprintf(stderr, "( VECTOR _)\n");
+ //fprintf(stderr, "loop.cc calling CreateDefineMacro( %s, argvec, repr)\n", (index_name + "_").c_str());
+ this_loop->ir->CreateDefineMacro(index_name + "_", argvec, repr);
+
+ Relation known_(copy(IS).n_set());
+ known_.copy_names(copy(IS));
+ known_.setup_names();
+ Variable_ID index_lb = known_.get_local(lb, Input_Tuple);
+ Variable_ID index_ub = known_.get_local(ub, Input_Tuple);
+ F_And *fr = known_.add_and();
+ GEQ_Handle g = fr->add_GEQ();
+ g.update_coef(index_ub, 1);
+ g.update_coef(index_lb, -1);
+ g.update_const(-1);
+ this_loop->addKnown(known_);
+
+ reprs3.push_back(
+
+ ocg->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+ reprs4.push_back(
+
+ ocgs->CreateIdent(IS.set_var(outer_loop_bounds.size())->name()));
+
+ CG_outputRepr *repr2 = ocg->CreateArrayRefExpression(index_name,
+ ocg->CreatePlus(
+ ocg->CreateIdent(
+ IS.set_var(outer_loop_bounds.size())->name()),
+ ocg->CreateInt(1)));
+
+ //fprintf(stderr, "( VECTOR __)\n");
+ //fprintf(stderr, "loop.cc calling CreateDefineMacro( %s, argvec, repr)\n", (index_name + "__").c_str());
+
+ this_loop->ir->CreateDefineMacro(index_name + "__", argvec, repr2);
+
+ uninterpreted_symbols.insert(
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "__", reprs3));
+ uninterpreted_symbols_string.insert(
+ std::pair<std::string, std::vector<CG_outputRepr *> >(
+ index_name + "__", reprs4));
+ } else {
+ Free_Var_Decl *ub = new Free_Var_Decl(index_name);
+ Variable_ID csr_ub = IS.get_local(ub);
+ F_And * f_r = IS.and_with_and();
+ GEQ_Handle upper_bound = f_r->add_GEQ();
+ upper_bound.update_coef(csr_ub, 1);
+ upper_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), -1);
+ upper_bound.update_const(-1);
+
+ GEQ_Handle lower_bound = f_r->add_GEQ();
+ lower_bound.update_coef(IS.set_var(outer_loop_bounds.size() + 1), 1);
+
+ }
+
+ for (int j = 1; j <= XFORM.n_inp(); j++) {
+ omega::EQ_Handle h = f_root->add_EQ();
+ h.update_coef(XFORM.output_var(2 * j), 1);
+ h.update_coef(XFORM.input_var(j), -1);
+ }
+
+ for (int j = 1; j <= XFORM.n_out(); j += 2) {
+ omega::EQ_Handle h = f_root->add_EQ();
+ h.update_coef(XFORM.output_var(j), 1);
+ }
+
+ if (_DEBUG_) {
+ IS.print();
+ XFORM.print();
+
+ }
+
+ return std::pair<Relation, Relation>(IS, XFORM);
+
}
+std::pair<Relation, Relation> construct_reduced_IS_And_XFORM(IR_Code *ir,
+ const Relation &is, const Relation &xform, const std::vector<int> loops,
+ std::vector<int> &lex_order, Relation &known,
+ std::map<std::string, std::vector<CG_outputRepr *> > &uninterpreted_symbols) {
+
+ Relation IS(loops.size());
+ Relation XFORM(loops.size(), 2 * loops.size() + 1);
+ int count_ = 1;
+ std::map<int, int> pos_mapping;
+
+ int n = is.n_set();
+ Relation is_and_known = Intersection(copy(is),
+ Extend_Set(copy(known), n - known.n_set()));
+
+ for (int it = 0; it < loops.size(); it++, count_++) {
+ IS.name_set_var(count_,
+ const_cast<Relation &>(is).set_var(loops[it])->name());
+ XFORM.name_input_var(count_,
+ const_cast<Relation &>(xform).input_var(loops[it])->name());
+ XFORM.name_output_var(2 * count_,
+ const_cast<Relation &>(xform).output_var((loops[it]) * 2)->name());
+ XFORM.name_output_var(2 * count_ - 1,
+ const_cast<Relation &>(xform).output_var((loops[it]) * 2 - 1)->name());
+ pos_mapping.insert(std::pair<int, int>(count_, loops[it]));
+ }
+
+ XFORM.name_output_var(2 * loops.size() + 1,
+ const_cast<Relation &>(xform).output_var(is.n_set() * 2 + 1)->name());
+
+ F_And * f_r = IS.add_and();
+ for (std::map<int, int>::iterator it = pos_mapping.begin();
+ it != pos_mapping.end(); it++)
+ IS = replace_set_var_as_another_set_var(IS, is_and_known, it->first,
+ it->second);
+ /*
+ for (std::map<std::string, std::vector<CG_outputRepr *> >::iterator it2 =
+ uninterpreted_symbols.begin();
+ it2 != uninterpreted_symbols.end(); it2++) {
+ std::vector<CG_outputRepr *> reprs_ = it2->second;
+ //std::vector<CG_outputRepr *> reprs_2;
+
+ for (int k = 0; k < reprs_.size(); k++) {
+ std::vector<IR_ScalarRef *> refs = ir->FindScalarRef(reprs_[k]);
+ bool exception_found = false;
+ for (int m = 0; m < refs.size(); m++){
+
+ if (refs[m]->name()
+ == const_cast<Relation &>(is).set_var(it->second)->name())
+ try {
+ ir->ReplaceExpression(refs[m],
+ ir->builder()->CreateIdent(
+ IS.set_var(it->first)->name()));
+ } catch (ir_error &e) {
+
+ reprs_[k] = ir->builder()->CreateIdent(
+ IS.set_var(it->first)->name());
+ exception_found = true;
+ }
+ if(exception_found)
+ break;
+ }
+
+ }
+ it2->second = reprs_;
+ }
+
+ }
+ */
+ if (_DEBUG_) {
+ std::cout << "relation debug" << std::endl;
+ IS.print();
+ }
+
+ F_And *f_root = XFORM.add_and();
+
+ count_ = 1;
+
+ for (int j = 1; j <= loops.size(); j++) {
+ omega::EQ_Handle h = f_root->add_EQ();
+ h.update_coef(XFORM.output_var(2 * j), 1);
+ h.update_coef(XFORM.input_var(j), -1);
+ }
+ for (int j = 0; j < loops.size(); j++, count_++) {
+ omega::EQ_Handle h = f_root->add_EQ();
+ h.update_coef(XFORM.output_var(count_ * 2 - 1), 1);
+ h.update_const(-lex_order[count_ * 2 - 2]);
+ }
+
+ omega::EQ_Handle h = f_root->add_EQ();
+ h.update_coef(XFORM.output_var((loops.size()) * 2 + 1), 1);
+ h.update_const(-lex_order[xform.n_out() - 1]);
+
+ if (_DEBUG_) {
+ std::cout << "relation debug" << std::endl;
+ IS.print();
+ XFORM.print();
+ }
+
+ return std::pair<Relation, Relation>(IS, XFORM);
+
+}
+
+std::set<std::string> inspect_repr_for_scalars(IR_Code *ir,
+ CG_outputRepr * repr, std::set<std::string> ignore) {
+
+ std::vector<IR_ScalarRef *> refs = ir->FindScalarRef(repr);
+ std::set<std::string> loop_vars;
+
+ for (int i = 0; i < refs.size(); i++)
+ if (ignore.find(refs[i]->name()) == ignore.end())
+ loop_vars.insert(refs[i]->name());
+
+ return loop_vars;
+
+}
+
+std::set<std::string> inspect_loop_bounds(IR_Code *ir, const Relation &R,
+ int pos,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols) {
+
+ if (!R.is_set())
+ throw loop_error("Input R has to be a set not a relation!");
+
+ std::set<std::string> vars;
+
+ std::vector<CG_outputRepr *> refs;
+ Variable_ID v = const_cast<Relation &>(R).set_var(pos);
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) {
+ if ((*gi).get_coef(v) != 0 && (*gi).is_const_except_for_global(v)) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+
+ case Global_Var: {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() > 0) {
+
+ std::string s = g->base_name();
+ std::copy(
+ uninterpreted_symbols.find(s)->second.begin(),
+ uninterpreted_symbols.find(s)->second.end(),
+ back_inserter(refs));
+
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ }
+ }
+ }
+
+ for (int i = 0; i < refs.size(); i++) {
+ std::vector<IR_ScalarRef *> refs_ = ir->FindScalarRef(refs[i]);
+
+ for (int j = 0; j < refs_.size(); j++)
+ vars.insert(refs_[j]->name());
+
+ }
+ return vars;
+}
+
+CG_outputRepr * create_counting_loop_body(IR_Code *ir, const Relation &R,
+ int pos, CG_outputRepr * count,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols) {
+
+ if (!R.is_set())
+ throw loop_error("Input R has to be a set not a relation!");
+
+ CG_outputRepr *ub, *lb;
+ ub = NULL;
+ lb = NULL;
+ std::vector<CG_outputRepr *> refs;
+ Variable_ID v = const_cast<Relation &>(R).set_var(pos);
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) {
+ if ((*gi).get_coef(v) != 0 && (*gi).is_const_except_for_global(v)) {
+ bool same_ge_1 = false;
+ bool same_ge_2 = false;
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+
+ case Global_Var: {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() > 0) {
+
+ std::string s = g->base_name();
+
+ if ((*gi).get_coef(v) > 0) {
+ if (ub != NULL)
+ throw ir_error(
+ "bound expression too complex!");
+
+ ub = ir->builder()->CreateInvoke(s,
+ uninterpreted_symbols.find(s)->second);
+ //ub = ir->builder()->CreateMinus(ub->clone(), ir->builder()->CreateInt(-(*gi).get_const()));
+ same_ge_1 = true;
+
+ } else {
+ if (lb != NULL)
+ throw ir_error(
+ "bound expression too complex!");
+ lb = ir->builder()->CreateInvoke(s,
+ uninterpreted_symbols.find(s)->second);
+ same_ge_2 = true;
+
+ }
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (same_ge_1 && same_ge_2)
+ lb = ir->builder()->CreatePlus(lb->clone(),
+ ir->builder()->CreateInt(-(*gi).get_const()));
+ else if (same_ge_1)
+ ub = ir->builder()->CreatePlus(ub->clone(),
+ ir->builder()->CreateInt(-(*gi).get_const()));
+ else if (same_ge_2)
+ lb = ir->builder()->CreatePlus(lb->clone(),
+ ir->builder()->CreateInt(-(*gi).get_const()));
+ }
+ }
+
+ }
+
+ return ir->builder()->CreatePlusAssignment(0, count,
+ ir->builder()->CreatePlus(
+ ir->builder()->CreateMinus(ub->clone(), lb->clone()),
+ ir->builder()->CreateInt(1)));
+}
+
+
+
+std::map<std::string, std::vector<std::string> > recurse_on_exp_for_arrays(
+ IR_Code * ir, CG_outputRepr * exp) {
+
+ std::map<std::string, std::vector<std::string> > arr_index_to_ref;
+ switch (ir->QueryExpOperation(exp)) {
+
+ case IR_OP_ARRAY_VARIABLE: {
+ IR_ArrayRef *ref = dynamic_cast<IR_ArrayRef *>(ir->Repr2Ref(exp));
+ IR_PointerArrayRef *ref_ =
+ dynamic_cast<IR_PointerArrayRef *>(ir->Repr2Ref(exp));
+ if (ref == NULL && ref_ == NULL)
+ throw loop_error("Array symbol unidentifiable!");
+
+ if (ref != NULL) {
+ std::vector<std::string> s0;
+
+ for (int i = 0; i < ref->n_dim(); i++) {
+ CG_outputRepr * index = ref->index(i);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, index);
+ std::vector<std::string> s;
+ for (std::map<std::string, std::vector<std::string> >::iterator j =
+ a0.begin(); j != a0.end(); j++) {
+ if (j->second.size() != 1 && (j->second)[0] != "")
+ throw loop_error(
+ "indirect array references not allowed in guard!");
+ s.push_back(j->first);
+ }
+ std::copy(s.begin(), s.end(), back_inserter(s0));
+ }
+ arr_index_to_ref.insert(
+ std::pair<std::string, std::vector<std::string> >(
+ ref->name(), s0));
+ } else {
+ std::vector<std::string> s0;
+ for (int i = 0; i < ref_->n_dim(); i++) {
+ CG_outputRepr * index = ref_->index(i);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, index);
+ std::vector<std::string> s;
+ for (std::map<std::string, std::vector<std::string> >::iterator j =
+ a0.begin(); j != a0.end(); j++) {
+ if (j->second.size() != 1 && (j->second)[0] != "")
+ throw loop_error(
+ "indirect array references not allowed in guard!");
+ s.push_back(j->first);
+ }
+ std::copy(s.begin(), s.end(), back_inserter(s0));
+ }
+ arr_index_to_ref.insert(
+ std::pair<std::string, std::vector<std::string> >(
+ ref_->name(), s0));
+ }
+ break;
+ }
+ case IR_OP_PLUS:
+ case IR_OP_MINUS:
+ case IR_OP_MULTIPLY:
+ case IR_OP_DIVIDE: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, v[0]);
+ std::map<std::string, std::vector<std::string> > a1 =
+ recurse_on_exp_for_arrays(ir, v[1]);
+ arr_index_to_ref.insert(a0.begin(), a0.end());
+ arr_index_to_ref.insert(a1.begin(), a1.end());
+ break;
+
+ }
+ case IR_OP_POSITIVE:
+ case IR_OP_NEGATIVE: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, v[0]);
+
+ arr_index_to_ref.insert(a0.begin(), a0.end());
+ break;
+
+ }
+ case IR_OP_VARIABLE: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+ IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+
+ std::string s = ref->name();
+ std::vector<std::string> to_insert;
+ to_insert.push_back("");
+ arr_index_to_ref.insert(
+ std::pair<std::string, std::vector<std::string> >(s,
+ to_insert));
+ break;
+ }
+ case IR_OP_CONSTANT:
+ break;
+
+ default: {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(exp);
+
+ for (int i = 0; i < v.size(); i++) {
+ std::map<std::string, std::vector<std::string> > a0 =
+ recurse_on_exp_for_arrays(ir, v[i]);
+
+ arr_index_to_ref.insert(a0.begin(), a0.end());
+ }
+
+ break;
+ }
+ }
+ return arr_index_to_ref;
+}
+
+
+
+std::vector<CG_outputRepr *> find_guards(IR_Code *ir, IR_Control *code) {
+ fprintf(stderr, "find_guards()\n");
+ std::vector<CG_outputRepr *> guards;
+ switch (code->type()) {
+ case IR_CONTROL_IF: {
+ fprintf(stderr, "find_guards() it's an if\n");
+ CG_outputRepr *cond = dynamic_cast<IR_If*>(code)->condition();
+
+ std::vector<CG_outputRepr *> then_body;
+ std::vector<CG_outputRepr *> else_body;
+ IR_Block *ORTB = dynamic_cast<IR_If*>(code)->then_body();
+ if (ORTB != NULL) {
+ fprintf(stderr, "recursing on then\n");
+ then_body = find_guards(ir, ORTB);
+ //dynamic_cast<IR_If*>(code)->then_body());
+ }
+ if (dynamic_cast<IR_If*>(code)->else_body() != NULL) {
+ fprintf(stderr, "recursing on then\n");
+ else_body = find_guards(ir,
+ dynamic_cast<IR_If*>(code)->else_body());
+ }
+
+ guards.push_back(cond);
+ if (then_body.size() > 0)
+ std::copy(then_body.begin(), then_body.end(),
+ back_inserter(guards));
+ if (else_body.size() > 0)
+ std::copy(else_body.begin(), else_body.end(),
+ back_inserter(guards));
+ break;
+ }
+ case IR_CONTROL_BLOCK: {
+ fprintf(stderr, "find_guards() it's a control block\n");
+ IR_Block* IRCB = dynamic_cast<IR_Block*>(code);
+ fprintf(stderr, "find_guards() calling ir->FindOneLevelControlStructure(IRCB);\n");
+ std::vector<IR_Control *> stmts = ir->FindOneLevelControlStructure(IRCB);
+
+ for (int i = 0; i < stmts.size(); i++) {
+ std::vector<CG_outputRepr *> stmt_repr = find_guards(ir, stmts[i]);
+ std::copy(stmt_repr.begin(), stmt_repr.end(),
+ back_inserter(guards));
+ }
+ break;
+ }
+ case IR_CONTROL_LOOP: {
+ fprintf(stderr, "find_guards() it's a control loop\n");
+ std::vector<CG_outputRepr *> body = find_guards(ir,
+ dynamic_cast<IR_Loop*>(code)->body());
+ if (body.size() > 0)
+ std::copy(body.begin(), body.end(), back_inserter(guards));
+ break;
+ } // loop
+ } // switch
+ return guards;
+}
+
+bool sort_helper(std::pair<std::string, std::vector<std::string> > i,
+ std::pair<std::string, std::vector<std::string> > j) {
+ int c1 = 0;
+ int c2 = 0;
+ for (int k = 0; k < i.second.size(); k++)
+ if (i.second[k] != "")
+ c1++;
+
+ for (int k = 0; k < j.second.size(); k++)
+ if (j.second[k] != "")
+ c2++;
+ return (c1 < c2);
+
+}
+
+bool sort_helper_2(std::pair<int, int> i, std::pair<int, int> j) {
+
+ return (i.second < j.second);
+
+}
+
+std::vector<std::string> construct_iteration_order(
+ std::map<std::string, std::vector<std::string> > & input) {
+ std::vector<std::string> arrays;
+ std::vector<std::string> scalars;
+ std::vector<std::pair<std::string, std::vector<std::string> > > input_aid;
+
+ for (std::map<std::string, std::vector<std::string> >::iterator j =
+ input.begin(); j != input.end(); j++)
+ input_aid.push_back(
+ std::pair<std::string, std::vector<std::string> >(j->first,
+ j->second));
+
+ std::sort(input_aid.begin(), input_aid.end(), sort_helper);
+
+ for (int j = 0; j < input_aid[input_aid.size() - 1].second.size(); j++)
+ if (input_aid[input_aid.size() - 1].second[j] != "") {
+ arrays.push_back(input_aid[input_aid.size() - 1].second[j]);
+
+ }
+
+ if (arrays.size() > 0) {
+ for (int i = input_aid.size() - 2; i >= 0; i--) {
+
+ int max_count = 0;
+ for (int j = 0; j < input_aid[i].second.size(); j++)
+ if (input_aid[i].second[j] != "") {
+ max_count++;
+ }
+ if (max_count > 0) {
+ for (int j = 0; j < max_count; j++) {
+ std::string s = input_aid[i].second[j];
+ bool found = false;
+ for (int k = 0; k < max_count; k++)
+ if (s == arrays[k])
+ found = true;
+ if (!found)
+ throw loop_error("guard condition not solvable");
+ }
+ } else {
+ bool found = false;
+ for (int k = 0; k < arrays.size(); k++)
+ if (arrays[k] == input_aid[i].first)
+ found = true;
+ if (!found)
+ arrays.push_back(input_aid[i].first);
+ }
+ }
+ } else {
+
+ for (int i = input_aid.size() - 1; i >= 0; i--) {
+ arrays.push_back(input_aid[i].first);
+ }
+ }
+ return arrays;
+}
+
+
+
diff --git a/src/loop_basic.cc b/src/loop_basic.cc
index cf72c97..a058598 100644
--- a/src/loop_basic.cc
+++ b/src/loop_basic.cc
@@ -11,6 +11,8 @@
#include "omegatools.hh"
#include <string.h>
+#include <code_gen/CG_utils.h>
+
using namespace omega;
void Loop::permute(const std::vector<int> &pi) {
@@ -26,6 +28,7 @@ void Loop::original() {
for (int i = 0; i < stmt.size(); i++)
active.insert(i);
setLexicalOrder(0, active);
+ //apply_xform();
}
void Loop::permute(int stmt_num, int level, const std::vector<int> &pi) {
// check for sanity of parameters
@@ -35,7 +38,7 @@ void Loop::permute(int stmt_num, int level, const std::vector<int> &pi) {
"invalid statement number " + to_string(stmt_num));
std::set<int> active;
if (level < 0 || level > stmt[stmt_num].loop_level.size())
- throw std::invalid_argument("invalid loop level " + to_string(level));
+ throw std::invalid_argument("3invalid loop level " + to_string(level));
else if (level == 0) {
for (int i = 0; i < stmt.size(); i++)
active.insert(i);
@@ -436,8 +439,7 @@ void Loop::permute(const std::set<int> &active, const std::vector<int> &pi) {
break;
case LoopLevelTile: {
new_loop_level[j - 1].type = LoopLevelTile;
- int ref_level = stmt[*i].loop_level[reverse_pi[j - level]
- - 1].payload;
+ int ref_level = stmt[*i].loop_level[reverse_pi[j - level]-1].payload;
if (ref_level >= level && ref_level < level + pi.size())
new_loop_level[j - 1].payload = reverse_pi[ref_level
- level];
@@ -485,12 +487,18 @@ void Loop::permute(const std::set<int> &active, const std::vector<int> &pi) {
setLexicalOrder(2 * level - 2, active);
}
+
+void Loop::set_array_size(std::string name, int size ){
+ array_dims.insert(std::pair<std::string, int >(name, size));
+}
+
+
std::set<int> Loop::split(int stmt_num, int level, const Relation &cond) {
// check for sanity of parameters
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invalid statement " + to_string(stmt_num));
if (level <= 0 || level > stmt[stmt_num].loop_level.size())
- throw std::invalid_argument("invalid loop level " + to_string(level));
+ throw std::invalid_argument("4invalid loop level " + to_string(level));
std::set<int> result;
int dim = 2 * level - 1;
@@ -784,8 +792,17 @@ std::set<int> Loop::split(int stmt_num, int level, const Relation &cond) {
stmt[*i].IS = part1;
- if (Intersection(copy(part2),
- Extend_Set(copy(this->known), n - this->known.n_set())).is_upper_bound_satisfiable()) {
+ int n1 = part2.n_set();
+ int m = this->known.n_set();
+ Relation test;
+ if(m > n1)
+ test = Intersection(copy(this->known),
+ Extend_Set(copy(part2), m - part2.n_set()));
+ else
+ test = Intersection(copy(part2),
+ Extend_Set(copy(this->known), n1 - this->known.n_set()));
+
+ if (test.is_upper_bound_satisfiable()) {
Statement new_stmt;
new_stmt.code = stmt[*i].code->clone();
new_stmt.IS = part2;
@@ -793,14 +810,23 @@ std::set<int> Loop::split(int stmt_num, int level, const Relation &cond) {
new_stmt.ir_stmt_node = NULL;
new_stmt.loop_level = stmt[*i].loop_level;
+ new_stmt.has_inspector = stmt[*i].has_inspector;
+ new_stmt.reduction = stmt[*i].reduction;
+ new_stmt.reductionOp = stmt[*i].reductionOp;
+
stmt_nesting_level_.push_back(stmt_nesting_level_[*i]);
-
+
+
if (place_after)
assign_const(new_stmt.xform, dim - 1, cur_lex + 1);
else
assign_const(new_stmt.xform, dim - 1, cur_lex - 1);
+ fprintf(stderr, "loop_basic.cc L828 adding stmt %d\n", stmt.size());
stmt.push_back(new_stmt);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
dep.insert();
what_stmt_num[*i] = stmt.size() - 1;
if (*i == stmt_num)
@@ -898,7 +924,7 @@ void Loop::skew(const std::set<int> &stmt_nums, int level,
"invalid statement number " + to_string(*i));
if (level < 1 || level > stmt[*i].loop_level.size())
throw std::invalid_argument(
- "invalid loop level " + to_string(level));
+ "5invalid loop level " + to_string(level));
for (int j = stmt[*i].loop_level.size(); j < skew_amount.size(); j++)
if (skew_amount[j] != 0)
throw std::invalid_argument("invalid skewing formula");
@@ -952,76 +978,56 @@ void Loop::skew(const std::set<int> &stmt_nums, int level,
int cur_dep_dim = get_dep_dim_of(*i, kk + 1);
if (skew_amount[kk] > 0) {
if (lb != -posInfinity
- && stmt[*i].loop_level[kk].type
- == LoopLevelOriginal
- && dv.lbounds[cur_dep_dim]
- != -posInfinity)
- lb += skew_amount[kk]
- * dv.lbounds[cur_dep_dim];
+ && stmt[*i].loop_level[kk].type == LoopLevelOriginal
+ && dv.lbounds[cur_dep_dim] != -posInfinity)
+ lb += skew_amount[kk] * dv.lbounds[cur_dep_dim];
else {
if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim]
- == 0
- && dv.ubounds[cur_dep_dim]
- == 0))
+ && !(dv.lbounds[cur_dep_dim] == 0
+ && dv.ubounds[cur_dep_dim]== 0))
lb = -posInfinity;
}
if (ub != posInfinity
- && stmt[*i].loop_level[kk].type
- == LoopLevelOriginal
- && dv.ubounds[cur_dep_dim]
- != posInfinity)
- ub += skew_amount[kk]
- * dv.ubounds[cur_dep_dim];
+ && stmt[*i].loop_level[kk].type == LoopLevelOriginal
+ && dv.ubounds[cur_dep_dim] != posInfinity)
+ ub += skew_amount[kk] * dv.ubounds[cur_dep_dim];
else {
if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim]
- == 0
- && dv.ubounds[cur_dep_dim]
- == 0))
+ && !(dv.lbounds[cur_dep_dim] == 0
+ && dv.ubounds[cur_dep_dim] == 0))
ub = posInfinity;
}
} else if (skew_amount[kk] < 0) {
if (lb != -posInfinity
- && stmt[*i].loop_level[kk].type
- == LoopLevelOriginal
- && dv.ubounds[cur_dep_dim]
- != posInfinity)
- lb += skew_amount[kk]
- * dv.ubounds[cur_dep_dim];
+ && stmt[*i].loop_level[kk].type == LoopLevelOriginal
+ && dv.ubounds[cur_dep_dim] != posInfinity)
+ lb += skew_amount[kk] * dv.ubounds[cur_dep_dim];
else {
if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim]
- == 0
- && dv.ubounds[cur_dep_dim]
- == 0))
+ && !(dv.lbounds[cur_dep_dim] == 0
+ && dv.ubounds[cur_dep_dim] == 0))
lb = -posInfinity;
}
if (ub != posInfinity
- && stmt[*i].loop_level[kk].type
- == LoopLevelOriginal
- && dv.lbounds[cur_dep_dim]
- != -posInfinity)
- ub += skew_amount[kk]
- * dv.lbounds[cur_dep_dim];
+ && stmt[*i].loop_level[kk].type == LoopLevelOriginal
+ && dv.lbounds[cur_dep_dim] != -posInfinity)
+ ub += skew_amount[kk] * dv.lbounds[cur_dep_dim];
else {
if (cur_dep_dim != -1
- && !(dv.lbounds[cur_dep_dim]
- == 0
- && dv.ubounds[cur_dep_dim]
- == 0))
+ && !(dv.lbounds[cur_dep_dim] == 0
+ && dv.ubounds[cur_dep_dim] == 0))
ub = posInfinity;
}
}
}
dv.lbounds[dep_dim] = lb;
dv.ubounds[dep_dim] = ub;
- if ((dv.isCarried(dep_dim)
- && dv.hasPositive(dep_dim)) && dv.quasi)
+ if ((dv.isCarried(dep_dim) && dv.hasPositive(dep_dim))
+ && dv.quasi)
dv.quasi = false;
- if ((dv.isCarried(dep_dim)
- && dv.hasNegative(dep_dim)) && !dv.quasi)
+ if ((dv.isCarried(dep_dim) && dv.hasNegative(dep_dim))
+ && !dv.quasi)
throw loop_error(
"loop error: Skewing is illegal, dependence violation!");
dv.lbounds[dep_dim] = lb;
@@ -1085,7 +1091,7 @@ void Loop::shift(const std::set<int> &stmt_nums, int level, int shift_amount) {
"invalid statement number " + to_string(*i));
if (level < 1 || level > stmt[*i].loop_level.size())
throw std::invalid_argument(
- "invalid loop level " + to_string(level));
+ "6invalid loop level " + to_string(level));
}
// do nothing
@@ -1185,16 +1191,25 @@ void Loop::fuse(const std::set<int> &stmt_nums, int level) {
// check for sanity of parameters
std::vector<int> ref_lex;
int ref_stmt_num;
+ apply_xform();
for (std::set<int>::const_iterator i = stmt_nums.begin();
i != stmt_nums.end(); i++) {
- if (*i < 0 || *i >= stmt.size())
+ if (*i < 0 || *i >= stmt.size()) {
+ fprintf(stderr, "statement number %d should be in [0, %d)\n", *i, stmt.size());
throw std::invalid_argument(
- "invalid statement number " + to_string(*i));
+ "FUSE invalid statement number " + to_string(*i));
+ }
if (level <= 0
- || (level > (stmt[*i].xform.n_out() - 1) / 2
- || level > stmt[*i].loop_level.size()))
+ // || (level > (stmt[*i].xform.n_out() - 1) / 2
+ // || level > stmt[*i].loop_level.size())
+ ) {
+ fprintf(stderr, "FUSE level %d ", level);
+ fprintf(stderr, "must be greater than zero and \n");
+ fprintf(stderr, "must NOT be greater than (%d - 1)/2 == %d and\n", stmt[*i].xform.n_out(), (stmt[*i].xform.n_out() - 1) / 2);
+ fprintf(stderr, "must NOT be greater than %d\n", stmt[*i].loop_level.size());
throw std::invalid_argument(
- "invalid loop level " + to_string(level));
+ "FUSE invalid loop level " + to_string(level));
+ }
if (ref_lex.size() == 0) {
ref_lex = getLexicalOrder(*i);
ref_stmt_num = *i;
@@ -1258,14 +1273,66 @@ void Loop::fuse(const std::set<int> &stmt_nums, int level) {
std::vector<std::set<int> > s = sort_by_same_loops(same_loop, level);
- std::set<int> s1;
- std::set<int> s2;
- std::set<int> s4;
- std::vector<std::set<int> > s3;
+ std::vector<bool> s2;
+
+ for (int i = 0; i < s.size(); i++) {
+ s2.push_back(false);
+ }
+
for (std::set<int>::iterator kk = stmt_nums.begin(); kk != stmt_nums.end();
kk++)
for (int i = 0; i < s.size(); i++)
if (s[i].find(*kk) != s[i].end()) {
+
+ s2[i] = true;
+ }
+
+ try {
+
+ //Dependence Check for Ordering Constraint
+ //Graph<std::set<int>, bool> dummy = construct_induced_graph_at_level(s5,
+ // dep, dep_dim);
+
+ Graph<std::set<int>, bool> g = construct_induced_graph_at_level(s, dep,
+ dep_dim);
+ std::cout << g;
+ s = typed_fusion(g, s2);
+ } catch (const loop_error &e) {
+
+ throw loop_error(
+ "statements cannot be fused together due to negative dependence");
+
+ }
+
+ int order = 0;
+ for (int i = 0; i < s.size(); i++) {
+ for (std::set<int>::iterator it = s[i].begin(); it != s[i].end(); it++) {
+ assign_const(stmt[*it].xform, 2 * level - 2, order);
+ }
+ order++;
+ }
+
+
+ //plan for selective typed fusion
+
+ /*
+ 1. sort the lex values of the statements
+ 2. construct induced graph on sorted statements
+ 3. pick a node from the graph, check if it is before/after from the candidate set for fusion
+ equal-> set the max fused node of this node to be the start/target node for fusion
+ before -> augment and continue
+
+ 4. once target node identified and is on work queue update successors and other nodes to start node
+ 5. augment and continue
+ 6. if all candidate nodes dont end up in start node throw error
+ 7. Get nodes and update lexical values
+
+ */
+
+ /* for (std::set<int>::iterator kk = stmt_nums.begin(); kk != stmt_nums.end();
+ kk++)
+ for (int i = 0; i < s.size(); i++)
+ if (s[i].find(*kk) != s[i].end()) {
s1.insert(s[i].begin(), s[i].end());
s2.insert(i);
}
@@ -1282,10 +1349,12 @@ void Loop::fuse(const std::set<int> &stmt_nums, int level) {
s5.push_back(s4);
//Dependence Check for Ordering Constraint
-
+ //Graph<std::set<int>, bool> dummy = construct_induced_graph_at_level(s5,
+ // dep, dep_dim);
+
Graph<std::set<int>, bool> g = construct_induced_graph_at_level(s3, dep,
dep_dim);
-
+ std::cout<< g;
s = typed_fusion(g);
} catch (const loop_error &e) {
@@ -1346,7 +1415,7 @@ void Loop::fuse(const std::set<int> &stmt_nums, int level) {
} else
throw loop_error("Typed Fusion Error");
-
+ */
}
@@ -1354,7 +1423,9 @@ void Loop::fuse(const std::set<int> &stmt_nums, int level) {
void Loop::distribute(const std::set<int> &stmt_nums, int level) {
if (stmt_nums.size() == 0 || stmt_nums.size() == 1)
return;
-
+ fprintf(stderr, "Loop::distribute()\n");
+
+
// invalidate saved codegen computation
delete last_compute_cgr_;
last_compute_cgr_ = NULL;
@@ -1369,11 +1440,12 @@ void Loop::distribute(const std::set<int> &stmt_nums, int level) {
if (*i < 0 || *i >= stmt.size())
throw std::invalid_argument(
"invalid statement number " + to_string(*i));
+
if (level < 1
|| (level > (stmt[*i].xform.n_out() - 1) / 2
|| level > stmt[*i].loop_level.size()))
throw std::invalid_argument(
- "invalid loop level " + to_string(level));
+ "8invalid loop level " + to_string(level));
if (ref_lex.size() == 0) {
ref_lex = getLexicalOrder(*i);
ref_stmt_num = *i;
@@ -1386,6 +1458,7 @@ void Loop::distribute(const std::set<int> &stmt_nums, int level) {
+ to_string(level) + " subloop");
}
}
+
// find SCC in the to-be-distributed loop
int dep_dim = get_dep_dim_of(ref_stmt_num, level);
std::set<int> same_loop = getStatements(ref_lex, dim - 1);
@@ -1491,6 +1564,276 @@ void Loop::distribute(const std::set<int> &stmt_nums, int level) {
order++;
}
// no need to update dependence graph
+
return;
}
+
+
+
+std::vector<IR_ArrayRef *> FindOuterArrayRefs(IR_Code *ir,
+ std::vector<IR_ArrayRef *> &arr_refs) {
+ std::vector<IR_ArrayRef *> to_return;
+ for (int i = 0; i < arr_refs.size(); i++)
+ if (!ir->parent_is_array(arr_refs[i])) {
+ int j;
+ for (j = 0; j < to_return.size(); j++)
+ if (*to_return[j] == *arr_refs[i])
+ break;
+ if (j == to_return.size())
+ to_return.push_back(arr_refs[i]);
+ }
+ return to_return;
+}
+
+
+
+
+
+std::vector<std::vector<std::string> > constructInspectorVariables(IR_Code *ir,
+ std::set<IR_ArrayRef *> &arr, std::vector<std::string> &index) {
+
+ fprintf(stderr, "constructInspectorVariables()\n");
+
+ std::vector<std::vector<std::string> > to_return;
+
+ for (std::set<IR_ArrayRef *>::iterator i = arr.begin(); i != arr.end();
+ i++) {
+
+ std::vector<std::string> per_index;
+
+ CG_outputRepr *subscript = (*i)->index(0);
+
+ if ((*i)->n_dim() > 1)
+ throw ir_error(
+ "multi-dimensional array support non-existent for flattening currently");
+
+ while (ir->QueryExpOperation(subscript) == IR_OP_ARRAY_VARIABLE) {
+
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(subscript);
+
+ IR_ArrayRef *ref = static_cast<IR_ArrayRef *>(ir->Repr2Ref(v[0]));
+ //per_index.push_back(ref->name());
+
+ subscript = ref->index(0);
+
+ }
+
+ if (ir->QueryExpOperation(subscript) == IR_OP_VARIABLE) {
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(subscript);
+ IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+ per_index.push_back(ref->name());
+ int j;
+ for (j = 0; j < index.size(); j++)
+ if (index[j] == ref->name())
+ break;
+
+ if (j == index.size())
+ throw ir_error("Non index variable in array expression");
+
+ int k;
+ for (k = 0; k < to_return.size(); k++)
+ if (to_return[k][0] == ref->name())
+ break;
+ if (k == to_return.size()) {
+ to_return.push_back(per_index);
+ fprintf(stderr, "adding index %s\n", ref->name().c_str());
+ }
+
+ }
+
+ }
+
+ return to_return;
+
+}
+
+/*std::vector<CG_outputRepr *> constructInspectorData(IR_Code *ir, std::vector<std::vector<std::string> > &indices){
+
+ std::vector<CG_outputRepr *> to_return;
+
+ for(int i =0; i < indices.size(); i++)
+ ir->CreateVariableDeclaration(indices[i][0]);
+ return to_return;
+ }
+
+
+ CG_outputRepr* constructInspectorFunction(IR_Code* ir, std::vector<std::vector<std::string> > &indices){
+
+ CG_outputRepr *to_return;
+
+
+
+ return to_return;
+ }
+
+*/
+
+CG_outputRepr * checkAndGenerateIndirectMappings(CG_outputBuilder * ocg,
+ std::vector<std::vector<std::string> > &indices,
+ CG_outputRepr * instance, CG_outputRepr * class_def,
+ CG_outputRepr * count_var) {
+
+ CG_outputRepr *to_return = NULL;
+
+ for (int i = 0; i < indices.size(); i++)
+ if (indices[i].size() > 1) {
+ std::string index = indices[i][indices[i].size() - 1];
+ CG_outputRepr *rep = ocg->CreateArrayRefExpression(
+ ocg->CreateDotExpression(instance,
+ ocg->lookup_member_data(class_def, index, instance)),
+ count_var);
+ for (int j = indices[i].size() - 2; j >= 0; j--)
+ rep = ocg->CreateArrayRefExpression(indices[i][j], rep);
+
+ CG_outputRepr *lhs = ocg->CreateArrayRefExpression(
+ ocg->CreateDotExpression(instance,
+ ocg->lookup_member_data(class_def, indices[i][0], instance)),
+ count_var);
+
+ to_return = ocg->StmtListAppend(to_return,
+ ocg->CreateAssignment(0, lhs, rep));
+
+ }
+
+ return to_return;
+
+}
+
+CG_outputRepr *generatePointerAssignments(CG_outputBuilder *ocg,
+ std::string prefix_name,
+ std::vector<std::vector<std::string> > &indices,
+ CG_outputRepr *instance,
+ CG_outputRepr *class_def) {
+
+ fprintf(stderr, "generatePointerAssignments()\n");
+ CG_outputRepr *list = NULL;
+
+ fprintf(stderr, "prefix '%s', %d indices\n", prefix_name.c_str(), indices.size());
+ for (int i = 0; i < indices.size(); i++) {
+
+ std::string s = prefix_name + "_" + indices[i][0];
+
+ fprintf(stderr, "s %s\n", s.c_str());
+
+ // create a variable definition for a pointer to int with this name
+ // that seems to be the only actual result of this routine ...
+ //chillAST_VarDecl *vd = new chillAST_VarDecl( "int", prefix_name.c_str(), "*", NULL);
+ //vd->print(); printf("\n"); fflush(stdout);
+ //vd->dump(); printf("\n"); fflush(stdout);
+
+ CG_outputRepr *ptr_exp = ocg->CreatePointer(s); // but dropped on the floor. unused
+ //fprintf(stderr, "ptr_exp created\n");
+
+ //CG_outputRepr *rhs = ocg->CreateDotExpression(instance,
+ // ocg->lookup_member_data(class_def, indices[i][0], instance));
+
+ //CG_outputRepr *ptr_assignment = ocg->CreateAssignment(0, ptr_exp, rhs);
+
+ //list = ocg->StmtListAppend(list, ptr_assignment);
+
+ }
+
+ fprintf(stderr, "generatePointerAssignments() DONE\n\n");
+ return list;
+}
+
+void Loop::normalize(int stmt_num, int loop_level) {
+
+ if (stmt_num < 0 || stmt_num >= stmt.size())
+ throw std::invalid_argument(
+
+ "invalid statement number " + to_string(stmt_num));
+
+ if (loop_level <= 0)
+ throw std::invalid_argument(
+ "12invalid loop level " + to_string(loop_level));
+ if (loop_level > stmt[stmt_num].loop_level.size())
+ throw std::invalid_argument(
+ "there is no loop level " + to_string(loop_level)
+ + " for statement " + to_string(stmt_num));
+
+ apply_xform(stmt_num);
+
+ Relation r = copy(stmt[stmt_num].IS);
+
+ Relation bound = get_loop_bound(r, loop_level, this->known);
+ if (!bound.has_single_conjunct() || !bound.is_satisfiable()
+ || bound.is_tautology())
+ throw loop_error("unable to extract loop bound for normalize");
+
+ // extract the loop stride
+ coef_t stride;
+ std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(bound,
+ bound.set_var(loop_level));
+ if (result.second == NULL)
+ stride = 1;
+ else
+ stride = abs(result.first.get_coef(result.second))
+ / gcd(abs(result.first.get_coef(result.second)),
+ abs(result.first.get_coef(bound.set_var(loop_level))));
+
+ if (stride != 1)
+ throw loop_error(
+ "normalize currently only handles unit stride, non unit stride present in loop bounds");
+
+ GEQ_Handle lb;
+
+ Conjunct *c = bound.query_DNF()->single_conjunct();
+ for (GEQ_Iterator gi(c->GEQs()); gi; gi++) {
+ int coef = (*gi).get_coef(bound.set_var(loop_level));
+ if (coef > 0)
+ lb = *gi;
+ }
+
+ //Loop bound already zero
+ //Nothing to do.
+ if (lb.is_const(bound.set_var(loop_level)) && lb.get_const() == 0)
+ return;
+
+ if (lb.is_const_except_for_global(bound.set_var(loop_level))) {
+
+ int n = stmt[stmt_num].xform.n_out();
+
+ Relation r(n, n);
+ F_And *f_root = r.add_and();
+ for (int j = 1; j <= n; j++)
+ if (j != 2 * loop_level) {
+ EQ_Handle h = f_root->add_EQ();
+ h.update_coef(r.input_var(j), 1);
+ h.update_coef(r.output_var(j), -1);
+ }
+
+ stmt[stmt_num].xform = Composition(r, stmt[stmt_num].xform);
+ stmt[stmt_num].xform.simplify();
+
+ for (Constr_Vars_Iter ci(lb); ci; ci++) {
+ if ((*ci).var->kind() == Global_Var) {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ Variable_ID v;
+ if (g->arity() == 0)
+ v = stmt[stmt_num].xform.get_local(g);
+ else
+ v = stmt[stmt_num].xform.get_local(g,
+ (*ci).var->function_of());
+
+ F_And *f_super_root = stmt[stmt_num].xform.and_with_and();
+ F_Exists *f_exists = f_super_root->add_exists();
+ F_And *f_root = f_exists->add_and();
+
+ EQ_Handle h = f_root->add_EQ();
+ h.update_coef(stmt[stmt_num].xform.output_var(2 * loop_level),
+ 1);
+ h.update_coef(stmt[stmt_num].xform.input_var(loop_level), -1);
+ h.update_coef(v, 1);
+
+ stmt[stmt_num].xform.simplify();
+ }
+
+ }
+
+ } else
+ throw loop_error("loop bounds too complex for normalize!");
+
+}
+
diff --git a/src/loop_datacopy.cc b/src/loop_datacopy.cc
index 1ccd444..12d74fd 100644
--- a/src/loop_datacopy.cc
+++ b/src/loop_datacopy.cc
@@ -21,8 +21,15 @@
using namespace omega;
+//
+// data copy function by referring arrays by numbers.
+// e.g. A[i] = A[i-1] + B[i]
+// parameter array_ref_num=[0,2] means to copy data touched by A[i-1] and A[i]
+//
bool Loop::datacopy(const std::vector<std::pair<int, std::vector<int> > > &array_ref_nums, int level,
bool allow_extra_read, int fastest_changing_dimension, int padding_stride, int padding_alignment, int memory_type) {
+ //fprintf(stderr, "Loop::datacopy()\n");
+
// check for sanity of parameters
std::set<int> same_loop;
for (int i = 0; i < array_ref_nums.size(); i++) {
@@ -67,11 +74,22 @@ bool Loop::datacopy(const std::vector<std::pair<int, std::vector<int> > > &array
throw std::invalid_argument("found no array references to copy");
// do the copy
- return datacopy_privatized(selected_refs, level, std::vector<int>(), allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ bool whatever = datacopy_privatized(selected_refs, level, std::vector<int>(), allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ return whatever;
}
+//
+// data copy function by referring arrays by name.
+// e.g. A[i] = A[i-1] + B[i]
+// parameter array_name=A means to copy data touched by A[i-1] and A[i]
+//
bool Loop::datacopy(int stmt_num, int level, const std::string &array_name,
bool allow_extra_read, int fastest_changing_dimension, int padding_stride, int padding_alignment, int memory_type) {
+
+ fflush(stdout);
+ //fprintf(stderr, "Loop::datacopy2()\n");
+ //fprintf(stderr, "array name %s stmt num %d\n", array_name.c_str(), stmt_num);
+
// check for sanity of parameters
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invalid statement number " + to_string(stmt_num));
@@ -95,16 +113,38 @@ bool Loop::datacopy(int stmt_num, int level, const std::string &array_name,
if (t.size() != 0)
selected_refs.push_back(std::make_pair(*i, t));
}
+
+ //fprintf(stderr, "selected refs:\n");
+ //for (int i=0; i<selected_refs.size(); i++) {
+ // //fprintf(stderr, "%d 0x%x ", selected_refs[i].first, selected_refs[i].second[0]);
+ // selected_refs[i].second[0]->Dump(); printf("\n"); fflush(stdout);
+ //}
+
if (selected_refs.size() == 0)
throw std::invalid_argument("found no array references with name " + to_string(array_name) + " to copy");
+ IR_ArrayRef *AR = selected_refs[0].second[0];
+ //IR_roseArrayRef *RAR = (IR_roseArrayRef *)AR;
+ //fprintf(stderr, "before datacopy_privatized, ");
+ //AR->Dump();
+
// do the copy
- return datacopy_privatized(selected_refs, level, std::vector<int>(), allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ //fprintf(stderr, "\nLoop::datacopy2 calling privatized\n");
+
+ bool whatever = datacopy_privatized(selected_refs, level, std::vector<int>(), allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+
+ //AR = selected_refs[0].second[0];
+ //fprintf(stderr, "after datacopy_privatized, ");
+ //AR->Dump();
+
+ return whatever;
}
bool Loop::datacopy_privatized(int stmt_num, int level, const std::string &array_name, const std::vector<int> &privatized_levels,
bool allow_extra_read, int fastest_changing_dimension, int padding_stride, int padding_alignment, int memory_type) {
+ //fprintf(stderr, "Loop::datacopy_privatized()\n");
+
// check for sanity of parameters
if (stmt_num < 0 || stmt_num >= stmt.size())
throw std::invalid_argument("invalid statement number " + to_string(stmt_num));
@@ -131,11 +171,14 @@ bool Loop::datacopy_privatized(int stmt_num, int level, const std::string &array
throw std::invalid_argument("found no array references with name " + to_string(array_name) + " to copy");
// do the copy
- return datacopy_privatized(selected_refs, level, privatized_levels, allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ bool whatever = datacopy_privatized(selected_refs, level, privatized_levels, allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ return whatever;
}
bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<int> > > &array_ref_nums, int level, const std::vector<int> &privatized_levels, bool allow_extra_read, int fastest_changing_dimension, int padding_stride, int padding_alignment, int memory_type) {
+ //fprintf(stderr, "Loop::datacopy_privatized2()\n");
+
// check for sanity of parameters
std::set<int> same_loop;
for (int i = 0; i < array_ref_nums.size(); i++) {
@@ -180,13 +223,28 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<int>
throw std::invalid_argument("found no array references to copy");
// do the copy
- return datacopy_privatized(selected_refs, level, privatized_levels, allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ bool whatever = datacopy_privatized(selected_refs, level, privatized_levels, allow_extra_read, fastest_changing_dimension, padding_stride, padding_alignment, memory_type);
+ return whatever;
}
-bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_ArrayRef *> > > &stmt_refs, int level,
+
+//
+// Implement low level datacopy function with lots of options.
+//
+
+bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_ArrayRef *> > > &stmt_refs,
+ int level,
const std::vector<int> &privatized_levels,
- bool allow_extra_read, int fastest_changing_dimension,
- int padding_stride, int padding_alignment, int memory_type) {
+ bool allow_extra_read,
+ int fastest_changing_dimension,
+ int padding_stride,
+ int padding_alignment,
+ int memory_type) {
+
+ //fprintf(stderr, "\nLoop::datacopy_privatized3() *****\n");
+ //fprintf(stderr, "privatized_levels.size() %d\n", privatized_levels.size());
+ //fprintf(stderr, "level %d\n", level);
+
if (stmt_refs.size() == 0)
return true;
@@ -233,6 +291,12 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
}
}
+
+ //fprintf(stderr, "sym %p\n", sym);
+ if (!sym) {
+ fprintf(stderr, "sym NULL, gonna die\n"); int *i=0; int j=i[0];
+ }
+
if (!(fastest_changing_dimension >= -1 && fastest_changing_dimension < sym->n_dim()))
throw std::invalid_argument("invalid fastest changing dimension for the array to be copied");
if (padding_stride < 0)
@@ -255,6 +319,7 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
default:
throw loop_error("unsupported array layout");
}
+ // OK, parameter sanity checked
// invalidate saved codegen computation
@@ -264,20 +329,58 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
last_compute_cg_ = NULL;
// build iteration spaces for all reads and for all writes separately
+ //fprintf(stderr, "dp3: before apply_xform() ARRAY REFS\n");
+ //for (int i = 0; i < stmt_refs.size(); i++) {
+ // for (int j = 0; j < stmt_refs[i].second.size(); j++) {
+ // IR_ArrayRef *AR = stmt_refs[i].second[j];
+ // fprintf(stderr, "array ref ij %d %d ", i, j); AR->Dump(); fprintf(stderr, "\n");
+ // }
+ //}
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "stmt %d = ", i);
+ // stmt[i].code->dump();
+ // fprintf(stderr, "\n");
+ //}
+
apply_xform(active);
+ //fprintf(stderr, "dp3: back from apply_xform() ARRAY REFS\n");
+
+ //for (int i = 0; i < stmt_refs.size(); i++) {
+ // for (int j = 0; j < stmt_refs[i].second.size(); j++) {
+ // IR_ArrayRef *AR = stmt_refs[i].second[j];
+ // fprintf(stderr, "array ref ij %d %d ", i, j);
+ // AR->Dump();
+ // fprintf(stderr, "\n");
+ // }
+ //}
+
+ //for (int i=0; i<stmt.size(); i++) {
+ // fprintf(stderr, "stmt %d = ", i);
+ // stmt[i].code->dump();
+ // fprintf(stderr, "\n");
+ //}
+
bool has_write_refs = false;
bool has_read_refs = false;
Relation wo_copy_is = Relation::False(level-1+privatized_levels.size()+n_dim);
Relation ro_copy_is = Relation::False(level-1+privatized_levels.size()+n_dim);
+ //fprintf(stderr, "\n\ni range: 0-%d\n", -1 + stmt_refs.size());
+ int stmt_num = stmt_refs[0].first;
for (int i = 0; i < stmt_refs.size(); i++) {
int stmt_num = stmt_refs[i].first;
+ //fprintf(stderr, "j range: 0-%d\n", -1 + stmt_refs[i].second.size());
+
for (int j = 0; j < stmt_refs[i].second.size(); j++) {
+ //fprintf(stderr, "ij %d %d\n", i, j);
+
Relation mapping(stmt[stmt_num].IS.n_set(), level-1+privatized_levels.size()+n_dim);
for (int k = 1; k <= mapping.n_inp(); k++)
mapping.name_input_var(k, stmt[stmt_num].IS.set_var(k)->name());
mapping.setup_names();
+ mapping.print(); fflush(stdout); // "{[I] -> [_t1] : I = _t1 }
+
F_And *f_root = mapping.add_and();
for (int k = 1; k <= level-1; k++) {
EQ_Handle h = f_root->add_EQ();
@@ -290,12 +393,28 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
h.update_coef(mapping.output_var(level+k), -1);
}
for (int k = 0; k < n_dim; k++) {
+ IR_ArrayRef *AR = stmt_refs[i].second[j];
+ //fprintf(stderr, "array ref ");
+ AR->Dump();
+
CG_outputRepr *repr = stmt_refs[i].second[j]->index(k);
- exp2formula(ir, mapping, f_root, freevar, repr, mapping.output_var(level-1+privatized_levels.size()+k+1), 'w', IR_COND_EQ, false);
+ //fprintf(stderr, "k %d j %d repr ", k, j); repr->dump(); fflush(stdout);
+
+ exp2formula(ir,
+ mapping,
+ f_root,
+ freevar,
+ repr,
+ mapping.output_var(level-1+privatized_levels.size()+k+1),
+ 'w',
+ IR_COND_EQ,
+ false,
+ uninterpreted_symbols[stmt_num],
+ uninterpreted_symbols_stringrepr[stmt_num]);
repr->clear();
delete repr;
}
- Relation r = Range(Restrict_Domain(mapping, Intersection(copy(stmt[stmt_num].IS), Extend_Set(copy(this->known), stmt[stmt_num].IS.n_set() - this->known.n_set()))));
+ Relation r = omega::Range(Restrict_Domain(mapping, Intersection(copy(stmt[stmt_num].IS), Extend_Set(copy(this->known), stmt[stmt_num].IS.n_set() - this->known.n_set()))));
if (stmt_refs[i].second[j]->is_write()) {
has_write_refs = true;
wo_copy_is = Union(wo_copy_is, r);
@@ -312,6 +431,7 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
}
+ //fprintf(stderr, "dp3: simplify\n");
// simplify read and write footprint iteration space
{
if (allow_extra_read)
@@ -356,6 +476,7 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
ro_copy_is.setup_names();
}
+ //fprintf(stderr, "\ndp3: build merged\n");
// build merged footprint iteration space for calculating temporary array size
Relation copy_is = SimpleHull(Union(copy(ro_copy_is), copy(wo_copy_is)), true, true);
@@ -368,37 +489,48 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
Relation reduced_copy_is = copy(copy_is);
for (int i = 0; i < n_dim; i++) {
+ //fprintf(stderr, "i %d/%d\n", i, n_dim);
if (i != 0)
reduced_copy_is = Project(reduced_copy_is, level-1+privatized_levels.size()+i, Set_Var);
Relation bound = get_loop_bound(reduced_copy_is, level-1+privatized_levels.size()+i);
+ //fprintf(stderr, "dp3: extract stride\n");
// extract stride
std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(bound, bound.set_var(level-1+privatized_levels.size()+i+1));
if (result.second != NULL)
index_stride[i] = abs(result.first.get_coef(result.second))/gcd(abs(result.first.get_coef(result.second)), abs(result.first.get_coef(bound.set_var(level-1+privatized_levels.size()+i+1))));
else
index_stride[i] = 1;
+ //fprintf(stderr, "dp3: index_stride[%d] = %d\n", i, index_stride[i]);
- // check if this arary index requires loop
+ // check if this array index requires loop
Conjunct *c = bound.query_DNF()->single_conjunct();
for (EQ_Iterator ei(c->EQs()); ei; ei++) {
+ //fprintf(stderr, "dp3: for\n");
if ((*ei).has_wildcards())
continue;
+ //fprintf(stderr, "dp3: no wildcards\n");
int coef = (*ei).get_coef(bound.set_var(level-1+privatized_levels.size()+i+1));
if (coef != 0) {
+ //fprintf(stderr, "coef != 0\n");
int sign = 1;
if (coef < 0) {
+ //fprintf(stderr, "coef < 0\n");
coef = -coef;
sign = -1;
}
CG_outputRepr *op = NULL;
for (Constr_Vars_Iter ci(*ei); ci; ci++) {
+ //fprintf(stderr, "dp3: ci\n");
switch ((*ci).var->kind()) {
case Input_Var:
{
- if ((*ci).var != bound.set_var(level-1+privatized_levels.size()+i+1))
+ //fprintf(stderr, "dp3: Input_Var\n");
+ if ((*ci).var != bound.set_var(level-1+privatized_levels.size()+i+1)) {
+ //fprintf(stderr, "dp3: IF sign %d\n",(*ci).coef*sign);
+
if ((*ci).coef*sign == 1)
op = ocg->CreateMinus(op, ocg->CreateIdent((*ci).var->name()));
else if ((*ci).coef*sign == -1)
@@ -407,10 +539,12 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
op = ocg->CreateMinus(op, ocg->CreateTimes(ocg->CreateInt(abs((*ci).coef)), ocg->CreateIdent((*ci).var->name())));
else // (*ci).coef*sign < -1
op = ocg->CreatePlus(op, ocg->CreateTimes(ocg->CreateInt(abs((*ci).coef)), ocg->CreateIdent((*ci).var->name())));
+ }
break;
}
case Global_Var:
{
+ //fprintf(stderr, "dp3: Global_Var\n");
Global_Var_ID g = (*ci).var->get_global_var();
if ((*ci).coef*sign == 1)
op = ocg->CreateMinus(op, ocg->CreateIdent(g->base_name()));
@@ -439,7 +573,8 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
if (is_index_eq[i])
continue;
- // seperate lower and upper bounds
+ //fprintf(stderr, "dp3: separate lower and upper bounds\n");
+ // separate lower and upper bounds
std::vector<GEQ_Handle> lb_list, ub_list;
std::set<Variable_ID> excluded_floor_vars;
excluded_floor_vars.insert(bound.set_var(level-1+privatized_levels.size()+i+1));
@@ -465,19 +600,41 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
if (lb_list.size() == 0 || ub_list.size() == 0)
throw loop_error("failed to calcuate array footprint size");
+ //fprintf(stderr, "dp3: build lower bound representation\n");
// build lower bound representation
std::vector<CG_outputRepr *> lb_repr_list;
for (int j = 0; j < lb_list.size(); j++){
- if(this->known.n_set() == 0)
- lb_repr_list.push_back(output_lower_bound_repr(ocg, lb_list[j], bound.set_var(level-1+privatized_levels.size()+i+1), result.first, result.second, bound, Relation::True(bound.n_set()), std::vector<std::pair<CG_outputRepr *, int> >(bound.n_set(), std::make_pair(static_cast<CG_outputRepr *>(NULL), 0))));
- else
- lb_repr_list.push_back(output_lower_bound_repr(ocg, lb_list[j], bound.set_var(level-1+privatized_levels.size()+i+1), result.first, result.second, bound, this->known, std::vector<std::pair<CG_outputRepr *, int> >(bound.n_set(), std::make_pair(static_cast<CG_outputRepr *>(NULL), 0))));
+ if(this->known.n_set() == 0) {
+ lb_repr_list.push_back(output_lower_bound_repr(ocg,
+ lb_list[j],
+ bound.set_var(level-1+privatized_levels.size()+i+1),
+ result.first,
+ result.second,
+ bound,
+ Relation::True(bound.n_set()),
+ std::vector<std::pair<CG_outputRepr *, int> >(bound.n_set(), std::make_pair(static_cast<CG_outputRepr *>(NULL), 0)),
+ uninterpreted_symbols[stmt_num]));
+ }
+ else {
+ lb_repr_list.push_back(output_lower_bound_repr(ocg,
+ lb_list[j],
+ bound.set_var(level-1+privatized_levels.size()+i+1),
+ result.first,
+ result.second,
+ bound,
+ this->known,
+ std::vector<std::pair<CG_outputRepr *, int> >(bound.n_set(), std::make_pair(static_cast<CG_outputRepr *>(NULL), 0)),
+ uninterpreted_symbols[stmt_num]));
+ }
}
- if (lb_repr_list.size() > 1)
+ if (lb_repr_list.size() > 1) {
+ //fprintf(stderr, "loop_datacopy.cc dp3 createInvoke( max )\n");
index_lb[i] = ocg->CreateInvoke("max", lb_repr_list);
+ }
else if (lb_repr_list.size() == 1)
index_lb[i] = lb_repr_list[0];
+ //fprintf(stderr, "dp3: build temporary array size representation\n");
// build temporary array size representation
{
Relation cal(copy_is.n_set(), 1);
@@ -545,6 +702,7 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
cal = Project(cal, j, Input_Var);
cal.simplify();
+ //fprintf(stderr, "dp3: pad temporary array size\n");
// pad temporary array size
// TODO: for variable array size, create padding formula
Conjunct *c = cal.query_DNF()->single_conjunct();
@@ -626,8 +784,9 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
}
+ //fprintf(stderr, "dp3: change the temporary array index order\n");
// change the temporary array index order
- for (int i = 0; i < index_sz.size(); i++)
+ for (int i = 0; i < index_sz.size(); i++) {
if (index_sz[i].first == fastest_changing_dimension)
switch (sym->layout_type()) {
case IR_ARRAY_LAYOUT_ROW_MAJOR:
@@ -639,36 +798,53 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
default:
throw loop_error("unsupported array layout");
}
-
+ }
+
+ //fprintf(stderr, "dp3: declare temporary array or scalar\n");
// declare temporary array or scalar
IR_Symbol *tmp_sym;
if (index_sz.size() == 0) {
+ //fprintf(stderr, "tmp_sym is a scalar\n");
tmp_sym = ir->CreateScalarSymbol(sym, memory_type);
}
else {
+ //fprintf(stderr, "tmp_sym is an array\n");
std::vector<CG_outputRepr *> tmp_array_size(index_sz.size());
- for (int i = 0; i < index_sz.size(); i++)
+ for (int i = 0; i < index_sz.size(); i++) {
tmp_array_size[i] = index_sz[i].second->clone();
+ index_sz[i].second->dump(); // THIS PRINTF
+ }
tmp_sym = ir->CreateArraySymbol(sym, tmp_array_size, memory_type);
}
+ //fprintf(stderr, "dp3: create temporary array read initialization code\n");
// create temporary array read initialization code
CG_outputRepr *copy_code_read;
- if (has_read_refs)
+ if (has_read_refs) {
+ //fprintf(stderr, "has read refs\n");
if (index_sz.size() == 0) {
- IR_ScalarRef *tmp_scalar_ref = ir->CreateScalarRef(static_cast<IR_ScalarSymbol *>(tmp_sym));
+ //fprintf(stderr, "if\n");
+ //fprintf(stderr, "tmp sym %s\n", tmp_sym->name().c_str());
+ IR_ScalarRef *tmp_scalar_ref = ir->CreateScalarRef(static_cast<IR_ScalarSymbol *>(tmp_sym)); // create ref from symbol
+ // tmp_scalar_ref is incomplete
+
std::vector<CG_outputRepr *> rhs_index(n_dim);
- for (int i = 0; i < index_lb.size(); i++)
+ for (int i = 0; i < index_lb.size(); i++) {
+ //fprintf(stderr, "i %d\n", i);
if (is_index_eq[i])
rhs_index[i] = index_lb[i]->clone();
else
rhs_index[i] = ir->builder()->CreateIdent(copy_is.set_var(level-1+privatized_levels.size()+i+1)->name());
+ }
IR_ArrayRef *copied_array_ref = ir->CreateArrayRef(sym, rhs_index);
+ // IR_ScalarRef tmp_scalar_ref has no actual reference yet. It only has the variable definition.
copy_code_read = ir->builder()->CreateAssignment(0, tmp_scalar_ref->convert(), copied_array_ref->convert());
+ //fprintf(stderr, "if ends\n");
}
else {
+ //fprintf(stderr, "else\n");
std::vector<CG_outputRepr *> lhs_index(index_sz.size());
for (int i = 0; i < index_sz.size(); i++) {
int cur_index_num = index_sz[i].first;
@@ -693,7 +869,9 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
lhs_index[i] = cur_index_repr;
}
+ //fprintf(stderr, "dp3: making tmp_array_ref\n");
IR_ArrayRef *tmp_array_ref = ir->CreateArrayRef(static_cast<IR_ArraySymbol *>(tmp_sym), lhs_index);
+ //fprintf(stderr, "dp3: DONE making tmp_array_ref\n");
std::vector<CG_outputRepr *> rhs_index(n_dim);
for (int i = 0; i < index_lb.size(); i++)
@@ -703,13 +881,22 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
rhs_index[i] = ir->builder()->CreateIdent(copy_is.set_var(level-1+privatized_levels.size()+i+1)->name());
IR_ArrayRef *copied_array_ref = ir->CreateArrayRef(sym, rhs_index);
- copy_code_read = ir->builder()->CreateAssignment(0, tmp_array_ref->convert(), copied_array_ref->convert());
+ //fprintf(stderr, "dp3: loop_datacopy.cc copy_code_read = CreateAssignment\n");
+ //copy_code_read = ir->builder()->CreateAssignment(0, tmp_array_ref->convert(), copied_array_ref->convert());
+ CG_outputRepr *lhs = tmp_array_ref->convert();
+ CG_outputRepr *rhs = copied_array_ref->convert();
+ copy_code_read = ir->builder()->CreateAssignment(0, lhs, rhs); //tmp_array_ref->convert(), copied_array_ref->convert());
+ //fprintf(stderr, "dp3: loop_datacopy.cc copy_code_read = CreateAssignment DONE\n\n");
}
+ } // has read refs
+ //fprintf(stderr, "dp3: create temporary array write back code\n");
// create temporary array write back code
CG_outputRepr *copy_code_write;
- if (has_write_refs)
+ if (has_write_refs) {
+ //fprintf(stderr, "has_write_refs\n");
if (index_sz.size() == 0) {
+ //fprintf(stderr, "index_sz.size() == 0\n");
IR_ScalarRef *tmp_scalar_ref = ir->CreateScalarRef(static_cast<IR_ScalarSymbol *>(tmp_sym));
std::vector<CG_outputRepr *> rhs_index(n_dim);
@@ -723,6 +910,8 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
copy_code_write = ir->builder()->CreateAssignment(0, copied_array_ref->convert(), tmp_scalar_ref->convert());
}
else {
+ //fprintf(stderr, "index_sz.size() NOT = 0\n");
+
std::vector<CG_outputRepr *> lhs_index(n_dim);
for (int i = 0; i < index_lb.size(); i++)
if (is_index_eq[i])
@@ -758,9 +947,11 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
copy_code_write = ir->builder()->CreateAssignment(0, copied_array_ref->convert(), tmp_array_ref->convert());
}
+ } // has write refs
// now we can remove those loops for array indexes that are
// dependent on others
+ //fprintf(stderr, "dp3: now we can remove those loops\n");
if (!(index_sz.size() == n_dim && (sym->layout_type() == IR_ARRAY_LAYOUT_ROW_MAJOR || n_dim <= 1))) {
Relation mapping(level-1+privatized_levels.size()+n_dim, level-1+privatized_levels.size()+index_sz.size());
F_And *f_root = mapping.add_and();
@@ -793,8 +984,8 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
cur_index++;
}
- wo_copy_is = Range(Restrict_Domain(copy(mapping), wo_copy_is));
- ro_copy_is = Range(Restrict_Domain(copy(mapping), ro_copy_is));
+ wo_copy_is = omega::Range(Restrict_Domain(copy(mapping), wo_copy_is));
+ ro_copy_is = omega::Range(Restrict_Domain(copy(mapping), ro_copy_is));
for (int i = 1; i <= level-1+privatized_levels.size(); i++) {
wo_copy_is.name_set_var(i, copy_is.set_var(i)->name());
ro_copy_is.name_set_var(i, copy_is.set_var(i)->name());
@@ -808,6 +999,8 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
// insert read copy statement
+ //fprintf(stderr, "dp3: insert read copy statement\n");
+
int old_num_stmt = stmt.size();
int ro_copy_stmt_num = -1;
if (has_read_refs) {
@@ -834,8 +1027,10 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
copy_stmt_read.IS = ro_copy_is;
copy_stmt_read.xform = copy_xform;
copy_stmt_read.code = copy_code_read;
+ //fprintf(stderr, "dp3: copy_stmt_read.code = \n");
copy_stmt_read.loop_level = std::vector<LoopLevel>(ro_copy_is.n_set());
copy_stmt_read.ir_stmt_node = NULL;
+ copy_stmt_read.has_inspector = false;
for (int i = 0; i < level-1; i++) {
copy_stmt_read.loop_level[i].type = stmt[*(active.begin())].loop_level[i].type;
if (stmt[*(active.begin())].loop_level[i].type == LoopLevelTile &&
@@ -859,12 +1054,12 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
copy_stmt_read.loop_level[level-1+i].parallel_level = stmt[*(active.begin())].loop_level[privatized_levels[i]].parallel_level;
}
int left_num_dim = num_dep_dim - (get_last_dep_dim_before(*(active.begin()), level) + 1);
- for (int i = 0; i < min(left_num_dim, static_cast<int>(index_sz.size())); i++) {
+ for (int i = 0; i < std::min(left_num_dim, static_cast<int>(index_sz.size())); i++) {
copy_stmt_read.loop_level[level-1+privatized_levels.size()+i].type = LoopLevelOriginal;
copy_stmt_read.loop_level[level-1+privatized_levels.size()+i].payload = num_dep_dim-left_num_dim+i;
copy_stmt_read.loop_level[level-1+privatized_levels.size()+i].parallel_level = 0;
}
- for (int i = min(left_num_dim, static_cast<int>(index_sz.size())); i < index_sz.size(); i++) {
+ for (int i = std::min(left_num_dim, static_cast<int>(index_sz.size())); i < index_sz.size(); i++) {
copy_stmt_read.loop_level[level-1+privatized_levels.size()+i].type = LoopLevelUnknown;
copy_stmt_read.loop_level[level-1+privatized_levels.size()+i].payload = -1;
copy_stmt_read.loop_level[level-1+privatized_levels.size()+i].parallel_level = 0;
@@ -872,11 +1067,17 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
shiftLexicalOrder(lex, dim-1, 1);
+
+ fprintf(stderr, "loop_datacopy.cc L1071 adding stmt %d\n", stmt.size());
stmt.push_back(copy_stmt_read);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[*(active.begin())]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[*(active.begin())]);
ro_copy_stmt_num = stmt.size() - 1;
dep.insert();
}
+ //fprintf(stderr, "dp3: insert write copy statement\n");
// insert write copy statement
int wo_copy_stmt_num = -1;
if (has_write_refs) {
@@ -905,6 +1106,7 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
copy_stmt_write.code = copy_code_write;
copy_stmt_write.loop_level = std::vector<LoopLevel>(wo_copy_is.n_set());
copy_stmt_write.ir_stmt_node = NULL;
+ copy_stmt_write.has_inspector = false;
for (int i = 0; i < level-1; i++) {
copy_stmt_write.loop_level[i].type = stmt[*(active.begin())].loop_level[i].type;
@@ -929,28 +1131,35 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
copy_stmt_write.loop_level[level-1+i].parallel_level = stmt[*(active.begin())].loop_level[privatized_levels[i]].parallel_level;
}
int left_num_dim = num_dep_dim - (get_last_dep_dim_before(*(active.begin()), level) + 1);
- for (int i = 0; i < min(left_num_dim, static_cast<int>(index_sz.size())); i++) {
+ for (int i = 0; i < std::min(left_num_dim, static_cast<int>(index_sz.size())); i++) {
copy_stmt_write.loop_level[level-1+privatized_levels.size()+i].type = LoopLevelOriginal;
copy_stmt_write.loop_level[level-1+privatized_levels.size()+i].payload = num_dep_dim-left_num_dim+i;
copy_stmt_write.loop_level[level-1+privatized_levels.size()+i].parallel_level = 0;
}
- for (int i = min(left_num_dim, static_cast<int>(index_sz.size())); i < index_sz.size(); i++) {
+ for (int i = std::min(left_num_dim, static_cast<int>(index_sz.size())); i < index_sz.size(); i++) {
copy_stmt_write.loop_level[level-1+privatized_levels.size()+i].type = LoopLevelUnknown;
copy_stmt_write.loop_level[level-1+privatized_levels.size()+i].payload = -1;
copy_stmt_write.loop_level[level-1+privatized_levels.size()+i].parallel_level = 0;
}
lex[dim-1]++;
shiftLexicalOrder(lex, dim-1, -2);
+
+ fprintf(stderr, "loop_datacopy.cc L1147 adding stmt %d\n", stmt.size());
stmt.push_back(copy_stmt_write);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[*(active.begin())]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[*(active.begin())]);
wo_copy_stmt_num = stmt.size() - 1;
dep.insert();
}
+ //fprintf(stderr, "replace original array accesses with temporary array accesses\n");
// replace original array accesses with temporary array accesses
for (int i =0; i < stmt_refs.size(); i++)
for (int j = 0; j < stmt_refs[i].second.size(); j++) {
if (index_sz.size() == 0) {
IR_ScalarRef *tmp_scalar_ref = ir->CreateScalarRef(static_cast<IR_ScalarSymbol *>(tmp_sym));
+ //fprintf(stderr, "dp3: loop_datacopy.cc calling ReplaceExpression i%d j%d\n", i, j);
ir->ReplaceExpression(stmt_refs[i].second[j], tmp_scalar_ref->convert());
}
else {
@@ -980,11 +1189,14 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
IR_ArrayRef *tmp_array_ref = ir->CreateArrayRef(static_cast<IR_ArraySymbol *>(tmp_sym), index_repr);
+ //fprintf(stderr, "loop_datacopy.cc ir->ReplaceExpression( ... )\n");
ir->ReplaceExpression(stmt_refs[i].second[j], tmp_array_ref->convert());
}
}
// update dependence graph
+ //fprintf(stderr, "update dependence graph\n");
+
int dep_dim = get_last_dep_dim_before(*(active.begin()), level) + 1;
if (ro_copy_stmt_num != -1) {
for (int i = 0; i < old_num_stmt; i++) {
@@ -1029,6 +1241,8 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
// insert dependences from copy statement loop to copied statements
+ //fprintf(stderr, "insert dependences from copy statement loop to copied statements\n");
+
DependenceVector dv;
dv.type = DEP_W2R;
dv.sym = tmp_sym->clone();
@@ -1085,6 +1299,8 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
// insert dependences from copied statements to write statements
+ //fprintf(stderr, "dp3: insert dependences from copied statements to write statements\n");
+
DependenceVector dv;
dv.type = DEP_W2R;
dv.sym = tmp_sym->clone();
@@ -1133,6 +1349,7 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
}
}
+ //fprintf(stderr, "Loop::datacopy_privatized3() cleanup\n");
// cleanup
delete sym;
delete tmp_sym;
@@ -1147,3 +1364,6 @@ bool Loop::datacopy_privatized(const std::vector<std::pair<int, std::vector<IR_A
return true;
}
+
+
+
diff --git a/src/loop_unroll.cc b/src/loop_unroll.cc
index 911d900..86ffd84 100644
--- a/src/loop_unroll.cc
+++ b/src/loop_unroll.cc
@@ -20,6 +20,7 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
std::vector<std::vector<std::string> > idxNames,
int cleanup_split_level) {
// check for sanity of parameters
+ // check for sanity of parameters
if (unroll_amount < 0)
throw std::invalid_argument(
"invalid unroll amount " + to_string(unroll_amount));
@@ -70,6 +71,16 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
}
dim2 = stmt[*i].loop_level[dim2].payload;
+ /*if (dv.isCarried(dim2)
+ && (dv.hasNegative(dim2) && !dv.quasi))
+ throw loop_error(
+ "loop error: Unrolling is illegal, dependence violation!");
+
+ if (dv.isCarried(dim2)
+ && (dv.hasPositive(dim2) && dv.quasi))
+ throw loop_error(
+ "loop error: Unrolling is illegal, dependence violation!");
+ */
bool safe = false;
if (dv.isCarried(dim2) && dv.hasPositive(dim2)) {
@@ -78,11 +89,20 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
"loop error: a quasi dependence with a positive carried distance");
if (!dv.quasi) {
if (dv.lbounds[dim2] != posInfinity) {
+ //if (dv.lbounds[dim2] != negInfinity)
if (dv.lbounds[dim2] > unroll_amount)
safe = true;
} else
safe = true;
- }
+ }/* else {
+ if (dv.ubounds[dim2] != negInfinity) {
+ if (dv.ubounds[dim2] != posInfinity)
+ if ((-(dv.ubounds[dim2])) > unroll_amount)
+ safe = true;
+ } else
+ safe = true;
+ }*/
+
if (!safe) {
for (int l = level + 1; l <= (n - 1) / 2; l++) {
int dim3 = l - 1;
@@ -131,7 +151,7 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
h.update_coef(mapping.output_var(j), -1);
}
hull = Intersection(hull,
- Range(Restrict_Domain(mapping, copy(stmt[*i].IS))));
+ omega::Range(Restrict_Domain(mapping, copy(stmt[*i].IS))));
hull.simplify(2, 4);
}
@@ -288,7 +308,8 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
overflow_table[i][j][NULL] = int_mod_hat(
overflow_table[i][j][NULL], unroll_amount);
- // Since we don't have MODULO instruction in SUIF yet (only MOD), make all coef positive in the final formula
+ // Since we don't have MODULO instruction in SUIF yet (only MOD),
+ // make all coef positive in the final formula
for (std::map<Variable_ID, int>::iterator k =
overflow_table[i][j].begin();
k != overflow_table[i][j].end(); k++)
@@ -437,14 +458,16 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
std::vector<CG_outputRepr *> lb_repr_list, ub_repr_list;
for (int i = 0; i < lb_list.size(); i++) {
lb_repr_list.push_back(
- output_lower_bound_repr(ocg, lb_list[i],
+ output_lower_bound_repr(ocg,
+ lb_list[i],
bound.set_var(dim + 1), result.first, result.second,
bound, Relation::True(bound.n_set()),
std::vector<std::pair<CG_outputRepr *, int> >(
bound.n_set(),
std::make_pair(
static_cast<CG_outputRepr *>(NULL),
- 0))));
+ 0)),
+ uninterpreted_symbols[stmt_num]));
GEQ_Handle h = cond_lower.and_with_GEQ(lb_list[i]);
}
for (int i = 0; i < ub_list.size(); i++) {
@@ -455,21 +478,28 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
bound.n_set(),
std::make_pair(
static_cast<CG_outputRepr *>(NULL),
- 0))));
+ 0)),
+ uninterpreted_symbols[stmt_num]));
GEQ_Handle h = cond_upper.and_with_GEQ(ub_list[i]);
h.update_coef(cond_upper.get_local(over_free_var), -stride);
}
- CG_outputRepr *lbRepr, *ubRepr;
- if (lb_repr_list.size() > 1)
+ CG_outputRepr *lbRepr, *ubRepr;
+ if (lb_repr_list.size() > 1) {
+ //fprintf(stderr, "loop_unroll.cc createInvoke( max )\n");
lbRepr = ocg->CreateInvoke("max", lb_repr_list);
- else if (lb_repr_list.size() == 1)
+ }
+ else if (lb_repr_list.size() == 1) {
lbRepr = lb_repr_list[0];
+ }
- if (ub_repr_list.size() > 1)
+ if (ub_repr_list.size() > 1) {
+ //fprintf(stderr, "loop_unroll.cc createInvoke( min )\n");
ubRepr = ocg->CreateInvoke("min", ub_repr_list);
- else if (ub_repr_list.size() == 1)
+ }
+ else if (ub_repr_list.size() == 1) {
ubRepr = ub_repr_list[0];
+ }
// create overflow assignment
CG_outputRepr *rhs = ocg->CreatePlus(ocg->CreateMinus(ubRepr, lbRepr),
@@ -503,7 +533,7 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
h.update_coef(mapping.output_var(i), 1);
h.update_coef(mapping.input_var(i), -1);
}
- Relation overflow_IS = Range(Restrict_Domain(mapping, copy(hull)));
+ Relation overflow_IS = omega::Range(Restrict_Domain(mapping, copy(hull)));
for (int i = 1; i < cleanup_split_level; i++)
overflow_IS.name_set_var(i, hull.set_var(i)->name());
overflow_IS.setup_names();
@@ -548,7 +578,11 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
stmt[stmt_num].loop_level[i].parallel_level;
}
+ fprintf(stderr, "loop_unroll.cc L581 adding stmt %d\n", stmt.size());
stmt.push_back(overflow_stmt);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
dep.insert();
overflow_stmt_num = stmt.size() - 1;
overflow[overflow_stmt_num] = over_var_list;
@@ -567,8 +601,7 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
dv.type = DEP_W2W;
{
IR_ScalarSymbol *overflow_sym = NULL;
- std::vector<IR_ScalarRef *> scalars = ir->FindScalarRef(
- overflow_code);
+ std::vector<IR_ScalarRef *> scalars = ir->FindScalarRef(overflow_code);
for (int i = scalars.size() - 1; i >= 0; i--)
if (scalars[i]->is_write()) {
overflow_sym = scalars[i]->symbol();
@@ -703,7 +736,12 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
new_stmt.loop_level = stmt[*i].loop_level;
new_stmt.ir_stmt_node = NULL;
+
+ fprintf(stderr, "loop_unroll.cc L740 adding stmt %d\n", stmt.size());
stmt.push_back(new_stmt);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
dep.insert();
what_stmt_num[*i].push_back(stmt.size() - 1);
}
@@ -990,33 +1028,70 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
Statement new_stmt;
new_stmt.code = NULL;
- for (int j = 1; j < unroll_amount; j++)
+ for (int j = 1; j < unroll_amount; j++) {
for (int i = 0; i < stmt_order.size(); i++) {
std::vector<std::string> loop_vars;
std::vector<CG_outputRepr *> subs;
+
+ //fprintf(stderr, "loop_unroll.cc, will replace '%s with '%s+%d' ??\n",
+ // stmt[stmt_order[i].second].IS.set_var(level)->name().c_str(),
+ // stmt[stmt_order[i].second].IS.set_var(level)->name().c_str(), j * stride);
+
loop_vars.push_back(
stmt[stmt_order[i].second].IS.set_var(level)->name());
subs.push_back(
- ocg->CreatePlus(
- ocg->CreateIdent(
- stmt[stmt_order[i].second].IS.set_var(
- level)->name()),
- ocg->CreateInt(j * stride)));
+ ocg->CreatePlus(ocg->CreateIdent(stmt[stmt_order[i].second].IS.set_var(level)->name()),
+ ocg->CreateInt(j * stride))); // BUG HERE
+ //fprintf(stderr, "loop_unroll.cc subs now has %d parts\n", subs.size());
+ //for (int k=0; k< subs.size(); k++) //fprintf(stderr, "subs[%d] = 0x%x\n", k, subs[k]);
+
+ //fprintf(stderr, "ij %d %d ", i, j);
+ //fprintf(stderr, "old src was =\n");
+ //stmt[stmt_order[i].second].code->dump(); fflush(stdout); //fprintf(stderr, "\n");
+
+
+
CG_outputRepr *code = ocg->CreateSubstitutedStmt(0,
- stmt[stmt_order[i].second].code->clone(), loop_vars,
+ stmt[stmt_order[i].second].code->clone(),
+ loop_vars,
subs);
+
+ //fprintf(stderr, "old src is =\n");
+ //stmt[stmt_order[i].second].code->dump(); fflush(stdout); //fprintf(stderr, "\n");
+
+ //fprintf(stderr, "substituted copy is =\n");
+ //code->dump(); //fprintf(stderr, "\n\n");
+
+
new_stmt.code = ocg->StmtListAppend(new_stmt.code, code);
+ //fprintf(stderr, "appended code =\n");
+ //new_stmt.code->dump();
+
}
+ }
+
+
+ //fprintf(stderr, "new_stmt.IS = \n");
new_stmt.IS = copy(stmt[stmt_num].IS);
new_stmt.xform = copy(stmt[stmt_num].xform);
assign_const(new_stmt.xform, 2 * max_level,
stmt_order[stmt_order.size() - 1].first + 1);
new_stmt.loop_level = stmt[stmt_num].loop_level;
new_stmt.ir_stmt_node = NULL;
+
+ new_stmt.has_inspector = false; // ?? or from copied stmt?
+ if (stmt[stmt_num].has_inspector) fprintf(stderr, "OLD STMT HAS INSPECTOR\n");
+ else fprintf(stderr, "OLD STMT DOES NOT HAVE INSPECTOR\n");
+
+ fprintf(stderr, "loop_unroll.cc L1083 adding stmt %d\n", stmt.size());
stmt.push_back(new_stmt);
+
+ uninterpreted_symbols.push_back(uninterpreted_symbols[stmt_num]);
+ uninterpreted_symbols_stringrepr.push_back(uninterpreted_symbols_stringrepr[stmt_num]);
dep.insert();
+ //fprintf(stderr, "update dependence graph\n");
// update dependence graph
if (stmt[stmt_num].loop_level[level - 1].type == LoopLevelOriginal) {
int dep_dim = stmt[stmt_num].loop_level[level - 1].payload;
@@ -1140,6 +1215,7 @@ std::set<int> Loop::unroll(int stmt_num, int level, int unroll_amount,
}
}
+ //fprintf(stderr, " loop_unroll.cc returning new_stmts\n");
return new_stmts;
}
diff --git a/src/omegatools.cc b/src/omegatools.cc
index 3aac404..0322182 100644
--- a/src/omegatools.cc
+++ b/src/omegatools.cc
@@ -14,10 +14,15 @@
*****************************************************************************/
#include <code_gen/codegen.h>
+
#include "omegatools.hh"
#include "ir_code.hh"
#include "chill_error.hh"
+#include "chill_ast.hh"
+#include "code_gen/CG_chillRepr.h"
+#include <code_gen/CG_utils.h>
+
using namespace omega;
namespace {
@@ -41,471 +46,855 @@ std::string tmp_e() {
return std::string("e")+to_string(counter++);
}
-void exp2formula(IR_Code *ir, Relation &r, F_And *f_root, std::vector<Free_Var_Decl*> &freevars,
- CG_outputRepr *repr, Variable_ID lhs, char side, IR_CONDITION_TYPE rel, bool destroy) {
+
+
+//-----------------------------------------------------------------------------
+// Convert expression tree to omega relation. "destroy" means shallow
+// deallocation of "repr", not freeing the actual code inside.
+// -----------------------------------------------------------------------------
+void exp2formula(IR_Code *ir,
+ Relation &r,
+ F_And *f_root,
+ std::vector<Free_Var_Decl*> &freevars,
+ CG_outputRepr *repr,
+ Variable_ID lhs,
+ char side,
+ IR_CONDITION_TYPE rel,
+ bool destroy,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_stringrepr
+ ) {
- switch (ir->QueryExpOperation(repr)) {
- case IR_OP_CONSTANT:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
- IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[0]));
- if (!ref->is_integer())
- throw ir_exp_error("non-integer constant coefficient");
+ fprintf(stderr, "\n*** exp2formula()\n");
+ //repr->dump(); /* printf("\n"); */fflush(stdout);
+ fprintf(stderr, "repr "); r.print(); printf("\n"); fflush(stdout);
+
+
+ IR_OPERATION_TYPE optype = ir->QueryExpOperation(repr);
+
+ switch (optype) {
- coef_t c = ref->integer();
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_root->add_GEQ();
- h.update_coef(lhs, 1);
- if (rel == IR_COND_GE)
+
+
+
+ case IR_OP_CONSTANT:
+ {
+ fprintf(stderr, "IR_OP_CONSTANT\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[0]));
+ if (!ref->is_integer())
+ throw ir_exp_error("non-integer constant coefficient");
+
+ coef_t c = ref->integer();
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ GEQ_Handle h = f_root->add_GEQ();
+ h.update_coef(lhs, 1);
+ if (rel == IR_COND_GE)
+ h.update_const(-c);
+ else
+ h.update_const(-c-1);
+ }
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ GEQ_Handle h = f_root->add_GEQ();
+ h.update_coef(lhs, -1);
+ if (rel == IR_COND_LE)
+ h.update_const(c);
+ else
+ h.update_const(c-1);
+ }
+ else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_root->add_EQ();
+ h.update_coef(lhs, 1);
h.update_const(-c);
+ }
else
- h.update_const(-c-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_root->add_GEQ();
- h.update_coef(lhs, -1);
- if (rel == IR_COND_LE)
- h.update_const(c);
- else
- h.update_const(c-1);
- }
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(lhs, 1);
- h.update_const(-c);
+ throw std::invalid_argument("unsupported condition type");
+
+ delete v[0];
+ delete ref;
+ if (destroy)
+ delete repr;
+
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
- delete v[0];
- delete ref;
- if (destroy)
- delete repr;
- break;
- }
case IR_OP_VARIABLE:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
- IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
-
- std::string s = ref->name();
- Variable_ID e = find_index(r, s, side);
-
- if (e == NULL) { // must be free variable
- Free_Var_Decl *t = NULL;
- for (unsigned i = 0; i < freevars.size(); i++) {
- std::string ss = freevars[i]->base_name();
- if (s == ss) {
- t = freevars[i];
- break;
+ {
+ fprintf(stderr, "IR_OP_VARIABLE\n");
+ //fprintf(stderr, "repr "); repr->dump(); fflush(stdout);
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ //fprintf(stderr, "v "); v[0]->dump(); fflush(stdout);
+ IR_ScalarRef *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+
+ //fprintf(stderr, "omegatools.cc calling ref->name()\n");
+ std::string s = ref->name();
+ Variable_ID e = find_index(r, s, side);
+ //fprintf(stderr, "s %s\n", s.c_str());
+
+
+ if (e == NULL) { // must be free variable
+ Free_Var_Decl *t = NULL;
+ for (unsigned i = 0; i < freevars.size(); i++) {
+ std::string ss = freevars[i]->base_name();
+ if (s == ss) {
+ t = freevars[i];
+ break;
+ }
+ }
+
+ if (t == NULL) {
+ t = new Free_Var_Decl(s);
+ freevars.insert(freevars.end(), t);
}
+
+ e = r.get_local(t);
}
- if (t == NULL) {
- t = new Free_Var_Decl(s);
- freevars.insert(freevars.end(), t);
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ GEQ_Handle h = f_root->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ GEQ_Handle h = f_root->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e, 1);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
}
+ else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_root->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
- e = r.get_local(t);
- }
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_root->add_GEQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, -1);
- if (rel == IR_COND_GT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_root->add_GEQ();
- h.update_coef(lhs, -1);
- h.update_coef(e, 1);
- if (rel == IR_COND_LT)
- h.update_const(-1);
+ // delete v[0];
+ delete ref;
+ if (destroy)
+ delete repr;
+ break;
}
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_root->add_EQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, -1);
+
+ case IR_OP_ASSIGNMENT:
+ {
+ fprintf(stderr, "IR_OP_ASSIGNMENT\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
- // delete v[0];
- delete ref;
- if (destroy)
- delete repr;
- break;
- }
- case IR_OP_ASSIGNMENT:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
- exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true);
- if (destroy)
- delete repr;
- break;
- }
case IR_OP_PLUS:
- {
- F_Exists *f_exists = f_root->add_exists();
- Variable_ID e1 = f_exists->declare(tmp_e());
- Variable_ID e2 = f_exists->declare(tmp_e());
- F_And *f_and = f_exists->add_and();
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, 1);
- h.update_coef(e1, -1);
- h.update_coef(e2, -1);
- if (rel == IR_COND_GT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -1);
- h.update_coef(e1, 1);
- h.update_coef(e2, 1);
- if (rel == IR_COND_LT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_and->add_EQ();
- h.update_coef(lhs, 1);
- h.update_coef(e1, -1);
- h.update_coef(e2, -1);
+ {
+ fprintf(stderr, "IR_OP_PLUS\n");
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e1 = f_exists->declare(tmp_e());
+ Variable_ID e2 = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e1, -1);
+ h.update_coef(e2, -1);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e1, 1);
+ h.update_coef(e2, 1);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e1, -1);
+ h.update_coef(e2, -1);
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
+
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
-
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
- exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true);
- exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true);
- if (destroy)
- delete repr;
- break;
- }
case IR_OP_MINUS:
- {
- F_Exists *f_exists = f_root->add_exists();
- Variable_ID e1 = f_exists->declare(tmp_e());
- Variable_ID e2 = f_exists->declare(tmp_e());
- F_And *f_and = f_exists->add_and();
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, 1);
- h.update_coef(e1, -1);
- h.update_coef(e2, 1);
- if (rel == IR_COND_GT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -1);
- h.update_coef(e1, 1);
- h.update_coef(e2, -1);
- if (rel == IR_COND_LT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_and->add_EQ();
- h.update_coef(lhs, 1);
- h.update_coef(e1, -1);
- h.update_coef(e2, 1);
+ {
+ fprintf(stderr, "IR_OP_MINUS\n");
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e1 = f_exists->declare(tmp_e());
+ Variable_ID e2 = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e1, -1);
+ h.update_coef(e2, 1);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e1, 1);
+ h.update_coef(e2, -1);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e1, -1);
+ h.update_coef(e2, 1);
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
+
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ fprintf(stderr, "IR_OP_MINUS v has %d parts\n", (int)v.size());
+ fprintf(stderr, "IR_OP_MINUS recursing 1\n");
+ exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (v.size() > 1) {
+ fprintf(stderr, "IR_OP_MINUS recursing 2\n"); // dies here because it's unary minus?
+ exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+
+
+ if (destroy)
+ delete repr;
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
-
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
- exp2formula(ir, r, f_and, freevars, v[0], e1, side, IR_COND_EQ, true);
- exp2formula(ir, r, f_and, freevars, v[1], e2, side, IR_COND_EQ, true);
- if (destroy)
- delete repr;
- break;
- }
+
+
case IR_OP_MULTIPLY:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
-
- coef_t coef;
- CG_outputRepr *term;
- if (ir->QueryExpOperation(v[0]) == IR_OP_CONSTANT) {
- IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[0]));
- coef = ref->integer();
- delete v[0];
- delete ref;
- term = v[1];
+ {
+ fprintf(stderr, "IR_OP_MULTIPLY\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ coef_t coef;
+ CG_outputRepr *term;
+ if (ir->QueryExpOperation(v[0]) == IR_OP_CONSTANT) {
+ IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[0]));
+ coef = ref->integer();
+ delete v[0];
+ delete ref;
+ term = v[1];
+ }
+ else if (ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT) {
+ IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[1]));
+ coef = ref->integer();
+ delete v[1];
+ delete ref;
+ term = v[0];
+ }
+ else
+ throw ir_exp_error("not presburger expression");
+
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -coef);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e, coef);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
+ }
+ else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -coef);
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
+
+ exp2formula(ir, r, f_and, freevars, term, e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- else if (ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT) {
+
+ case IR_OP_DIVIDE:
+ {
+ fprintf(stderr, "IR_OP_DIVIDE\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ assert(ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT);
IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[1]));
- coef = ref->integer();
+ coef_t coef = ref->integer();
delete v[1];
delete ref;
- term = v[0];
- }
- else
- throw ir_exp_error("not presburger expression");
-
- F_Exists *f_exists = f_root->add_exists();
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_exists->add_and();
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, -coef);
- if (rel == IR_COND_GT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -1);
- h.update_coef(e, coef);
- if (rel == IR_COND_LT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_and->add_EQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, -coef);
- }
- else
- throw std::invalid_argument("unsupported condition type");
-
- exp2formula(ir, r, f_and, freevars, term, e, side, IR_COND_EQ, true);
- if (destroy)
- delete repr;
- break;
- }
- case IR_OP_DIVIDE:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
-
- assert(ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT);
- IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[1]));
- coef_t coef = ref->integer();
- delete v[1];
- delete ref;
-
- F_Exists *f_exists = f_root->add_exists();
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_exists->add_and();
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, coef);
- h.update_coef(e, -1);
- if (rel == IR_COND_GT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -coef);
- h.update_coef(e, 1);
- if (rel == IR_COND_LT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_and->add_EQ();
- h.update_coef(lhs, coef);
- h.update_coef(e, -1);
- }
- else
- throw std::invalid_argument("unsupported condition type");
-
- exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true);
- if (destroy)
- delete repr;
- break;
- }
- case IR_OP_POSITIVE:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
-
- exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true);
- if (destroy)
- delete repr;
- break;
- }
- case IR_OP_NEGATIVE:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
-
- F_Exists *f_exists = f_root->add_exists();
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_exists->add_and();
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, 1);
- if (rel == IR_COND_GT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -1);
- h.update_coef(e, -1);
- if (rel == IR_COND_LT)
- h.update_const(-1);
- }
- else if (rel == IR_COND_EQ) {
- EQ_Handle h = f_and->add_EQ();
- h.update_coef(lhs, 1);
- h.update_coef(e, 1);
- }
- else
- throw std::invalid_argument("unsupported condition type");
-
- exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true);
- if (destroy)
- delete repr;
- break;
- }
- case IR_OP_MIN:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
-
- F_Exists *f_exists = f_root->add_exists();
-
- if (rel == IR_COND_GE || rel == IR_COND_GT) {
- F_Or *f_or = f_exists->add_and()->add_or();
- for (int i = 0; i < v.size(); i++) {
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_or->add_and();
+
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, 1);
+ h.update_coef(lhs, coef);
h.update_coef(e, -1);
if (rel == IR_COND_GT)
h.update_const(-1);
-
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true);
}
- }
- else if (rel == IR_COND_LE || rel == IR_COND_LT) {
- F_And *f_and = f_exists->add_and();
- for (int i = 0; i < v.size(); i++) {
- Variable_ID e = f_exists->declare(tmp_e());
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -1);
+ h.update_coef(lhs, -coef);
h.update_coef(e, 1);
if (rel == IR_COND_LT)
h.update_const(-1);
-
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true);
}
+ else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, coef);
+ h.update_coef(e, -1);
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
+
+ exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
}
- else if (rel == IR_COND_EQ) {
- F_Or *f_or = f_exists->add_and()->add_or();
- for (int i = 0; i < v.size(); i++) {
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_or->add_and();
+
+ case IR_OP_MOD:
+ {
+ fprintf(stderr, "IR_OP_MOD\n");
+ /* the left hand of a mod can be a var but the right must be a const */
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ assert(ir->QueryExpOperation(v[1]) == IR_OP_CONSTANT);
+ IR_ConstantRef *ref = static_cast<IR_ConstantRef *>(ir->Repr2Ref(v[1]));
+ coef_t coef = ref->integer();
+ delete v[1];
+ delete ref;
+
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e = f_exists->declare(tmp_e());
+ Variable_ID b = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+
+ if (rel == IR_COND_EQ)
+ {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(b, coef);
+ h.update_coef(e, -1);
+ }
+
+ else if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ //i = CONST alpha + beta && beta >= const ( handled higher up ) && beta < CONST
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(b, coef);
+ h.update_coef(e, -1);
+ GEQ_Handle k = f_and->add_GEQ();
+ k.update_coef(lhs, -1 );
+ k.update_const(coef-1);
+
+ }
+
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ //i = CONST alpha + beta && beta <= const ( handled higher up ) && beta >= 0
EQ_Handle h = f_and->add_EQ();
h.update_coef(lhs, 1);
+ h.update_coef(b, coef);
h.update_coef(e, -1);
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false);
+ GEQ_Handle k = f_and->add_GEQ();
+ k.update_coef(lhs, 1 );
- for (int j = 0; j < v.size(); j++)
- if (j != i) {
- Variable_ID e2 = f_exists->declare(tmp_e());
- GEQ_Handle h2 = f_and->add_GEQ();
- h2.update_coef(e, -1);
- h2.update_coef(e2, 1);
-
- exp2formula(ir, r, f_and, freevars, v[j], e2, side, IR_COND_EQ, false);
- }
}
- for (int i = 0; i < v.size(); i++)
- delete v[i];
+ exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
- if (destroy)
- delete repr;
- }
- case IR_OP_MAX:
- {
- std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
- F_Exists *f_exists = f_root->add_exists();
+ case IR_OP_POSITIVE:
+ {
+ fprintf(stderr, "IR_OP_POSITIVE\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ exp2formula(ir, r, f_root, freevars, v[0], lhs, side, rel, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (destroy)
+ delete repr;
+ break;
+ }
+
- if (rel == IR_COND_LE || rel == IR_COND_LT) {
- F_Or *f_or = f_exists->add_and()->add_or();
- for (int i = 0; i < v.size(); i++) {
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_or->add_and();
+ case IR_OP_NEGATIVE:
+ {
+ fprintf(stderr, "IR_OP_NEGATIVE\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ F_Exists *f_exists = f_root->add_exists();
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_exists->add_and();
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, -1);
+ h.update_coef(lhs, 1);
h.update_coef(e, 1);
- if (rel == IR_COND_LT)
+ if (rel == IR_COND_GT)
h.update_const(-1);
-
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true);
}
- }
- else if (rel == IR_COND_GE || rel == IR_COND_GT) {
- F_And *f_and = f_exists->add_and();
- for (int i = 0; i < v.size(); i++) {
- Variable_ID e = f_exists->declare(tmp_e());
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
GEQ_Handle h = f_and->add_GEQ();
- h.update_coef(lhs, 1);
+ h.update_coef(lhs, -1);
h.update_coef(e, -1);
- if (rel == IR_COND_GT)
+ if (rel == IR_COND_LT)
h.update_const(-1);
-
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true);
}
- }
- else if (rel == IR_COND_EQ) {
- F_Or *f_or = f_exists->add_and()->add_or();
- for (int i = 0; i < v.size(); i++) {
- Variable_ID e = f_exists->declare(tmp_e());
- F_And *f_and = f_or->add_and();
-
+ else if (rel == IR_COND_EQ) {
EQ_Handle h = f_and->add_EQ();
h.update_coef(lhs, 1);
- h.update_coef(e, -1);
+ h.update_coef(e, 1);
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
+
+ exp2formula(ir, r, f_and, freevars, v[0], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ if (destroy)
+ delete repr;
+ break;
+ }
+
+
+ case IR_OP_MIN:
+ {
+ fprintf(stderr, "IR_OP_MIN\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ F_Exists *f_exists = f_root->add_exists();
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ F_Or *f_or = f_exists->add_and()->add_or();
+ for (int i = 0; i < v.size(); i++) {
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_or->add_and();
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+
+ exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
+ else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ F_And *f_and = f_exists->add_and();
+ for (int i = 0; i < v.size(); i++) {
+ Variable_ID e = f_exists->declare(tmp_e());
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e, 1);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
+
+ exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
+ else if (rel == IR_COND_EQ) {
+ F_Or *f_or = f_exists->add_and()->add_or();
+ for (int i = 0; i < v.size(); i++) {
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_or->add_and();
+
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+
+ exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ for (int j = 0; j < v.size(); j++)
+ if (j != i) {
+ Variable_ID e2 = f_exists->declare(tmp_e());
+ GEQ_Handle h2 = f_and->add_GEQ();
+ h2.update_coef(e, -1);
+ h2.update_coef(e2, 1);
+
+ exp2formula(ir, r, f_and, freevars, v[j], e2, side,
+ IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
- exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false);
+ for (int i = 0; i < v.size(); i++)
+ delete v[i];
+ }
+ else
+ throw std::invalid_argument("unsupported condition type");
+
+ if (destroy)
+ delete repr;
+ break;
+ }
+
+ case IR_OP_MAX:
+ {
+ fprintf(stderr, "IR_OP_MAX\n");
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+
+ F_Exists *f_exists = f_root->add_exists();
+
+ if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ F_Or *f_or = f_exists->add_and()->add_or();
+ for (int i = 0; i < v.size(); i++) {
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_or->add_and();
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e, 1);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
+
+ exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
+ else if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ F_And *f_and = f_exists->add_and();
+ for (int i = 0; i < v.size(); i++) {
+ Variable_ID e = f_exists->declare(tmp_e());
+ GEQ_Handle h = f_and->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+
+ exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ }
+ }
+ else if (rel == IR_COND_EQ) {
+ F_Or *f_or = f_exists->add_and()->add_or();
+ for (int i = 0; i < v.size(); i++) {
+ Variable_ID e = f_exists->declare(tmp_e());
+ F_And *f_and = f_or->add_and();
+
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+
+ exp2formula(ir, r, f_and, freevars, v[i], e, side, IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ for (int j = 0; j < v.size(); j++)
+ if (j != i) {
+ Variable_ID e2 = f_exists->declare(tmp_e());
+ GEQ_Handle h2 = f_and->add_GEQ();
+ h2.update_coef(e, 1);
+ h2.update_coef(e2, -1);
+
+ exp2formula(ir, r, f_and, freevars, v[j], e2, side, IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ }
- for (int j = 0; j < v.size(); j++)
- if (j != i) {
- Variable_ID e2 = f_exists->declare(tmp_e());
- GEQ_Handle h2 = f_and->add_GEQ();
- h2.update_coef(e, 1);
- h2.update_coef(e2, -1);
-
- exp2formula(ir, r, f_and, freevars, v[j], e2, side, IR_COND_EQ, false);
- }
+ for (int i = 0; i < v.size(); i++)
+ delete v[i];
}
+ else
+ throw std::invalid_argument("unsupported condition type");
- for (int i = 0; i < v.size(); i++)
- delete v[i];
+ if (destroy)
+ delete repr;
+ break;
}
- else
- throw std::invalid_argument("unsupported condition type");
- if (destroy)
- delete repr;
+ case IR_OP_ARRAY_VARIABLE: { // *****
+ fprintf(stderr, "\nomegatools.cc IR_OP_ARRAY_VARIABLE ARRAY! \n");
+
+ // temp for printing
+ //CG_chillRepr *CR = (CG_chillRepr *)repr;
+ //fprintf(stderr, "repr "); CR->dump(); fflush(stdout);
+
+ //fprintf(stderr, "repr "); repr->dump(); /* printf("\n"); */fflush(stdout);
+
+ std::vector<CG_outputRepr *> v = ir->QueryExpOperand(repr);
+ IR_Ref *ref = static_cast<IR_ScalarRef *>(ir->Repr2Ref(v[0]));
+
+
+ CG_chillRepr *CR = (CG_chillRepr *)v[0]; // cheat for now. we should not know this is a chillRepr
+ //fprintf(stderr, "v "); CR->dump(); fflush(stdout);
+ //fprintf(stderr, "v "); v[0]->dump(); /* printf("\n"); */ fflush(stdout);
+ chillAST_node* node = CR->GetCode();
+
+
+ //fprintf(stderr, "\n**** walking parents!\n");
+ //std::vector<chillAST_VarDecl*> loopvars;
+ //node->gatherLoopIndeces( loopvars );
+ //fprintf(stderr, "in omegatools, %d loop vars\n", (int)loopvars.size());
+
+
+ std::string s = ref->name();
+ //fprintf(stderr, "array variable s is %s\n", s.c_str());
+
+ int max_dim = 0;
+ bool need_new_fsymbol = false;
+ std::set<std::string> vars;
+ //fprintf(stderr, "ref->n_dim %d\n", ref->n_dim());
+ for (int i = 0; i < ref->n_dim(); i++) {
+ //fprintf(stderr, "dimension %d\n", i);
+ Relation temp(r.n_inp());
+
+ // r is enclosing relation, we build another that will include this
+ r.setup_names();
+ if (r.is_set())
+ for (int j = 1; j <= r.n_set(); j++) {
+ temp.name_set_var(j, r.set_var(j)->name());
+ }
+ else
+ for (int j = 1; j <= r.n_inp(); j++) {
+ temp.name_input_var(j, r.input_var(j)->name());
+ }
+
+ F_And *temp_root = temp.add_and();
+
+ CG_outputRepr* repr;
+ if(dynamic_cast<IR_PointerArrayRef *>(ref) != NULL)
+ repr = dynamic_cast<IR_PointerArrayRef *>(ref)->index(i); // i or i+1
+ else if(dynamic_cast<IR_ArrayRef *>(ref) != NULL)
+ repr = dynamic_cast<IR_ArrayRef *>(ref)->index(i);
+
+ std::vector<Free_Var_Decl*> freevars;
+ Free_Var_Decl *t = new Free_Var_Decl(s);
+ Variable_ID e = temp.get_local(t);
+ freevars.insert(freevars.end(), t);
+
+ fprintf(stderr, "exp2formula recursing? \n");
+ exp2formula(ir, temp, temp_root, freevars, repr, e, side,
+ IR_COND_EQ, false, uninterpreted_symbols,
+ uninterpreted_symbols_stringrepr);
+ fprintf(stderr, "BACK FROM exp2formula recursing? \n");
+
+ // temp is relation for the index of the array ??
+ for (DNF_Iterator di(temp.query_DNF()); di; di++) {
+ for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) {
+
+ if ((*ei).get_const() != 0)
+ need_new_fsymbol = true;
+ for (Constr_Vars_Iter cvi(*ei); cvi; cvi++)
+ if ((*cvi).var->kind() == Input_Var) {
+ if ((*cvi).var->get_position() > max_dim)
+ max_dim = (*cvi).var->get_position();
+ vars.insert(
+ r.input_var((*cvi).var->get_position())->name());
+
+ }
+ }
+
+ }
+
+ if (max_dim != ref->n_dim())
+ need_new_fsymbol = true;
+ }
+
+ //fprintf(stderr, "%d vars: ", (int)vars.size());
+ //for (int i=0; i<vars.size(); i++) fprintf(stderr, "%s", vars[i].c_str());
+ //for (std::set<std::string>::iterator it = vars.begin(); it != vars.end(); it++) {
+ // fprintf(stderr, "%s ", (*it).c_str());
+ //}
+ //fprintf(stderr, "\n");
+
+ // r is enclosing relation, we build another that will include
+ Variable_ID e = find_index(r, s, side); // s is the array named "index"
+
+ std::vector<chillAST_node*> internals = ((CG_chillRepr *)v[0])->getChillCode();
+ int numnodes = internals.size(); // always 1?
+ std::vector<chillAST_DeclRefExpr *>dres;
+ std::vector<chillAST_VarDecl*> decls;
+ std::vector<chillAST_VarDecl*> sdecls;
+ for (int i=0; i<numnodes; i++) {
+ internals[i]->gatherScalarVarDecls(sdecls); // vardecls for scalars
+ }
+
+ //fprintf(stderr, "%d scalar var decls()\n", sdecls.size());
+ //for (int i=0; i<sdecls.size(); i++) {
+ // fprintf(stderr, "vardecl %2d: ", i);
+ // sdecls[i]->print(); printf("\n"); fflush(stdout);
+ //}
+
+
+ //fprintf(stderr, "omegatools.cc, exp2formula() NOW WHAT\n");
+ //exit(0);
+
+ if (e == NULL) { // s must be a free variable
+ //fprintf(stderr, "'%s' must be free variable\n\n", s.c_str());
+ //fprintf(stderr, "SO WE WILL CREATE A MACRO ???\n");
+
+ Free_Var_Decl *t = NULL;
+
+ // keep adding underscores until we have created a unique name based on the original
+ do {
+ s += "_";
+ t = NULL;
+ for (unsigned i = 0; i < freevars.size(); i++) {
+ std::string ss = freevars[i]->base_name();
+
+ if (s == ss) {
+ t = freevars[i];
+ break;
+ }
+ }
+ } while (t != NULL);
+
+ if (!need_new_fsymbol)
+ t = new Free_Var_Decl(s, ref->n_dim());
+ else
+ t = new Free_Var_Decl(s, max_dim);
+ freevars.insert(freevars.end(), t); // add index_____ to freevars
+
+
+ std::vector< std::string > Vargs; // vector of args
+ std::string args;
+ std::vector<omega::CG_outputRepr *> reprs;
+ std::vector<omega::CG_outputRepr *> reprs2;
+ for (std::set<std::string>::iterator it = vars.begin();
+ it != vars.end(); it++) {
+ if (it == vars.begin())
+ args += "(";
+ else
+ args += ",";
+ args += *it;
+ //fprintf(stderr, "an argument to the macro: %s\n", it->c_str());
+ Vargs.push_back( (*it) );
+ reprs.push_back(ir->builder()->CreateIdent(*it));
+ reprs2.push_back(ir->builder()->CreateIdent(*it));
+ }
+ args += ")";
+
+ //fprintf(stderr, "args '%s'\n", args.c_str());
+ //fprintf(stderr, "Vargs ");
+ //for (int i=0; i<Vargs.size(); i++) fprintf(stderr, "%s ",Vargs[i].c_str());
+ //fprintf(stderr, "\n");
+
+ //fprintf(stderr, "omegatools.cc ir->CreateDefineMacro( s (%s), args(%s), repr)\n", s.c_str(), args.c_str());
+
+ // TODO repr, the rhs of the macro, needs to NOT refer to an actual variable ???
+
+
+ ir->CreateDefineMacro(s, Vargs, repr);
+
+
+
+ // index_(i) uses i outputrepr
+ //fprintf(stderr,"omegatools.cc making uninterpreted symbol %s\n",s.c_str());
+ uninterpreted_symbols.insert( // adding to uninterpreted_symbols
+ std::pair<std::string, std::vector<omega::CG_outputRepr *> >(
+ s, reprs));
+ uninterpreted_symbols_stringrepr.insert( // adding to uninterpreted_symbols_stringrepr
+ std::pair<std::string, std::vector<omega::CG_outputRepr *> >(s, reprs2));
+
+
+ e = r.get_local(t, Input_Tuple);
+
+ if (rel == IR_COND_GE || rel == IR_COND_GT) {
+ GEQ_Handle h = f_root->add_GEQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+ if (rel == IR_COND_GT)
+ h.update_const(-1);
+ } else if (rel == IR_COND_LE || rel == IR_COND_LT) {
+ GEQ_Handle h = f_root->add_GEQ();
+ h.update_coef(lhs, -1);
+ h.update_coef(e, 1);
+ if (rel == IR_COND_LT)
+ h.update_const(-1);
+ } else if (rel == IR_COND_EQ) {
+ EQ_Handle h = f_root->add_EQ();
+ h.update_coef(lhs, 1);
+ h.update_coef(e, -1);
+ } else
+ throw std::invalid_argument("unsupported condition type");
+ }
+ // delete v[0];
+ delete ref;
+ if (destroy) delete repr;
+
+ //fprintf(stderr, "FINALLY DONE with IR_OP_ARRAY_VARIABLE\n\n");
+ break;
}
- case IR_OP_NULL:
+
+
+ case IR_OP_NULL:
+ fprintf(stderr, "IR_OP_NULL\n");
break;
+
+
default:
throw ir_exp_error("unsupported operand type");
}
}
+
+
+
+//-----------------------------------------------------------------------------
+// Build dependence relation for two array references.
+// -----------------------------------------------------------------------------
Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
const IR_ArrayRef *ref_src, const Relation &IS_w,
- const IR_ArrayRef *ref_dst, const Relation &IS_r) {
+ const IR_ArrayRef *ref_dst, const Relation &IS_r,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_stringrepr) {
+
+ //fprintf(stderr, "arrays2relation()\n");
+ //fprintf(stderr, "%d freevars\n", freevars.size());
+ //for (int i=0; i<freevars.size(); i++) fprintf(stderr, "freevar %d %s\n", i, (const char *)(freevars[i]->base_name()));
+
+
Relation &IS1 = const_cast<Relation &>(IS_w);
Relation &IS2 = const_cast<Relation &>(IS_r);
+ //Relation *helper;
+ //helper = new Relation(IS1); fprintf(stderr, "IS1 "); helper->print(); fflush(stdout);
+ //helper = new Relation(IS2); fprintf(stderr, "IS2 "); helper->print(); fflush(stdout);
+
Relation r(IS1.n_set(), IS2.n_set());
+ //helper = new Relation(r); fprintf(stderr, "r "); helper->print(); fflush(stdout);
for (int i = 1; i <= IS1.n_set(); i++)
r.name_input_var(i, IS1.set_var(i)->name());
@@ -513,9 +902,25 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
for (int i = 1; i <= IS2.n_set(); i++)
r.name_output_var(i, IS2.set_var(i)->name()+"'");
+ //fprintf(stderr, "omegatools.cc sym_src\n");
IR_Symbol *sym_src = ref_src->symbol();
IR_Symbol *sym_dst = ref_dst->symbol();
+ //fprintf(stderr, "omegatools.cc going to do IR_Symbol operator==\n");
+ //fprintf(stderr, "omegatools.cc comparing symbol 0x%x to symbol 0x%x\n", sym_src, sym_dst);
+
+ //if (!(*sym_src == *sym_dst)) fprintf(stderr, "!(*sym_src == *sym_dst)\n");
+
+ //fprintf(stderr, "calling !=\n");
+ //if (*sym_src != *sym_dst) fprintf(stderr, "omegatools.cc (*sym_src != *sym_dst) TRUE\n");
+ //else fprintf(stderr, "omegatools.cc (*sym_src != *sym_dst) FALSE\n");
+
+ //fprintf(stderr, "calling ==\n");
+ //if ((*sym_src == *sym_dst)) fprintf(stderr, "(*sym_src == *sym_dst)) TRUE \n");
+ //else fprintf(stderr, "(*sym_src == *sym_dst) FALSE \n");
+
if (*sym_src != *sym_dst) {
+ //if (!(*sym_src == *sym_dst)) {
+ //fprintf(stderr, "False Relation\n");
r.add_or(); // False Relation
delete sym_src;
delete sym_dst;
@@ -526,9 +931,13 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
delete sym_dst;
}
+ //fprintf(stderr, "f_root\n");
F_And *f_root = r.add_and();
+ //fprintf(stderr, "omegatools.cc ref_src->n_dim() %d\n", ref_src->n_dim());
for (int i = 0; i < ref_src->n_dim(); i++) {
+ //fprintf(stderr, "arrays2 i %d\n", i);
+
F_Exists *f_exists = f_root->add_exists();
Variable_ID e1 = f_exists->declare(tmp_e());
Variable_ID e2 = f_exists->declare(tmp_e());
@@ -538,20 +947,29 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
CG_outputRepr *repr_dst = ref_dst->index(i);
bool has_complex_formula = false;
- try {
- exp2formula(ir, r, f_and, freevars, repr_src, e1, 'w', IR_COND_EQ, false);
- exp2formula(ir, r, f_and, freevars, repr_dst, e2, 'r', IR_COND_EQ, false);
- }
- catch (const ir_exp_error &e) {
+
+ if (ir->QueryExpOperation(repr_src) == IR_OP_ARRAY_VARIABLE
+ || ir->QueryExpOperation(repr_dst) == IR_OP_ARRAY_VARIABLE)
has_complex_formula = true;
- }
if (!has_complex_formula) {
- EQ_Handle h = f_and->add_EQ();
- h.update_coef(e1, 1);
- h.update_coef(e2, -1);
+
+ try {
+ exp2formula(ir, r, f_and, freevars, repr_src, e1, 'w', IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, repr_dst, e2, 'r', IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ }
+ catch (const ir_exp_error &e) {
+ has_complex_formula = true;
+ }
+
+ if (!has_complex_formula) {
+ EQ_Handle h = f_and->add_EQ();
+ h.update_coef(e1, 1);
+ h.update_coef(e2, -1);
+ }
}
-
repr_src->clear();
repr_dst->clear();
delete repr_src;
@@ -566,32 +984,61 @@ Relation arrays2relation(IR_Code *ir, std::vector<Free_Var_Decl*> &freevars,
for (int i = 1; i <= IS2.n_set(); i++)
r.name_output_var(i, IS2.set_var(i)->name()+"'");
+ //helper = new Relation(r); fprintf(stderr, "r "); helper->print(); fflush(stdout);
+ //fprintf(stderr, "leaving arrays2relation\n");
return r;
}
-std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relation2dependences (const IR_ArrayRef *ref_src, const IR_ArrayRef *ref_dst, const Relation &r) {
+
+//-----------------------------------------------------------------------------
+// Convert array dependence relation into set of dependence vectors, assuming
+// ref_w is lexicographically before ref_r in the source code.
+// -----------------------------------------------------------------------------
+std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relation2dependences (
+ const IR_ArrayRef *ref_src,
+ const IR_ArrayRef *ref_dst,
+ const Relation &r) {
+ //fprintf(stderr, "relation2dependences()\n");
assert(r.n_inp() == r.n_out());
std::vector<DependenceVector> dependences1, dependences2;
+ //std::vector<DependenceVector*> dep1, dep2;
std::stack<DependenceLevel> working;
working.push(DependenceLevel(r, r.n_inp()));
while (!working.empty()) {
+ //fprintf(stderr, "!empty size %d\n", working.size());
+
DependenceLevel dep = working.top();
working.pop();
+ //if (!dep.r.is_satisfiable()) fprintf(stderr, "NOT dep.r.is_satisfiable()\n");
+ //else fprintf(stderr, " dep.r.is_satisfiable()\n");
+
// No dependence exists, move on.
- if (!dep.r.is_satisfiable())
+ if (!dep.r.is_satisfiable()) {
+ //fprintf(stderr, "No dependence exists, move on.\n");
continue;
+ }
+ //fprintf(stderr, "satisfiable\n");
+ //fprintf(stderr, "dep.level %d r.n_inp() %d\n", dep.level, r.n_inp());
if (dep.level == r.n_inp()) {
+ //fprintf(stderr, "dep.level == r.n_inp()\n");
DependenceVector dv;
+ //fprintf(stderr, "\ndv created in if ***\n");
+ //DependenceVector *dv2 = new DependenceVector;
+
+ //fprintf(stderr, "for loop independent dependence dep.dir %d\n", dep.dir);
// for loop independent dependence, use lexical order to
// determine the correct source and destination
if (dep.dir == 0) {
- if (*ref_src == *ref_dst)
+ //fprintf(stderr, "dep.dir == 0\n");
+ if (*ref_src == *ref_dst) { // c == c
+ //fprintf(stderr, "trivial\n");
continue; // trivial self zero-dependence
+ }
if (ref_src->is_write()) {
if (ref_dst->is_write())
@@ -608,6 +1055,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
}
else if (dep.dir == 1) {
+ //fprintf(stderr, "dep.dir == 1\n");
if (ref_src->is_write()) {
if (ref_dst->is_write())
dv.type = DEP_W2W;
@@ -622,6 +1070,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
}
}
else { // dep.dir == -1
+ //fprintf(stderr, "dep.dir == -1\n");
if (ref_dst->is_write()) {
if (ref_src->is_write())
dv.type = DEP_W2W;
@@ -638,27 +1087,74 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
dv.lbounds = dep.lbounds;
dv.ubounds = dep.ubounds;
+
+ //fprintf(stderr, "omegatools.cc calling ref_src->symbol();\n");
dv.sym = ref_src->symbol();
+ //fprintf(stderr, "dv.sym = %p\n", dv.sym);
+
+ //fprintf(stderr, "symbol %s ADDING A DEPENDENCE OF TYPE ", dv.sym->name().c_str());
+ //switch (dv.type) {
+ //case DEP_W2W: fprintf(stderr, "DEP_W2W to "); break;
+ //case DEP_W2R: fprintf(stderr, "DEP_W2R to "); break;
+ //case DEP_R2W: fprintf(stderr, "DEP_R2W to "); break;
+ //case DEP_R2R: fprintf(stderr, "DEP_R2R to "); break;
+ //default: fprintf(stderr, "DEP_UNKNOWN to "); break;
+ //}
+ //if (dep.dir == 0 || dep.dir == 1) fprintf(stderr, "dependences1\n");
+ //else fprintf(stderr, "dependences2\n");
- if (dep.dir == 0 || dep.dir == 1)
+ if (dep.dir == 0 || dep.dir == 1) {
+ //fprintf(stderr, "pushing dv\n");
dependences1.push_back(dv);
- else
+ //fprintf(stderr, "DONE pushing dv\n");
+
+ //fprintf(stderr, "now %d dependences1\n", dependences1.size() );
+ //for (int i=0; i<dependences1.size(); i++) {
+ // fprintf(stderr, "dependences1[%d]: ", i );
+ // //fprintf(stderr, "symbol %p ", dependences1[i].sym);
+ // fprintf(stderr, "symbol ");
+ // fprintf(stderr, "%s\n", dependences1[i].sym->name().c_str());
+ //}
+ //fprintf(stderr, "\n");
+ }
+ else {
+ //fprintf(stderr, "pushing dv\n");
dependences2.push_back(dv);
+ //fprintf(stderr, "DONE pushing dv\n");
+
+ //fprintf(stderr, "now %d dependences2\n", dependences2.size() );
+ //for (int i=0; i<dependences2.size(); i++) {
+ // fprintf(stderr, "dependences2[%d]: ", i);
+ // //fprintf(stderr, "symbol %p ", dependences2[i].sym);
+ // fprintf(stderr, "symbol ");
+ // fprintf(stderr, "%s\n", dependences2[i].sym->name().c_str());
+ //}
+ //fprintf(stderr, "\n");
+ }
+
+ //fprintf(stderr, "dv goes out of scope ***\n");
}
else {
+ //fprintf(stderr, "now work on the next dimension level\n");
// now work on the next dimension level
int level = ++dep.level;
+ //fprintf(stderr, "level %d\n", level);
coef_t lbound, ubound;
Relation delta = Deltas(copy(dep.r));
+ //delta.print(); fflush(stdout);
delta.query_variable_bounds(delta.set_var(level), lbound, ubound);
+ //fprintf(stderr, "delta lb " coef_fmt " 0x%llx ub " coef_fmt " 0x%llx\n", lbound,lbound,ubound,ubound);
+
if (dep.dir == 0) {
+ //fprintf(stderr, "dep.dir == 0\n");
if (lbound > 0) {
dep.dir = 1;
dep.lbounds[level-1] = lbound;
dep.ubounds[level-1] = ubound;
+ //fprintf(stderr, "push 1\n");
working.push(dep);
}
else if (ubound < 0) {
@@ -666,6 +1162,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
dep.lbounds[level-1] = -ubound;
dep.ubounds[level-1] = -lbound;
+ //fprintf(stderr, "push 2\n");
working.push(dep);
}
else {
@@ -683,10 +1180,16 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
h.update_coef(dep2.r.input_var(level), 1);
h.update_coef(dep2.r.output_var(level), -1);
+ //fprintf(stderr, "push 3\n");
working.push(dep2);
}
- if (lbound < 0 && *ref_src != *ref_dst) {
+ //fprintf(stderr, "lbound %lld 0x%llx\n", lbound, lbound);
+ //if (lbound < 0LL) fprintf(stderr, "lbound < 0LL\n");
+ //if (*ref_src != *ref_dst) fprintf(stderr, "(*ref_src != *ref_dst)\n");
+ //else fprintf(stderr, "(*ref_src EQUAL *ref_dst)\n");
+
+ if (lbound < 0LL && (*ref_src != *ref_dst)) { // c == c
DependenceLevel dep2 = dep;
F_And *f_root = dep2.r.and_with_and();
@@ -702,12 +1205,14 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
lbound, ubound);
dep2.dir = -1;
- dep2.lbounds[level-1] = max(-ubound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness
+ dep2.lbounds[level-1] = std::max(-ubound,static_cast<coef_t>(1)); // use max() to avoid Omega retardedness
dep2.ubounds[level-1] = -lbound;
+ //fprintf(stderr, "push 4\n");
working.push(dep2);
}
+ //fprintf(stderr, "ubound %d\n", ubound);
if (ubound > 0) {
DependenceLevel dep2 = dep;
@@ -723,9 +1228,10 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
delta.query_variable_bounds(delta.set_var(level),
lbound, ubound);
dep2.dir = 1;
- dep2.lbounds[level-1] = max(lbound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness
+ dep2.lbounds[level-1] = std::max(lbound,static_cast<coef_t>(1)); // use max() to avoid Omega retardness
dep2.ubounds[level-1] = ubound;
+ //fprintf(stderr, "push 5\n");
working.push(dep2);
}
}
@@ -733,6 +1239,7 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
// now deal with dependence vector with known direction
// determined at previous levels
else {
+ //fprintf(stderr, "else messy\n");
// For messy bounds, further test to see if the dependence distance
// can be reduced to positive/negative. This is an omega hack.
if (lbound == negInfinity && ubound == posInfinity) {
@@ -788,59 +1295,167 @@ std::pair<std::vector<DependenceVector>, std::vector<DependenceVector> > relatio
dep.ubounds[level-1] = ubound;
}
+ //fprintf(stderr, "push 6\n");
working.push(dep);
}
}
+ //fprintf(stderr, "at bottom, size %d\n", working.size());
+
}
+ //fprintf(stderr, "leaving relation2dependences, %d and %d dependences\n", dependences1.size(), dependences2.size());
+
+
+ //for (int i=0; i<dependences1.size(); i++) {
+ //fprintf(stderr, "dependences1[%d]: ", i);
+ //fprintf(stderr, "symbol %s\n", dependences1[i].sym->name().c_str());
+
+ //fprintf(stderr, "symbol %s HAS A left DEPENDENCE OF TYPE ", dependences1[i].sym->name().c_str());
+ //switch (dependences1[i].type) {
+ //case DEP_W2W: fprintf(stderr, "DEP_W2W\n"); break;
+ //case DEP_W2R: fprintf(stderr, "DEP_W2R\n"); break;
+ //case DEP_R2W: fprintf(stderr, "DEP_R2W\n"); break;
+ //case DEP_R2R: fprintf(stderr, "DEP_R2R\n"); break;
+ //default: fprintf(stderr, "DEP_UNKNOWN\n"); break;
+ //}
+ //}
+
+
+ //for (int i=0; i<dependences2.size(); i++) {
+
+ //fprintf(stderr, "symbol %s HAS A right DEPENDENCE OF TYPE ", dependences2[i].sym->name().c_str());
+ //switch (dependences2[i].type) {
+ //case DEP_W2W: fprintf(stderr, "DEP_W2W\n"); break;
+ //case DEP_W2R: fprintf(stderr, "DEP_W2R\n"); break;
+ //case DEP_R2W: fprintf(stderr, "DEP_R2W\n"); break;
+ //case DEP_R2R: fprintf(stderr, "DEP_R2R\n"); break;
+ //default: fprintf(stderr, "DEP_UNKNOWN\n"); break;
+ //}
+ //}
+
+
+
return std::make_pair(dependences1, dependences2);
}
+
+//-----------------------------------------------------------------------------
+// Convert a boolean expression to omega relation. "destroy" means shallow
+// deallocation of "repr", not freeing the actual code inside.
+//-----------------------------------------------------------------------------
void exp2constraint(IR_Code *ir, Relation &r, F_And *f_root,
std::vector<Free_Var_Decl *> &freevars,
- CG_outputRepr *repr, bool destroy) {
+ CG_outputRepr *repr,
+ bool destroy,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols,
+ std::map<std::string, std::vector<omega::CG_outputRepr *> > &uninterpreted_symbols_stringrepr)
+{
IR_CONDITION_TYPE cond = ir->QueryBooleanExpOperation(repr);
switch (cond) {
case IR_COND_LT:
case IR_COND_LE:
case IR_COND_EQ:
case IR_COND_GT:
- case IR_COND_GE: {
- F_Exists *f_exist = f_root->add_exists();
- Variable_ID e = f_exist->declare();
- F_And *f_and = f_exist->add_and();
- std::vector<omega::CG_outputRepr *> op = ir->QueryExpOperand(repr);
- exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true);
- exp2formula(ir, r, f_and, freevars, op[1], e, 's', cond, true);
- if (destroy)
- delete repr;
- break;
- }
- case IR_COND_NE: {
- F_Exists *f_exist = f_root->add_exists();
- Variable_ID e = f_exist->declare();
- F_Or *f_or = f_exist->add_or();
- F_And *f_and = f_or->add_and();
- std::vector<omega::CG_outputRepr *> op = ir->QueryExpOperand(repr);
- exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, false);
- exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_GT, false);
-
- f_and = f_or->add_and();
- exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true);
- exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_LT, true);
-
- if (destroy)
- delete repr;
- break;
- }
+ case IR_COND_GE:
+ {
+ F_Exists *f_exist = f_root->add_exists();
+ Variable_ID e = f_exist->declare();
+ F_And *f_and = f_exist->add_and();
+ std::vector<omega::CG_outputRepr *> op = ir->QueryExpOperand(repr);
+ exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, op[1], e, 's', cond, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (destroy)
+ delete repr;
+ break;
+ }
+ case IR_COND_NE:
+ {
+ F_Exists *f_exist = f_root->add_exists();
+ Variable_ID e = f_exist->declare();
+ F_Or *f_or = f_exist->add_or();
+ F_And *f_and = f_or->add_and();
+ std::vector<omega::CG_outputRepr *> op = ir->QueryExpOperand(repr);
+ exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_GT, false,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ f_and = f_or->add_and();
+ exp2formula(ir, r, f_and, freevars, op[0], e, 's', IR_COND_EQ, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+ exp2formula(ir, r, f_and, freevars, op[1], e, 's', IR_COND_LT, true,
+ uninterpreted_symbols, uninterpreted_symbols_stringrepr);
+
+ if (destroy)
+ delete repr;
+ break;
+ }
default:
throw ir_exp_error("unrecognized conditional expression");
}
}
-bool is_single_loop_iteration(const Relation &r, int level, const Relation &known) {
+
+
+
+
+//-----------------------------------------------------------------------------
+// Generate iteration space constraints
+//-----------------------------------------------------------------------------
+
+// void add_loop_stride_constraints(Relation &r, F_And *f_root,
+// std::vector<Free_Var_Decl*> &freevars,
+// tree_for *tnf, char side) {
+
+// std::string name(tnf->index()->name());
+// int dim = 0;
+// for (;dim < r.n_set(); dim++)
+// if (r.set_var(dim+1)->name() == name)
+// break;
+
+// Relation bound = get_loop_bound(r, dim);
+
+// operand op = tnf->step_op();
+// if (!op.is_null()) {
+// if (op.is_immed()) {
+// immed im = op.immediate();
+// if (im.is_integer()) {
+// int c = im.integer();
+
+// if (c != 1 && c != -1)
+// add_loop_stride(r, bound, dim, c);
+// }
+// else
+// assert(0); // messy stride
+// }
+// else
+// assert(0); // messy stride
+// }
+// }
+
+
+
+
+//-----------------------------------------------------------------------------
+// Determine whether the loop (starting from 0) in the iteration space
+// has only one iteration.
+//-----------------------------------------------------------------------------
+bool is_single_loop_iteration(const Relation &r,
+ int level,
+ const Relation &known) {
int n = r.n_set();
- Relation r1 = Intersection(copy(r), Extend_Set(copy(known), n-known.n_set()));
+ Relation r1;
+ if(n > known.n_set()) {
+ r1 = Intersection(copy(r), Extend_Set(copy(known), n - known.n_set()));
+ }
+ else{
+ r1 = Intersection(copy(known), Extend_Set(copy(r), known.n_set() - n));
+ n = known.n_set();
+ }
+
Relation mapping(n, n);
F_And *f_root = mapping.add_and();
@@ -869,6 +1484,8 @@ bool is_single_loop_iteration(const Relation &r, int level, const Relation &know
}
+
+
bool is_single_iteration(const Relation &r, int dim) {
assert(r.is_set());
const int n = r.n_set();
@@ -878,6 +1495,11 @@ bool is_single_iteration(const Relation &r, int dim) {
Relation bound = get_loop_bound(r, dim);
+ // if (!bound.has_single_conjunct())
+ // return false;
+
+ // Conjunct *c = bound.query_DNF()->single_conjunct();
+
for (DNF_Iterator di(bound.query_DNF()); di; di++) {
bool is_single = false;
for (EQ_Iterator ei((*di)->EQs()); ei; ei++)
@@ -891,8 +1513,78 @@ bool is_single_iteration(const Relation &r, int dim) {
}
return true;
+
+
+
+
+ // Relation r = copy(r_);
+ // const int n = r.n_set();
+
+ // if (dim >= n)
+ // return true;
+
+ // Relation bound = get_loop_bound(r, dim);
+ // bound = Approximate(bound);
+ // Conjunct *c = bound.query_DNF()->single_conjunct();
+
+ // return c->n_GEQs() == 0;
+
+
+
+
+
+ // Relation r = copy(r_);
+ // r.simplify();
+ // const int n = r.n_set();
+
+ // if (dim >= n)
+ // return true;
+
+ // for (DNF_Iterator i(r.query_DNF()); i; i++) {
+ // std::vector<bool> is_single(n);
+ // for (int j = 0; j < dim; j++)
+ // is_single[j] = true;
+ // for (int j = dim; j < n; j++)
+ // is_single[j] = false;
+
+ // bool found_new_single = true;
+ // while (found_new_single) {
+ // found_new_single = false;
+
+ // for (EQ_Iterator j = (*i)->EQs(); j; j++) {
+ // int saved_pos = -1;
+ // for (Constr_Vars_Iter k(*j); k; k++)
+ // if ((*k).var->kind() == Set_Var || (*k).var->kind() == Input_Var) {
+ // int pos = (*k).var->get_position() - 1;
+ // if (!is_single[pos])
+ // if (saved_pos == -1)
+ // saved_pos = pos;
+ // else {
+ // saved_pos = -1;
+ // break;
+ // }
+ // }
+
+ // if (saved_pos != -1) {
+ // is_single[saved_pos] = true;
+ // found_new_single = true;
+ // }
+ // }
+
+ // if (is_single[dim])
+ // break;
+ // }
+
+ // if (!is_single[dim])
+ // return false;
+ // }
+
+ // return true;
}
+//-----------------------------------------------------------------------------
+// Set/get the value of a variable which is know to be constant.
+//-----------------------------------------------------------------------------
void assign_const(Relation &r, int dim, int val) {
const int n = r.n_out();
@@ -917,10 +1609,14 @@ void assign_const(Relation &r, int dim, int val) {
int get_const(const Relation &r, int dim, Var_Kind type) {
+ // Relation rr = copy(r);
Relation &rr = const_cast<Relation &>(r);
Variable_ID v;
switch (type) {
+ // case Set_Var:
+ // v = rr.set_var(dim+1);
+ // break;
case Input_Var:
v = rr.input_var(dim+1);
break;
@@ -939,10 +1635,19 @@ int get_const(const Relation &r, int dim, Var_Kind type) {
throw std::runtime_error("cannot get variable's constant value");
}
+
+
+
+
+
+//---------------------------------------------------------------------------
+// Get the bound for a specific loop.
+//---------------------------------------------------------------------------
Relation get_loop_bound(const Relation &r, int dim) {
assert(r.is_set());
const int n = r.n_set();
+ // Relation r1 = project_onto_levels(copy(r), dim+1, true);
Relation mapping(n,n);
F_And *f_root = mapping.add_and();
for (int i = 1; i <= dim+1; i++) {
@@ -959,9 +1664,20 @@ Relation get_loop_bound(const Relation &r, int dim) {
return Gist(r1, r2, 1);
}
+
+
Relation get_loop_bound(const Relation &r, int level, const Relation &known) {
- int n = r.n_set();
- Relation r1 = Intersection(copy(r), Extend_Set(copy(known), n-known.n_set()));
+ int n1 = r.n_set();
+ int n = n1;
+ Relation r1;
+ if(n > known.n_set())
+ r1 = Intersection(copy(r),
+ Extend_Set(copy(known), n - known.n_set()));
+ else{
+ r1 = Intersection(copy(known),
+ Extend_Set(copy(r), known.n_set() - n));
+ n = known.n_set();
+ }
Relation mapping(n, n);
F_And *f_root = mapping.add_and();
@@ -974,7 +1690,7 @@ Relation get_loop_bound(const Relation &r, int level, const Relation &known) {
Relation r2 = Project(copy(r1), level, Set_Var);
r1 = Gist(r1, r2, 1);
- for (int i = 1; i <= n; i++)
+ for (int i = 1; i <= n1; i++)
r1.name_set_var(i, const_cast<Relation &>(r).set_var(i)->name());
r1.setup_names();
@@ -1017,6 +1733,12 @@ Relation get_min_loop_bound(const std::vector<Relation> &r, int dim) {
return res;
}
+//-----------------------------------------------------------------------------
+// Add strident to a loop.
+// Issues:
+// - Don't work with relations with multiple disjuncts.
+// - Omega's dealing with max lower bound is awkward.
+//-----------------------------------------------------------------------------
void add_loop_stride(Relation &r, const Relation &bound_, int dim, int stride) {
F_And *f_root = r.and_with_and();
Relation &bound = const_cast<Relation &>(bound_);
@@ -1042,30 +1764,32 @@ void add_loop_stride(Relation &r, const Relation &bound_, int dim, int stride) {
for (Constr_Vars_Iter ci(*gi); ci; ci++) {
switch ((*ci).var->kind()) {
// case Set_Var:
- case Input_Var: {
- int pos = (*ci).var->get_position();
- if (pos == dim + 1) {
- h1.update_coef(e1, (*ci).coef);
- h2.update_coef(e1, (*ci).coef);
- }
- else {
- if (!r.is_set()) {
- h1.update_coef(r.output_var(pos), (*ci).coef);
- h2.update_coef(r.output_var(pos), (*ci).coef);
+ case Input_Var:
+ {
+ int pos = (*ci).var->get_position();
+ if (pos == dim + 1) {
+ h1.update_coef(e1, (*ci).coef);
+ h2.update_coef(e1, (*ci).coef);
}
else {
- h1.update_coef(r.set_var(pos), (*ci).coef);
- h2.update_coef(r.set_var(pos), (*ci).coef);
- }
+ if (!r.is_set()) {
+ h1.update_coef(r.output_var(pos), (*ci).coef);
+ h2.update_coef(r.output_var(pos), (*ci).coef);
+ }
+ else {
+ h1.update_coef(r.set_var(pos), (*ci).coef);
+ h2.update_coef(r.set_var(pos), (*ci).coef);
+ }
+ }
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = (*ci).var->get_global_var();
+ h1.update_coef(r.get_local(g, (*ci).var->function_of()), (*ci).coef);
+ h2.update_coef(r.get_local(g, (*ci).var->function_of()), (*ci).coef);
+ break;
}
- break;
- }
- case Global_Var: {
- Global_Var_ID g = (*ci).var->get_global_var();
- h1.update_coef(r.get_local(g, (*ci).var->function_of()), (*ci).coef);
- h2.update_coef(r.get_local(g, (*ci).var->function_of()), (*ci).coef);
- break;
- }
default:
break;
}
@@ -1078,8 +1802,18 @@ void add_loop_stride(Relation &r, const Relation &bound_, int dim, int stride) {
}
-bool is_inner_loop_depend_on_level(const Relation &r, int level, const Relation &known) {
- Relation r1 = Intersection(copy(r), Extend_Set(copy(known), r.n_set()-known.n_set()));
+bool is_inner_loop_depend_on_level(const Relation &r,
+ int level,
+ const Relation &known) {
+
+ Relation r1;
+ if(r.n_set() > known.n_set())
+ r1 = Intersection(copy(r),
+ Extend_Set(copy(known), r.n_set() - known.n_set()));
+ else
+ r1 = Intersection(copy(known),
+ Extend_Set(copy(r), known.n_set() - r.n_set()));
+
Relation r2 = copy(r1);
for (int i = level+1; i <= r2.n_set(); i++)
r2 = Project(r2, r2.set_var(i));
@@ -1100,6 +1834,15 @@ bool is_inner_loop_depend_on_level(const Relation &r, int level, const Relation
return false;
}
+
+//-----------------------------------------------------------------------------
+// Suppose loop dim is i. Replace i with i+adjustment in loop bounds.
+// e.g. do i = 1, n
+// do j = i, n
+// after call with dim = 0 and adjustment = 1:
+// do i = 1, n
+// do j = i+1, n
+// -----------------------------------------------------------------------------
Relation adjust_loop_bound(const Relation &r, int level, int adjustment) {
if (adjustment == 0)
return copy(r);
@@ -1136,6 +1879,236 @@ Relation adjust_loop_bound(const Relation &r, int level, int adjustment) {
return r1;
}
+
+// commented out on 07/14/2010
+// void adjust_loop_bound(Relation &r, int dim, int adjustment, std::vector<Free_Var_Decl *> globals) {
+// assert(r.is_set());
+
+// if (adjustment == 0)
+// return;
+
+// const int n = r.n_set();
+// Tuple<std::string> name(n);
+// for (int i = 1; i <= n; i++)
+// name[i] = r.set_var(i)->name();
+
+// Relation r1 = project_onto_levels(copy(r), dim+1, true);
+// Relation r2 = Gist(copy(r), copy(r1));
+
+// // remove old bogus global variable conditions since we are going to
+// // update the value.
+// if (globals.size() > 0)
+// r1 = Gist(r1, project_onto_levels(copy(r), 0, true));
+
+// Relation r4 = Relation::True(n);
+
+// for (DNF_Iterator di(r2.query_DNF()); di; di++) {
+// for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) {
+// EQ_Handle h = r4.and_with_EQ(*ei);
+
+// Variable_ID v = r2.set_var(dim+1);
+// coef_t c = (*ei).get_coef(v);
+// if (c != 0)
+// h.update_const(c*adjustment);
+
+// for (int i = 0; i < globals.size(); i++) {
+// Variable_ID v = r2.get_local(globals[i]);
+// coef_t c = (*ei).get_coef(v);
+// if (c != 0)
+// h.update_const(c*adjustment);
+// }
+// }
+
+// for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) {
+// GEQ_Handle h = r4.and_with_GEQ(*gi);
+
+// Variable_ID v = r2.set_var(dim+1);
+// coef_t c = (*gi).get_coef(v);
+// if (c != 0)
+// h.update_const(c*adjustment);
+
+// for (int i = 0; i < globals.size(); i++) {
+// Variable_ID v = r2.get_local(globals[i]);
+// coef_t c = (*gi).get_coef(v);
+// if (c != 0)
+// h.update_const(c*adjustment);
+// }
+// }
+// }
+// r = Intersection(r1, r4);
+// // }
+// // else
+// // r = Intersection(r1, r2);
+
+// for (int i = 1; i <= n; i++)
+// r.name_set_var(i, name[i]);
+// r.setup_names();
+// }
+
+
+// void adjust_loop_bound(Relation &r, int dim, int adjustment) {
+// assert(r.is_set());
+// const int n = r.n_set();
+// Tuple<String> name(n);
+// for (int i = 1; i <= n; i++)
+// name[i] = r.set_var(i)->name();
+
+// Relation r1 = project_onto_levels(copy(r), dim+1, true);
+// Relation r2 = Gist(r, copy(r1));
+
+// Relation r3(n, n);
+// F_And *f_root = r3.add_and();
+// for (int i = 0; i < n; i++) {
+// EQ_Handle h = f_root->add_EQ();
+// h.update_coef(r3.output_var(i+1), 1);
+// h.update_coef(r3.input_var(i+1), -1);
+// if (i == dim)
+// h.update_const(adjustment);
+// }
+
+// r2 = Range(Restrict_Domain(r3, r2));
+// r = Intersection(r1, r2);
+
+// for (int i = 1; i <= n; i++)
+// r.name_set_var(i, name[i]);
+// r.setup_names();
+// }
+
+// void adjust_loop_bound(Relation &r, int dim, Free_Var_Decl *global_var, int adjustment) {
+// assert(r.is_set());
+// const int n = r.n_set();
+// Tuple<String> name(n);
+// for (int i = 1; i <= n; i++)
+// name[i] = r.set_var(i)->name();
+
+// Relation r1 = project_onto_levels(copy(r), dim+1, true);
+// Relation r2 = Gist(r, copy(r1));
+
+// Relation r3(n);
+// Variable_ID v = r2.get_local(global_var);
+
+// for (DNF_Iterator di(r2.query_DNF()); di; di++) {
+// for (EQ_Iterator ei = (*di)->EQs(); ei; ei++) {
+// coef_t c = (*ei).get_coef(v);
+// EQ_Handle h = r3.and_with_EQ(*ei);
+// if (c != 0)
+// h.update_const(c*adjustment);
+// }
+// for (GEQ_Iterator gi = (*di)->GEQs(); gi; gi++) {
+// coef_t c = (*gi).get_coef(v);
+// GEQ_Handle h = r3.and_with_GEQ(*gi);
+// if (c != 0)
+// h.update_const(c*adjustment);
+// }
+// }
+
+// r = Intersection(r1, r3);
+// for (int i = 1; i <= n; i++)
+// r.name_set_var(i, name[i]);
+// r.setup_names();
+// }
+
+
+
+//------------------------------------------------------------------------------
+// If the dimension has value posInfinity, the statement should be privatized
+// at this dimension.
+//------------------------------------------------------------------------------
+// boolean is_private_statement(const Relation &r, int dim) {
+// int n;
+// if (r.is_set())
+// n = r.n_set();
+// else
+// n = r.n_out();
+
+// if (dim >= n)
+// return false;
+
+// try {
+// coef_t c;
+// if (r.is_set())
+// c = get_const(r, dim, Set_Var);
+// else
+// c = get_const(r, dim, Output_Var);
+// if (c == posInfinity)
+// return true;
+// else
+// return false;
+// }
+// catch (loop_error e){
+// }
+
+// return false;
+// }
+
+
+
+// // ----------------------------------------------------------------------------
+// // Calculate v mod dividend based on equations inside relation r.
+// // Return posInfinity if it is not a constant.
+// // ----------------------------------------------------------------------------
+// static coef_t mod_(const Relation &r_, Variable_ID v, int dividend, std::set<Variable_ID> &working_on) {
+// assert(dividend > 0);
+// if (v->kind() == Forall_Var || v->kind() == Exists_Var || v->kind() == Wildcard_Var)
+// return posInfinity;
+
+// working_on.insert(v);
+
+// Relation &r = const_cast<Relation &>(r_);
+// Conjunct *c = r.query_DNF()->single_conjunct();
+
+// for (EQ_Iterator ei(c->EQs()); ei; ei++) {
+// int coef = mod((*ei).get_coef(v), dividend);
+// if (coef != 1 && coef != dividend - 1 )
+// continue;
+
+// coef_t result = 0;
+// for (Constr_Vars_Iter cvi(*ei); cvi; cvi++)
+// if ((*cvi).var != v) {
+// int p = mod((*cvi).coef, dividend);
+
+// if (p == 0)
+// continue;
+
+// if (working_on.find((*cvi).var) != working_on.end()) {
+// result = posInfinity;
+// break;
+// }
+
+// coef_t q = mod_(r, (*cvi).var, dividend, working_on);
+// if (q == posInfinity) {
+// result = posInfinity;
+// break;
+// }
+// result += p * q;
+// }
+
+// if (result != posInfinity) {
+// result += (*ei).get_const();
+// if (coef == 1)
+// result = -result;
+// working_on.erase(v);
+
+// return mod(result, dividend);
+// }
+// }
+
+// working_on.erase(v);
+// return posInfinity;
+// }
+
+
+// coef_t mod(const Relation &r, Variable_ID v, int dividend) {
+// std::set<Variable_ID> working_on = std::set<Variable_ID>();
+
+// return mod_(r, v, dividend, working_on);
+// }
+
+
+
+//-----------------------------------------------------------------------------
+// Generate mapping relation for permuation.
+//-----------------------------------------------------------------------------
Relation permute_relation(const std::vector<int> &pi) {
const int n = pi.size();
@@ -1151,6 +2124,11 @@ Relation permute_relation(const std::vector<int> &pi) {
return r;
}
+
+
+//---------------------------------------------------------------------------
+// Find the position index variable in a Relation by name.
+//---------------------------------------------------------------------------
Variable_ID find_index(Relation &r, const std::string &s, char side) {
// Omega quirks: assure the names are propagated inside the relation
r.setup_names();
@@ -1183,3 +2161,1104 @@ Variable_ID find_index(Relation &r, const std::string &s, char side) {
return NULL;
}
+// EQ_Handle get_eq(const Relation &r, int dim, Var_Kind type) {
+// Variable_ID v;
+// switch (type) {
+// case Set_Var:
+// v = r.set_var(dim+1);
+// break;
+// case Input_Var:
+// v = r.input_var(dim+1);
+// break;
+// case Output_Var:
+// v = r.output_var(dim+1);
+// break;
+// default:
+// return NULL;
+// }
+// for (DNF_iterator di(r.query_DNF()); di; di++)
+// for (EQ_Iterator ei = (*di)->EQs(); ei; ei++)
+// if ((*ei).get_coef(v) != 0)
+// return (*ei);
+
+// return NULL;
+// }
+
+
+// std::Pair<Relation, Relation> split_loop(const Relation &r, const Relation &cond) {
+// Relation r1 = Intersection(copy(r), copy(cond));
+// Relation r2 = Intersection(copy(r), Complement(copy(cond)));
+
+// return std::Pair<Relation, Relation>(r1, r2);
+// }
+
+
+
+//----------------------------------------------------------------------------
+//check if loop is normalized to zero
+//----------------------------------------------------------------------------
+bool lowerBoundIsZero(const omega::Relation &bound, int dim) {
+ Relation &IS = const_cast<Relation &>(bound);
+ Variable_ID v = IS.input_var(dim);
+ bool found = false;
+ for (DNF_Iterator di(IS.query_DNF()); di; di++) {
+ bool is_single = false;
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++)
+ if ((*gi).get_coef(v) >= 0 && !(*gi).is_const(v)
+ && (*gi).get_const() != 0) {
+ return false;
+ }
+ else if ((*gi).get_coef(v) >= 0 && (*gi).is_const(v)
+ && (*gi).get_const() == 0)
+ found = true;
+ }
+
+ return found;
+}
+
+
+
+Relation replicate_IS_and_add_bound(const omega::Relation &R, int level,
+ omega::Relation &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+
+ for (int i = 1; i <= R.n_set(); i++) {
+ r.name_set_var(i + 1, const_cast<Relation &>(R).set_var(i)->name());
+ }
+
+ std::string new_var = bound.set_var(1)->name();
+
+ r.name_set_var(level, new_var);
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h = f_root->add_EQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ r.simplify();
+ r.setup_names();
+ return r;
+}
+
+
+
+
+// Replicates old_relation's bounds for set var at old_pos int o new_relation at new_pos, but position's bounds must involve constants
+// only supports GEQs
+//
+Relation replace_set_var_as_another_set_var(const omega::Relation &new_relation,
+ const omega::Relation &old_relation, int new_pos, int old_pos) {
+
+ Relation r = copy(new_relation);
+ r.copy_names(new_relation);
+ r.setup_names();
+
+ F_Exists *f_exists = r.and_with_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+
+ for (DNF_Iterator di(const_cast<Relation &>(old_relation).query_DNF()); di;
+ di++)
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if (((*gi).get_coef(
+ const_cast<Relation &>(old_relation).set_var(old_pos)) != 0)
+ && (*gi).is_const_except_for_global(
+ const_cast<Relation &>(old_relation).set_var(
+ old_pos))) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+
+ if (v->get_position() == old_pos)
+ h.update_coef(r.input_var(new_pos),
+ cvi.curr_coef());
+ else
+ throw omega_error(
+ "relation contains set vars other than that to be replicated!");
+ break;
+
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(
+ old_relation, v, r, f_exists, f_root,
+ exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ return r;
+
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Copy all relations from r and add new bound at position indicated by level.
+// -----------------------------------------------------------------------------
+
+Relation replicate_IS_and_add_at_pos(const omega::Relation &R, int level,
+ omega::Relation &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set() + 1);
+
+ for (int i = 1; i <= R.n_set(); i++) {
+ if (i < level)
+ r.name_set_var(i, const_cast<Relation &>(R).set_var(i)->name());
+ else
+ r.name_set_var(i + 1, const_cast<Relation &>(R).set_var(i)->name());
+
+ }
+
+ std::string new_var = bound.set_var(1)->name();
+
+ r.name_set_var(level, new_var);
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+
+ for (int i = 1; i <= R.n_set(); i++)
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if ((*gi).get_coef(const_cast<Relation &>(R).set_var(i)) != 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (i < level)
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+ h.update_coef(
+ r.input_var(v->get_position() + 1),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (int i = 1; i <= R.n_set(); i++)
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+ if ((*gi).get_coef(const_cast<Relation &>(R).set_var(i)) != 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (i < level)
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+ h1.update_coef(
+ r.input_var(v->get_position() + 1),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (cvi.curr_var()->get_position() < level)
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ else
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (DNF_Iterator di(bound.query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h = f_root->add_EQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (cvi.curr_var()->get_position() < level)
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ else
+ h.update_coef(r.input_var(level), cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ r.simplify();
+ r.setup_names();
+ return r;
+}
+
+
+
+
+omega::Relation replace_set_var_as_Global(const omega::Relation &R, int pos,
+ std::vector<omega::Relation> &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ int count = 1;
+ for (int i = 1; i <= R.n_set(); i++) {
+
+ if (i != pos) {
+ r.name_set_var(i, const_cast<Relation &>(R).set_var(i)->name());
+
+ }
+ else
+ r.name_set_var(i, "void");
+ }
+
+ Free_Var_Decl *repl = new Free_Var_Decl(
+ const_cast<Relation &>(R).set_var(pos)->name());
+
+ Variable_ID v3 = r.get_local(repl);
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (v->get_position() != pos)
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h1.update_coef(v3, cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+
+ for (int i = 0; i < bound.size(); i++)
+ for (DNF_Iterator di(bound[i].query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if ((*gi).get_coef(bound[i].set_var(pos)) == 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ //if (i < level)
+ if (v->get_position() != pos)
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h.update_coef(v3, cvi.curr_coef());
+ break;
+
+ //else
+ // h.update_coef(
+ // r.input_var(v->get_position() + 1),
+ // cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+ return r;
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Replace an input variable's constraints as an existential in order
+// to simplify other constraints in Relation
+// -----------------------------------------------------------------------------
+std::pair<Relation, bool> replace_set_var_as_existential(
+ const omega::Relation &R, int pos,
+ std::vector<omega::Relation> &bound) {
+
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+ for (int i = 1; i <= R.n_set(); i++)
+ r.name_set_var(i, const_cast<Relation &>(R).set_var(i)->name());
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ int coef_in_equality = 0;
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++)
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++)
+ if (((*gi).get_coef(const_cast<Relation &>(R).set_var(pos)) != 0)
+ && (!(*gi).has_wildcards()))
+ if (coef_in_equality == 0)
+ coef_in_equality = (*gi).get_coef(
+ const_cast<Relation &>(R).set_var(pos));
+ else
+ return std::pair<Relation, bool>(copy(R), false);
+
+ if (coef_in_equality < 0)
+ coef_in_equality = -coef_in_equality;
+
+ std::pair<EQ_Handle, Variable_ID> result = find_simplest_stride(
+ const_cast<Relation &>(R), const_cast<Relation &>(R).set_var(pos));
+
+ if (result.second == NULL && coef_in_equality != 1)
+ return std::pair<Relation, bool>(copy(R), false);
+
+ if (result.second != NULL) {
+ if (result.first.get_coef(const_cast<Relation &>(R).set_var(pos)) != 1)
+ return std::pair<Relation, bool>(copy(R), false);
+
+ if (result.first.get_coef(result.second) != coef_in_equality)
+ return std::pair<Relation, bool>(copy(R), false);
+ }
+ Variable_ID v3 = f_exists->declare();
+
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h1 = f_root->add_EQ();
+ if ((*gi).get_coef(const_cast<Relation &>(R).set_var(pos)) == 0
+ || !(*gi).has_wildcards()) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ if (v->get_position() != pos)
+ h1.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h1.update_coef(v3, cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h1.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h1.update_const((*gi).get_const());
+ }
+ }
+ }
+
+ for (int i = 0; i < bound.size(); i++)
+ for (DNF_Iterator di(bound[i].query_DNF()); di; di++) {
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ //if ((*gi).get_coef(const_cast<Relation &>(R).set_var(i)) != 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ //if (i < level)
+ if (v->get_position() != pos)
+
+ h.update_coef(r.set_var(v->get_position()),
+ cvi.curr_coef());
+ else
+
+ h.update_coef(v3, cvi.curr_coef());
+
+ //else
+ // h.update_coef(
+ // r.input_var(v->get_position() + 1),
+ // cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ }
+ h.update_const((*gi).get_const());
+ //}
+ }
+ }
+
+ //for (int i = 1; i <= R.n_set(); i++)
+ return std::pair<Relation, bool>(r, true);
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Copy all relations from r except those for set var v.
+// And with GEQ given by g
+// NOTE: This function only removes the relations involving v if they are simple relations
+// involving only v but not complex relations that have v in other variables' constraints
+// -----------------------------------------------------------------------------
+Relation and_with_relation_and_replace_var(const Relation &R, Variable_ID v1,
+ Relation &g) {
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ EQ_Handle h = f_root->add_EQ();
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++) {
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++) {
+ EQ_Handle h = f_root->add_EQ();
+ if (!(*gi).is_const(v1) && !(*gi).is_const_except_for_global(v1)) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+
+ h.update_const((*gi).get_const());
+ }
+ }
+
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++) {
+ GEQ_Handle h = f_root->add_GEQ();
+ if ((*gi).get_coef(v1) == 0) {
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ {
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ break;
+ }
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+ }
+ }
+ for (DNF_Iterator di(const_cast<Relation &>(g).query_DNF()); di; di++)
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++)
+ r.and_with_GEQ(*gi);
+
+ for (DNF_Iterator di(const_cast<Relation &>(g).query_DNF()); di; di++)
+ for (EQ_Iterator gi((*di)->EQs()); gi; gi++)
+ r.and_with_EQ(*gi);
+
+ r.simplify();
+ r.copy_names(R);
+ r.setup_names();
+ return r;
+}
+
+
+
+
+
+omega::Relation extract_upper_bound(const Relation &R, Variable_ID v1) {
+ if (!R.is_set())
+ throw std::invalid_argument("Input R has to be a set not a relation!");
+
+ Relation r(R.n_set());
+
+ F_Exists *f_exists = r.add_and()->add_exists();
+ F_And *f_root = f_exists->add_and();
+ std::map<Variable_ID, Variable_ID> exists_mapping;
+ GEQ_Handle h = f_root->add_GEQ();
+ for (DNF_Iterator di(const_cast<Relation &>(R).query_DNF()); di; di++)
+ for (GEQ_Iterator gi((*di)->GEQs()); gi; gi++)
+ if ((*gi).get_coef(v1) < 0) {
+
+ for (Constr_Vars_Iter cvi(*gi); cvi; cvi++) {
+ Variable_ID v = cvi.curr_var();
+ switch (v->kind()) {
+ case Input_Var:
+ h.update_coef(r.input_var(v->get_position()),
+ cvi.curr_coef());
+ break;
+ case Wildcard_Var:
+ {
+ Variable_ID v2 = replicate_floor_definition(R, v, r,
+ f_exists, f_root, exists_mapping);
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ case Global_Var:
+ {
+ Global_Var_ID g = v->get_global_var();
+ Variable_ID v2;
+ if (g->arity() == 0)
+ v2 = r.get_local(g);
+ else
+ v2 = r.get_local(g, v->function_of());
+ h.update_coef(v2, cvi.curr_coef());
+ break;
+ }
+ default:
+ assert(false);
+ }
+ }
+ h.update_const((*gi).get_const());
+ }
+
+ r.simplify();
+
+ return r;
+
+}
+
+/*CG_outputRepr * modified_output_subs_repr(CG_outputBuilder * ocg, const Relation &R, const EQ_Handle &h, Variable_ID v,const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly,
+ std::map<std::string, std::vector<CG_outputRepr *> > unin){
+
+
+
+
+ }
+*/
+
+
+
+
+
+CG_outputRepr * construct_int_floor(CG_outputBuilder * ocg, const Relation &R,
+ const GEQ_Handle &h, Variable_ID v,
+ const std::vector<std::pair<CG_outputRepr *, int> > &assigned_on_the_fly,
+ std::map<std::string, std::vector<CG_outputRepr *> > unin) {
+
+ std::set<Variable_ID> excluded_floor_vars;
+ const_cast<Relation &>(R).setup_names(); // hack
+ assert(v->kind() == Set_Var);
+
+ int a = h.get_coef(v);
+
+ CG_outputRepr *lhs = ocg->CreateIdent(v->name());
+ excluded_floor_vars.insert(v);
+ std::vector<std::pair<bool, GEQ_Handle> > result2;
+ CG_outputRepr *repr = NULL;
+ for (Constr_Vars_Iter cvi(h); cvi; cvi++)
+ if (cvi.curr_var() != v) {
+ CG_outputRepr *t;
+ if (cvi.curr_var()->kind() == Wildcard_Var) {
+ std::pair<bool, GEQ_Handle> result = find_floor_definition(R,
+ cvi.curr_var(), excluded_floor_vars);
+ if (!result.first) {
+ coef_t coef_ = cvi.curr_coef();
+ result2 = find_floor_definition_temp(R, cvi.curr_var(),
+ excluded_floor_vars);
+
+ for (Constr_Vars_Iter cvi_(
+ result2[result2.size() - 1].second); cvi_; cvi_++) {
+ if (cvi_.curr_var()->kind() != Wildcard_Var
+ && cvi_.curr_var()->kind() != Set_Var) {
+ t = output_ident(ocg, R, cvi_.curr_var(),
+ assigned_on_the_fly, unin);
+ coef_t coef2 = cvi_.curr_coef();
+ assert(cvi_.curr_coef() == -1 && a == 1);
+ repr = ocg->CreateIntegerFloor(t,
+ ocg->CreateInt(-coef_));
+ repr = ocg->CreateTimes(ocg->CreateInt(-coef_),
+ repr);
+
+ return repr;
+
+ }
+
+ }
+
+ };
+ if (!result.first) {
+ delete repr;
+ throw omega_error(
+ "Can't generate bound expression with wildcard not involved in floor definition");
+ }
+
+ try {
+ t = output_inequality_repr(ocg, result.second,
+ cvi.curr_var(), R, assigned_on_the_fly, unin,
+ excluded_floor_vars);
+ } catch (const std::exception &e) {
+ delete repr;
+ throw e;
+ }
+ }
+ else
+ t = output_ident(ocg, R, cvi.curr_var(), assigned_on_the_fly,
+ unin);
+
+ coef_t coef = cvi.curr_coef();
+ if (a > 0) {
+ if (coef > 0) {
+ if (coef == 1)
+ repr = ocg->CreateMinus(repr, t);
+ else
+ repr = ocg->CreateMinus(repr,
+ ocg->CreateTimes(ocg->CreateInt(coef), t));
+ }
+ else {
+ if (coef == -1)
+ repr = ocg->CreatePlus(repr, t);
+ else
+ repr = ocg->CreatePlus(repr,
+ ocg->CreateTimes(ocg->CreateInt(-coef), t));
+ }
+ }
+ else {
+ if (coef > 0) {
+ if (coef == 1)
+ repr = ocg->CreatePlus(repr, t);
+ else
+ repr = ocg->CreatePlus(repr,
+ ocg->CreateTimes(ocg->CreateInt(coef), t));
+ }
+ else {
+ if (coef == -1)
+ repr = ocg->CreateMinus(repr, t);
+ else
+ repr = ocg->CreateMinus(repr,
+ ocg->CreateTimes(ocg->CreateInt(-coef), t));
+ }
+ }
+ }
+ coef_t c = h.get_const();
+ if (c > 0) {
+ if (a > 0)
+ repr = ocg->CreateMinus(repr, ocg->CreateInt(c));
+ else
+ repr = ocg->CreatePlus(repr, ocg->CreateInt(c));
+ }
+ else if (c < 0) {
+ if (a > 0)
+ repr = ocg->CreatePlus(repr, ocg->CreateInt(-c));
+ else
+ repr = ocg->CreateMinus(repr, ocg->CreateInt(-c));
+ }
+
+ if (abs(a) == 1)
+ ocg->CreateAssignment(0, lhs, repr);
+ else if (a > 0)
+ return ocg->CreateAssignment(0, lhs,
+ ocg->CreateIntegerCeil(repr, ocg->CreateInt(a)));
+ else
+ // a < 0
+ return ocg->CreateAssignment(0, lhs,
+ ocg->CreateIntegerFloor(repr, ocg->CreateInt(-a)));
+
+}
+
+
+
+