//searches for locations where types may be connected through assignment, passing as argument and returns //then passes the associated node along with the expression to link variables. int Analysis::variableSetAnalysis(SgProject* project, SgType* matchType, bool base){ RoseAst wholeAST(project); list<SgVariableDeclaration*> listOfGlobalVars = SgNodeHelper::listOfGlobalVars(project); if(listOfGlobalVars.size() > 0){ for(auto varDec : listOfGlobalVars){ SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDec); if(!initName) continue; SgInitializer* init = initName->get_initializer(); if(!init) continue; SgType* keyType = initName->get_type(); if(!checkMatch(base, keyType, matchType)) continue; addToMap(varDec, varDec); if(!isArrayPointerType(keyType)) continue; SgExpression* exp = init; linkVariables(varDec, keyType, exp); } } list<SgFunctionDefinition*> listOfFunctionDefinitions = SgNodeHelper::listOfFunctionDefinitions(project); for(auto funDef : listOfFunctionDefinitions){ SgInitializedNamePtrList& initNameList = SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef); SgFunctionDeclaration* funDec = funDef->get_declaration(); if(checkMatch(base, funDec->get_type()->get_return_type(), matchType)) addToMap(funDec, funDec); for(auto init : initNameList) if(checkMatch(base, init->get_type(), matchType)) addToMap(init, init); RoseAst ast(funDef); for(RoseAst::iterator i = ast.begin(); i!=ast.end(); i++){ SgNode* key = nullptr; SgType* keyType = nullptr; SgExpression* exp = nullptr; if(SgAssignOp* assignOp = isSgAssignOp(*i)){ SgExpression* lhs = assignOp->get_lhs_operand(); if(SgVarRefExp* varRef = isSgVarRefExp(lhs)){ keyType = varRef->get_type(); if(!isArrayPointerType(keyType)) continue; SgVariableSymbol* varSym = varRef->get_symbol(); key = varSym->get_declaration()->get_declaration(); } exp = assignOp->get_rhs_operand(); } else if(SgVariableDeclaration* varDec = isSgVariableDeclaration(*i)){ SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDec); if(!initName) continue; if(checkMatch(base, matchType, initName->get_type())) addToMap(varDec, varDec); SgInitializer* init = initName->get_initializer(); if(!init) continue; keyType = initName->get_type(); if(!isArrayPointerType(keyType)) continue; key = initName->get_declaration(); exp = init; } else if(SgFunctionCallExp* callExp = isSgFunctionCallExp(*i)){ SgFunctionDefinition* funDef = SgNodeHelper::determineFunctionDefinition(callExp); if(!funDef) continue; SgInitializedNamePtrList& initNameList = SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef); SgExpressionPtrList& expList = callExp->get_args()->get_expressions(); auto initIter = initNameList.begin(); auto expIter = expList.begin(); while(initIter != initNameList.end()){ if(isArrayPointerType((*initIter)->get_type())){ if(checkMatch(base, matchType, (*initIter)->get_type())) linkVariables((*initIter), (*initIter)->get_type(), (*expIter)); } ++initIter; ++expIter; } } else if(SgReturnStmt* ret = isSgReturnStmt(*i)){ exp = ret->get_expression(); keyType = exp->get_type(); if(!isArrayPointerType(keyType)) continue; key = funDec; } if(!checkMatch(base, keyType, matchType)) continue; if(key && keyType && exp) linkVariables(key, keyType, exp); } } for(auto i = setMap.begin(); i != setMap.end(); ++i){ bool intersect = false; set<SgNode*>* found = nullptr; for(auto j = listSets.begin(); j != listSets.end(); ++j){ intersect = setIntersect(*j, i->second); if((*j)->count(i->first)) intersect = true; if(found != nullptr && intersect){ inPlaceUnion(found, i->second); inPlaceUnion(found, *j); (found)->insert(i->first); j = listSets.erase(j); ++j; } else if(intersect){ inPlaceUnion(*j, i->second); (*j)->insert(i->first); found = *j; } } if(!intersect){ set<SgNode*>* copy = copySet(i->second); copy->insert(i->first); listSets.push_back(copy); } } return 0; }
void TransformationSupport::getTransformationOptions ( SgNode* astNode, list<OptionDeclaration> & generatedList, string identifingTypeName ) { // This function searches for variables of type ScopeBasedTransformationOptimization. Variables // of type ScopeBasedTransformationOptimization are used to communicate optimizations from the // application to the preprocessor. If called from a project or file object it traverses down to // the global scope of the file and searches only the global scope, if called from and other // location within the AST it searches the current scope and then traverses the parent nodes to // find all enclosing scopes until in reaches the global scope. At each scope it searches for // variables of type ScopeBasedTransformationOptimization. // printf ("######################### START OF TRANSFORMATION OPTION QUERY ######################## \n"); ROSE_ASSERT (astNode != NULL); ROSE_ASSERT (identifingTypeName.c_str() != NULL); #if 0 printf ("In getTransformationOptions(): astNode->sage_class_name() = %s generatedList.size() = %d \n", astNode->sage_class_name(),generatedList.size()); SgLocatedNode* locatedNode = isSgLocatedNode(astNode); if (locatedNode != NULL) { printf (" locatedNode->get_file_info()->get_filename() = %s \n",locatedNode->get_file_info()->get_filename()); printf (" locatedNode->get_file_info()->get_line() = %d \n",locatedNode->get_file_info()->get_line()); } #endif switch (astNode->variant()) { case ProjectTag: { SgProject* project = isSgProject(astNode); ROSE_ASSERT (project != NULL); //! Loop through all the files in the project and call the mainTransform function for each file int i = 0; for (i=0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); // printf ("Calling Query::traverse(SgFile,QueryFunctionType,QueryAssemblyFunctionType) \n"); getTransformationOptions ( file, generatedList, identifingTypeName ); } break; } case SourceFileTag: { SgSourceFile* file = isSgSourceFile(astNode); ROSE_ASSERT (file != NULL); SgGlobal* globalScope = file->get_globalScope(); ROSE_ASSERT (globalScope != NULL); ROSE_ASSERT (isSgGlobal(globalScope) != NULL); getTransformationOptions ( globalScope, generatedList, identifingTypeName ); break; } // Global Scope case GLOBAL_STMT: { SgGlobal* globalScope = isSgGlobal(astNode); ROSE_ASSERT (globalScope != NULL); SgSymbolTable* symbolTable = globalScope->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // printf ("Processed global scope, exiting .. \n"); // ROSE_ABORT(); break; } case SymbolTableTag: { // List the variable in each scope // printf ("List all the variables in this symbol table! \n"); SgSymbolTable* symbolTable = isSgSymbolTable(astNode); ROSE_ASSERT (symbolTable != NULL); bool foundTransformationOptimizationSpecifier = false; // printf ("Now print out the information in the symbol table for this scope: \n"); // symbolTable->print(); #if 0 // I don't know when a SymbolTable is given a name! printf ("SymbolTable has a name = %s \n", (symbolTable->get_no_name()) ? "NO: it has no name" : "YES: it does have a name"); if (!symbolTable->get_no_name()) printf ("SymbolTable name = %s \n",symbolTable->get_name().str()); else ROSE_ASSERT (symbolTable->get_name().str() == NULL); #endif if (symbolTable->get_table() != NULL) { SgSymbolTable::hash_iterator i = symbolTable->get_table()->begin(); int counter = 0; while (i != symbolTable->get_table()->end()) { ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Initial info: number: %d pair.first (SgName) = %s pair.second (SgSymbol) sage_class_name() = %s \n", // counter,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); SgType* type = symbol->get_type(); ROSE_ASSERT ( type != NULL ); SgNamedType* namedType = isSgNamedType(type); string typeName; if (namedType != NULL) { SgName n = namedType->get_name(); typeName = namedType->get_name().str(); // char* nameString = namedType->get_name().str(); // printf ("Type is: (named type) = %s \n",nameString); ROSE_ASSERT (identifingTypeName.c_str() != NULL); // ROSE_ASSERT (typeName != NULL); // printf ("In getTransformationOptions(): typeName = %s identifingTypeName = %s \n",typeName.c_str(),identifingTypeName.c_str()); // if ( (typeName != NULL) && ( typeName == identifingTypeName) ) if ( typeName == identifingTypeName ) { // Now look at the parameter list to the constructor and save the // values into the list. // printf ("Now save the constructor arguments! \n"); SgVariableSymbol* variableSymbol = isSgVariableSymbol(symbol); if ( variableSymbol != NULL ) { SgInitializedName* initializedNameDeclaration = variableSymbol->get_declaration(); ROSE_ASSERT (initializedNameDeclaration != NULL); SgDeclarationStatement* declarationStatement = initializedNameDeclaration->get_declaration(); ROSE_ASSERT (declarationStatement != NULL); SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(declarationStatement); ROSE_ASSERT (variableDeclaration != NULL); getTransformationOptionsFromVariableDeclarationConstructorArguments(variableDeclaration,generatedList); foundTransformationOptimizationSpecifier = true; // printf ("Exiting after saving the constructor arguments! \n"); // ROSE_ABORT(); } else { #if 0 printf ("Not a SgVariableSymbol: symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif } } else { #if 0 printf ("typeName != identifingTypeName : symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif #if 0 // I don't think this should ever be NULL (but it is sometimes) if (typeName != NULL) printf ("typeName == NULL \n"); #endif } } else { typeName = (char *)type->sage_class_name(); } // printf ("In while loop at the base: counter = %d \n",counter); i++; counter++; } } else { // printf ("Pointer to symbol table is NULL \n"); } // printf ("foundTransformationOptimizationSpecifier = %s \n",foundTransformationOptimizationSpecifier ? "true" : "false"); // SgSymbolTable objects don't have a parent node (specifically they lack a get_parent // member function in the interface)! break; } case BASIC_BLOCK_STMT: { // List the variable in each scope // printf ("List all the variables in this scope! \n"); SgBasicBlock* basicBlock = isSgBasicBlock(astNode); ROSE_ASSERT (basicBlock != NULL); SgSymbolTable* symbolTable = basicBlock->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // Next go (fall through this case) to the default case so that we traverse the parent // of the SgBasicBlock. // break; } default: // Most cases will be the default (this is by design) // printf ("default in switch found in globalQueryGetListOperandStringFunction() (sage_class_name = %s) \n",astNode->sage_class_name()); // Need to recursively backtrack through the parents until we reach the SgGlobal (global scope) SgStatement* statement = isSgStatement(astNode); if (statement != NULL) { SgNode* parentNode = statement->get_parent(); ROSE_ASSERT (parentNode != NULL); // printf ("parent = %p parentNode->sage_class_name() = %s \n",parentNode,parentNode->sage_class_name()); SgStatement* parentStatement = isSgStatement(parentNode); if (parentStatement == NULL) { printf ("parentStatement == NULL: statement (%p) is a %s \n",statement,statement->sage_class_name()); printf ("parentStatement == NULL: statement->get_file_info()->get_filename() = %s \n",statement->get_file_info()->get_filename()); printf ("parentStatement == NULL: statement->get_file_info()->get_line() = %d \n",statement->get_file_info()->get_line()); } ROSE_ASSERT (parentStatement != NULL); // Call this function recursively (directly rather than through the query mechanism) getTransformationOptions ( parentStatement, generatedList, identifingTypeName ); } else { // printf ("astNode is not a SgStatement! \n"); } break; } #if 0 printf ("At BASE of getTransformationOptions(): astNode->sage_class_name() = %s size of generatedList = %d \n", astNode->sage_class_name(),generatedList.size()); #endif // printf ("######################### END OF TRANSFORMATION OPTION QUERY ######################## \n"); }