diff options
| author | Tuowen Zhao <ztuowen@gmail.com> | 2016-09-21 22:35:47 -0600 | 
|---|---|---|
| committer | Tuowen Zhao <ztuowen@gmail.com> | 2016-09-21 22:35:47 -0600 | 
| commit | ab016596602a4c6bdc27adf01c308b325af221f0 (patch) | |
| tree | 4e86bfcf1f38fb00cc58082d540dc3570e0f126b /src | |
| parent | 6983c09937baac3ffb7d3a45c3c5009c0eba7e6c (diff) | |
| download | chill-ab016596602a4c6bdc27adf01c308b325af221f0.tar.gz chill-ab016596602a4c6bdc27adf01c308b325af221f0.tar.bz2 chill-ab016596602a4c6bdc27adf01c308b325af221f0.zip  | |
something that only builds ...
Diffstat (limited to 'src')
| -rw-r--r-- | src/chill.cc | 3 | ||||
| -rw-r--r-- | src/chill_ast.cc | 6493 | ||||
| -rw-r--r-- | src/chillmodule.cc | 6 | ||||
| -rw-r--r-- | src/dep.cc | 133 | ||||
| -rwxr-xr-x | src/ir_clang.cc | 3239 | ||||
| -rw-r--r-- | src/ir_rose.cc | 1699 | ||||
| -rw-r--r-- | src/ir_rose_utils.cc | 62 | ||||
| -rw-r--r-- | src/irtools.cc | 525 | ||||
| -rw-r--r-- | src/loop.cc | 3500 | ||||
| -rw-r--r-- | src/loop_basic.cc | 477 | ||||
| -rw-r--r-- | src/loop_datacopy.cc | 282 | ||||
| -rw-r--r-- | src/loop_unroll.cc | 118 | ||||
| -rw-r--r-- | src/omegatools.cc | 3007 | 
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( ¶meters, 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++) { @@ -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))); +   +} + + + +  | 
