void SPRAY::set_union(const VariableIdSet& set1, const VariableIdSet& set2, VariableIdSet& rset) { VariableIdSet::const_iterator it1 = set1.begin(); VariableIdSet::const_iterator it2 = set2.begin(); VariableIdSet::iterator rit = rset.begin(); // // re-implementation of set-union while(true) { if(it1 == set1.end()) { rset.insert(it2, set2.end()); break; } if(it2 == set2.end()) { rset.insert(it1, set1.end()); break; } if(*it1 < *it2) { rset.insert(rit, *it1); ++it1; ++rit; } else if(*it2 < *it1) { rset.insert(rit, *it2); ++it2; ++rit; } else { rset.insert(rit, *it1); ++it1; ++it2; ++rit; } } }
void FIConstAnalysis::filterVariables(VariableIdSet& variableIdSet) { VariableIdSet toBeRemoved; for(VarConstSetMap::iterator i=_varConstSetMap.begin(); i!=_varConstSetMap.end(); ++i) { VariableId varId=(*i).first; if(variableIdSet.find(varId)==variableIdSet.end()) { toBeRemoved.insert(varId); } } for(VariableIdSet::iterator i=toBeRemoved.begin(); i!=toBeRemoved.end(); ++i) { _varConstSetMap.erase(*i); } }
std::string SPRAY::VariableIdSetPrettyPrint::str(VariableIdSet& vset, VariableIdMapping& vidm) { std::ostringstream ostr; ostr << "["; VariableIdSet::iterator it = vset.begin(); for( ; it != vset.end(); ) { ostr << "<" << (*it).toString() << ", " << vidm.variableName(*it) << ">"; it++; if(it != vset.end()) ostr << ", "; } ostr << "]"; return ostr.str(); }
std::string SPRAY::VariableIdSetPrettyPrint::str(VariableIdSet& vset) { std::ostringstream ostr; ostr << "["; VariableIdSet::iterator it = vset.begin(); for( ; it != vset.end(); ) { ostr << (*it).toString(); it++; if(it != vset.end()) ostr << ", "; } ostr << "]"; return ostr.str(); }
/*! * \author Markus Schordan * \date 2014. */ void SPRAY::IntervalTransferFunctions::transferFunctionExit(Label lab, SgFunctionDefinition* funDef, VariableIdSet& localVariablesInFunction, Lattice& element) { // remove all declared variables at function exit (including function parameter variables) for(VariableIdSet::iterator i=localVariablesInFunction.begin();i!=localVariablesInFunction.end();++i) { VariableId varId=*i; IntervalPropertyState* ips=dynamic_cast<IntervalPropertyState*>(&element); ips->removeVariable(varId); } }
/*! * \author Markus Schordan * \date 2013. */ void RDTransferFunctions::transferFunctionExit(Label lab, SgFunctionDefinition* callExp, VariableIdSet& localVariablesInFunction, Lattice& element0) { RDLattice& element=dynamic_cast<RDLattice&>(element0); // remove all declared variable at function exit (including function parameter variables) for(VariableIdSet::iterator i=localVariablesInFunction.begin();i!=localVariablesInFunction.end();++i) { VariableId varId=*i; element.removeAllPairsWithVariableId(varId); } }
// returns the number of race conditions detected (0 or 1 as of now) int Specialization::verifyUpdateSequenceRaceConditions(LoopInfoSet& loopInfoSet, ArrayUpdatesSequence& arrayUpdates, VariableIdMapping* variableIdMapping) { int cnt=0; stringstream ss; cout<<"STATUS: checking race conditions."<<endl; cout<<"INFO: number of parallel loops: "<<numParLoops(loopInfoSet,variableIdMapping)<<endl; VariableIdSet allIterVars; for(LoopInfoSet::iterator lis=loopInfoSet.begin();lis!=loopInfoSet.end();++lis) { allIterVars.insert((*lis).iterationVarId); } for(LoopInfoSet::iterator lis=loopInfoSet.begin();lis!=loopInfoSet.end();++lis) { if((*lis).iterationVarType==ITERVAR_PAR) { VariableId parVariable; parVariable=(*lis).iterationVarId; cout<<"INFO: checking parallel loop: "<<variableIdMapping->variableName(parVariable)<<endl; // race check // intersect w-set_i = empty // w-set_i intersect r-set_j = empty, i!=j. IndexToReadWriteDataMap indexToReadWriteDataMap; for(ArrayUpdatesSequence::iterator i=arrayUpdates.begin();i!=arrayUpdates.end();++i) { const EState* estate=(*i).first; const PState* pstate=estate->pstate(); SgExpression* exp=(*i).second; IndexVector index; // use all vars for indexing or only outer+par loop variables #ifdef USE_ALL_ITER_VARS for(VariableIdSet::iterator ol=allIterVars.begin();ol!=allIterVars.end();++ol) { VariableId otherVarId=*ol; ROSE_ASSERT(otherVarId.isValid()); if(!pstate->varValue(otherVarId).isTop()) { int otherIntVal=pstate->varValue(otherVarId).getIntValue(); index.push_back(otherIntVal); } } #else for(VariableIdSet::iterator ol=(*lis).outerLoopsVarIds.begin();ol!=(*lis).outerLoopsVarIds.end();++ol) { VariableId otherVarId=*ol; ROSE_ASSERT(otherVarId.isValid()); if(!pstate->varValue(otherVarId).isTop()&&pstate->varValue(otherVarId).isConstInt()) { int otherIntVal=pstate->varValue(otherVarId).getIntValue(); index.push_back(otherIntVal); } } if(!pstate->varValue(parVariable).isTop()&&pstate->varValue(parVariable).isConstInt()) { int parIntVal=pstate->varValue(parVariable).getIntValue(); index.push_back(parIntVal); } #endif if((*lis).isInAssociatedLoop(estate)) { SgExpression* lhs=isSgExpression(SgNodeHelper::getLhs(exp)); SgExpression* rhs=isSgExpression(SgNodeHelper::getRhs(exp)); ROSE_ASSERT(isSgPntrArrRefExp(lhs)||SgNodeHelper::isFloatingPointAssignment(exp)); //cout<<"EXP: "<<exp->unparseToString()<<", lhs:"<<lhs->unparseToString()<<" :: "<<endl; // read-set RoseAst rhsast(rhs); for(RoseAst::iterator j=rhsast.begin();j!=rhsast.end();++j) { if(SgPntrArrRefExp* useRef=isSgPntrArrRefExp(*j)) { j.skipChildrenOnForward(); ArrayElementAccessData access(useRef,variableIdMapping); indexToReadWriteDataMap[index].readArrayAccessSet.insert(access); } else if(SgVarRefExp* useRef=isSgVarRefExp(*j)) { ROSE_ASSERT(useRef); j.skipChildrenOnForward(); VariableId varId=variableIdMapping->variableId(useRef); indexToReadWriteDataMap[index].readVarIdSet.insert(varId); } else { //cout<<"INFO: UpdateExtraction: ignored expression on rhs:"<<(*j)->unparseToString()<<endl; } } if(SgPntrArrRefExp* arr=isSgPntrArrRefExp(lhs)) { ArrayElementAccessData access(arr,variableIdMapping); indexToReadWriteDataMap[index].writeArrayAccessSet.insert(access); } else if(SgVarRefExp* var=isSgVarRefExp(lhs)) { VariableId varId=variableIdMapping->variableId(var); indexToReadWriteDataMap[index].writeVarIdSet.insert(varId); } else { cerr<<"Error: SSA Numbering: unknown LHS."<<endl; exit(1); } ss<<"UPD"<<cnt<<":"<<pstate->toString(variableIdMapping)<<" : "<<exp->unparseToString()<<endl; ++cnt; } } // array sequence iter // to be utilized later for more detailed output #if 0 for(IndexToReadWriteDataMap::iterator imap=indexToReadWriteDataMap.begin(); imap!=indexToReadWriteDataMap.end(); ++imap) { // cout<<"DEBUG: INDEX: "<<(*imap).first<<" R-SET: "; IndexVector index=(*imap).first; cout<<"DEBUG: INDEX: "; for(IndexVector::iterator iv=index.begin();iv!=index.end();++iv) { if(iv!=index.begin()) cout<<","; cout<<*iv; } cout<<" R-SET: "; for(ArrayElementAccessDataSet::const_iterator i=indexToReadWriteDataMap[index].readArrayAccessSet.begin();i!=indexToReadWriteDataMap[index].readArrayAccessSet.end();++i) { cout<<(*i).toString(variableIdMapping)<<" "; } cout<<endl; cout<<"DEBUG: INDEX: "; for(IndexVector::iterator iv=index.begin();iv!=index.end();++iv) { if(iv!=index.begin()) cout<<","; cout<<*iv; } cout<<" W-SET: "; for(ArrayElementAccessDataSet::const_iterator i=indexToReadWriteDataMap[index].writeArrayAccessSet.begin();i!=indexToReadWriteDataMap[index].writeArrayAccessSet.end();++i) { cout<<(*i).toString(variableIdMapping)<<" "; } cout<<endl; cout<<"DEBUG: read-array-access:"<<indexToReadWriteDataMap[index].readArrayAccessSet.size()<<" read-var-access:"<<indexToReadWriteDataMap[index].readVarIdSet.size()<<endl; cout<<"DEBUG: write-array-access:"<<indexToReadWriteDataMap[index].writeArrayAccessSet.size()<<" write-var-access:"<<indexToReadWriteDataMap[index].writeVarIdSet.size()<<endl; } // imap #endif // perform the check now // 1) compute vector if index-vectors for each outer-var-vector // 2) check each index-vector. For each iteration of each par-loop iteration then. //typedef set<int> ParVariableValueSet; //ParVariableValueSet parVariableValueSet; // MAP: par-variable-val -> vector of IndexVectors with this par-variable-val typedef vector<IndexVector> ThreadVector; typedef map<IndexVector,ThreadVector > CheckMapType; CheckMapType checkMap; for(IndexToReadWriteDataMap::iterator imap=indexToReadWriteDataMap.begin(); imap!=indexToReadWriteDataMap.end(); ++imap) { IndexVector index=(*imap).first; IndexVector outVarIndex; // if index.size()==0, it will analyze the loop independet of outer loops if(index.size()>0) { ROSE_ASSERT(index.size()>0); for(size_t iv1=0;iv1<index.size()-1;iv1++) { outVarIndex.push_back(index[iv1]); } ROSE_ASSERT(outVarIndex.size()<index.size()); } else { // nothing to check continue; } // last index of index of par-variable //int parVariableValue=index[index.size()-1]; checkMap[outVarIndex].push_back(index); } //cout<<"INFO: race condition check-map size: "<<checkMap.size()<<endl; // perform the check now for(CheckMapType::iterator miter=checkMap.begin();miter!=checkMap.end();++miter) { IndexVector outerVarIndexVector=(*miter).first; ThreadVector threadVectorToCheck=(*miter).second; //cout<<"DEBUG: to check: "<<threadVectorToCheck.size()<<endl; for(ThreadVector::iterator tv1=threadVectorToCheck.begin();tv1!=threadVectorToCheck.end();++tv1) { ArrayElementAccessDataSet wset=indexToReadWriteDataMap[*tv1].writeArrayAccessSet; for(ThreadVector::iterator tv2=tv1;tv2!=threadVectorToCheck.end();++tv2) { ThreadVector::iterator tv2b=tv2; ++tv2b; if(tv2b!=threadVectorToCheck.end()) { ArrayElementAccessDataSet rset2=indexToReadWriteDataMap[*tv2b].readArrayAccessSet; ArrayElementAccessDataSet wset2=indexToReadWriteDataMap[*tv2b].writeArrayAccessSet; // check intersect(rset,wset) if(accessSetIntersect(wset,rset2)) { // verification failed cout<<"INFO: race condition detected (wset1,rset2)."<<endl; return 1; } if(accessSetIntersect(wset,wset2)) { // verification failed cout<<"INFO: race condition detected (wset1,wset2)."<<endl; return 1; } } } } } } // if parallel loop } // foreach loop return 0; }
void runAnalyses(SgProject* root, Labeler* labeler, VariableIdMapping* variableIdMapping) { SPRAY::DFAnalysisBase::normalizeProgram(root); if(option_fi_constanalysis) { VarConstSetMap varConstSetMap; FIConstAnalysis fiConstAnalysis(variableIdMapping); fiConstAnalysis.runAnalysis(root); fiConstAnalysis.attachAstAttributes(labeler,"const-analysis-inout"); // not iolabeler if(csvConstResultFileName) { cout<<"INFO: generating const CSV file "<<option_prefix+csvConstResultFileName<<endl; fiConstAnalysis.writeCvsConstResult(*variableIdMapping, option_prefix+csvConstResultFileName); } cout << "INFO: annotating analysis results as comments."<<endl; AstAnnotator ara(labeler); ara.annotateAstAttributesAsCommentsBeforeStatements(root, "const-analysis-inout"); ara.annotateAstAttributesAsCommentsAfterStatements(root, "const-analysis-inout"); } if(option_at_analysis) { cout<<"STATUS: running address taken analysis."<<endl; cout << "STATUS: computing variable and function mappings."<<endl; // compute variableId mappings VariableIdMapping variableIdMapping; variableIdMapping.computeVariableSymbolMapping(root); // Compute function id mappings: FunctionIdMapping functionIdMapping; functionIdMapping.computeFunctionSymbolMapping(root); if(option_trace) { std::cout << std::endl << "TRACE: Variable Id Mapping:" << std::endl; variableIdMapping.toStream(std::cout); std::cout << std::endl << "TRACE: Function Id Mapping:" << std::endl; functionIdMapping.toStream(std::cout); } cout << "STATUS: computing address taken sets."<<endl; SPRAY::FIPointerAnalysis fipa(&variableIdMapping, &functionIdMapping, root); fipa.initialize(); fipa.run(); //cout << "STATUS: computed address taken sets:"<<endl; //fipa.getFIPointerInfo()->printInfoSets(); bool createCsv = false; ofstream addressTakenCsvFile; if(csvAddressTakenResultFileName) { std::string addressTakenCsvFileName = option_prefix; addressTakenCsvFileName += csvAddressTakenResultFileName; addressTakenCsvFile.open(addressTakenCsvFileName.c_str()); createCsv = true; } cout << "INFO: annotating declarations of address taken variables and functions."<<endl; // Annotate declarations/definitions of variables from which the address was taken: VariableIdSet addressTakenVariableIds = fipa.getAddressTakenVariables(); for(VariableIdSet::const_iterator idIter = addressTakenVariableIds.begin(); idIter != addressTakenVariableIds.end(); ++idIter) { // Determine the variable declaration/definition: SgLocatedNode* decl = variableIdMapping.getVariableDeclaration(*idIter); if(!decl) { // The current variable is presumably a function parameter: Try to get the initialized name: SgVariableSymbol* varSymbol = isSgVariableSymbol(variableIdMapping.getSymbol(*idIter)); ROSE_ASSERT(varSymbol); SgInitializedName* paramDecl = isSgInitializedName(varSymbol->get_declaration()); // We should not have a real variable declaration for the parameter: ROSE_ASSERT(isSgFunctionParameterList(paramDecl->get_declaration())); // Use the InitializedName: decl = paramDecl; } if(decl) { // Create the comment: ostringstream commentStream; commentStream << "/* Address of \"" << variableIdMapping.variableName(*idIter) << "\" is " << "presumably taken.*/"; // Annotate first declaration: insertComment(commentStream.str(), PreprocessingInfo::before, decl); // TODO: Annotate other declarations too! // Annotate definition if available (e.g. not available in case of parameter): if(SgDeclarationStatement* variableDeclaration = isSgDeclarationStatement(decl)) { if(SgDeclarationStatement* definingDeclaration = variableDeclaration->get_definingDeclaration()) { insertComment(commentStream.str(), PreprocessingInfo::before, definingDeclaration); } } if(createCsv) { // Write variable info to csv: addressTakenCsvFile << VariableId::idKindIndicator << "," // The id of the variable (id codes are influenced by the used system headers // and are therefore not stable/portable): << (option_csv_stable ? string("<unstable>") : int_to_string((*idIter).getIdCode())) << "," // Name of the variable: << variableIdMapping.variableName(*idIter) << "," // TODO: Mangled scope and type are currently not stable/portable // (see comments in getScopeAsMangledStableString(...)) // Mangled type of the variable (non-mangled type may contain commas (e.g. "A<int,bool>"): << (option_csv_stable ? string("<unstable>") : variableIdMapping.getType(*idIter)->get_mangled().getString()) << "," // Mangled scope of the variable: << (option_csv_stable ? string("<unstable>") : getScopeAsMangledStableString(decl)) << "," // Is the address taken? (currently only address taken variables are output to csv) << "1" << endl; } } else { cout << "ERROR: No declaration for " << variableIdMapping.uniqueShortVariableName(*idIter) << " available." << endl; ROSE_ASSERT(false); } } // Annotate declarations and definitions of functions from which the address was taken: FunctionIdSet addressTakenFunctionIds = fipa.getAddressTakenFunctions(); for(FunctionIdSet::const_iterator idIter = addressTakenFunctionIds.begin(); idIter != addressTakenFunctionIds.end(); ++idIter) { if(SgFunctionDeclaration* decl = functionIdMapping.getFunctionDeclaration(*idIter)) { // Create the comment: ostringstream commentStream; commentStream << "/* Address of \"" << functionIdMapping.getFunctionNameFromFunctionId(*idIter) << "(...)\" is " << "presumably taken.*/"; // Annotate first declaration: insertComment(commentStream.str(), PreprocessingInfo::before, decl); // TODO: Annotate other declarations too! // Annotate definition if available: if(SgDeclarationStatement* definingDeclaration = decl->get_definingDeclaration()) { insertComment(commentStream.str(), PreprocessingInfo::before, definingDeclaration); } if(createCsv) { addressTakenCsvFile << FunctionId::idKindIndicator << "," // The id of the function (id codes are influenced by the used system headers // and are therefore not stable/portable): << (option_csv_stable ? string("<unstable>") : int_to_string((*idIter).getIdCode())) << "," // Name of the function: << functionIdMapping.getFunctionNameFromFunctionId(*idIter) << "," // TODO: Mangled scope and type are currently not stable/portable // (see comments in getScopeAsMangledStableString(...)) // Mangled type of the function (non-mangled type may contain commas (e.g. "void (A<int,bool>)"): << (option_csv_stable ? string("<unstable>") : functionIdMapping.getTypeFromFunctionId(*idIter)->get_mangled().getString()) << "," // Mangled scope of the function: << (option_csv_stable ? string("<unstable>") :getScopeAsMangledStableString(decl)) << "," // Is the address taken? (currently only address taken functions are output to csv) << "1" << endl; } } else { cout << "ERROR: No declaration for " << functionIdMapping.getUniqueShortNameFromFunctionId(*idIter) << " available." << endl; ROSE_ASSERT(false); } } if(createCsv) { addressTakenCsvFile.close(); } #if 0 VariableIdSet vidset=fipa.getModByPointer(); cout<<"mod-set: "<<SPRAY::VariableIdSetPrettyPrint::str(vidset,variableIdMapping)<<endl; #endif } if(option_interval_analysis) { cout << "STATUS: creating interval analyzer."<<endl; SPRAY::IntervalAnalysis* intervalAnalyzer=new SPRAY::IntervalAnalysis(); cout << "STATUS: initializing interval analyzer."<<endl; intervalAnalyzer->setNoTopologicalSort(option_no_topological_sort); intervalAnalyzer->initialize(root); cout << "STATUS: running pointer analysis."<<endl; ROSE_ASSERT(intervalAnalyzer->getVariableIdMapping()); SPRAY::FIPointerAnalysis* fipa=new FIPointerAnalysis(intervalAnalyzer->getVariableIdMapping(), intervalAnalyzer->getFunctionIdMapping(), root); fipa->initialize(); fipa->run(); intervalAnalyzer->setPointerAnalysis(fipa); cout << "STATUS: initializing interval transfer functions."<<endl; intervalAnalyzer->initializeTransferFunctions(); cout << "STATUS: initializing interval global variables."<<endl; intervalAnalyzer->initializeGlobalVariables(root); intervalAnalyzer->setSolverTrace(option_trace); std::string funtofind="main"; RoseAst completeast(root); SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind); intervalAnalyzer->determineExtremalLabels(startFunRoot); intervalAnalyzer->run(); #if 0 intervalAnalyzer->attachInInfoToAst("iv-analysis-in"); intervalAnalyzer->attachOutInfoToAst("iv-analysis-out"); AstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping()); ara.annotateAstAttributesAsCommentsBeforeStatements(root, "iv-analysis-in"); ara.annotateAstAttributesAsCommentsAfterStatements(root, "iv-analysis-out"); #else AnalysisAstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping()); ara.annotateAnalysisPrePostInfoAsComments(root,"iv-analysis",intervalAnalyzer); #endif if(option_check_static_array_bounds) { checkStaticArrayBounds(root,intervalAnalyzer); } // schroder3 (2016-08-08): Generate csv-file that contains unreachable statements: if(csvDeadCodeUnreachableFileName) { // Generate file name and open file: std::string deadCodeCsvFileName = option_prefix; deadCodeCsvFileName += csvDeadCodeUnreachableFileName; ofstream deadCodeCsvFile; deadCodeCsvFile.open(deadCodeCsvFileName.c_str()); // Iteratate over all CFG nodes/ labels: for(Flow::const_node_iterator i = intervalAnalyzer->getFlow()->nodes_begin(); i != intervalAnalyzer->getFlow()->nodes_end(); ++i) { const Label& label = *i; // Do not output a function call twice (only the function call label and not the function call return label): if(!intervalAnalyzer->getLabeler()->isFunctionCallReturnLabel(label)) { /*const*/ IntervalPropertyState& intervalsLattice = *static_cast<IntervalPropertyState*>(intervalAnalyzer->getPreInfo(label.getId())); if(intervalsLattice.isBot()) { // Unreachable statement found: const SgNode* correspondingNode = intervalAnalyzer->getLabeler()->getNode(label); ROSE_ASSERT(correspondingNode); // Do not output scope statements ({ }, ...) if(!isSgScopeStatement(correspondingNode)) { deadCodeCsvFile << correspondingNode->get_file_info()->get_line() << "," << SPRAY::replace_string(correspondingNode->unparseToString(), ",", "/*comma*/") << endl; } } } } deadCodeCsvFile.close(); } delete fipa; } if(option_lv_analysis) { cout << "STATUS: creating LV analysis."<<endl; SPRAY::LVAnalysis* lvAnalysis=new SPRAY::LVAnalysis(); cout << "STATUS: initializing LV analysis."<<endl; lvAnalysis->setBackwardAnalysis(); lvAnalysis->setNoTopologicalSort(option_no_topological_sort); lvAnalysis->initialize(root); cout << "STATUS: running pointer analysis."<<endl; ROSE_ASSERT(lvAnalysis->getVariableIdMapping()); SPRAY::FIPointerAnalysis* fipa = new FIPointerAnalysis(lvAnalysis->getVariableIdMapping(), lvAnalysis->getFunctionIdMapping(), root); fipa->initialize(); fipa->run(); lvAnalysis->setPointerAnalysis(fipa); cout << "STATUS: initializing LV transfer functions."<<endl; lvAnalysis->initializeTransferFunctions(); cout << "STATUS: initializing LV global variables."<<endl; lvAnalysis->initializeGlobalVariables(root); std::string funtofind="main"; RoseAst completeast(root); SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind); cout << "generating icfg_backward.dot."<<endl; write_file("icfg_backward.dot", lvAnalysis->getFlow()->toDot(lvAnalysis->getLabeler())); lvAnalysis->determineExtremalLabels(startFunRoot); lvAnalysis->run(); cout << "INFO: attaching LV-data to AST."<<endl; #if 0 lvAnalysis->attachInInfoToAst("lv-analysis-in"); lvAnalysis->attachOutInfoToAst("lv-analysis-out"); AstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping()); ara.annotateAstAttributesAsCommentsBeforeStatements(root, "lv-analysis-in"); ara.annotateAstAttributesAsCommentsAfterStatements(root, "lv-analysis-out"); #else AnalysisAstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping()); ara.annotateAnalysisPrePostInfoAsComments(root,"lv-analysis",lvAnalysis); #endif // schroder3 (2016-08-15): Generate csv-file that contains dead assignments/ initializations: if(csvDeadCodeDeadStoreFileName) { // Generate file name and open file: std::string deadCodeCsvFileName = option_prefix; deadCodeCsvFileName += csvDeadCodeDeadStoreFileName; ofstream deadCodeCsvFile; deadCodeCsvFile.open(deadCodeCsvFileName.c_str()); if(option_trace) { cout << "TRACE: checking for dead stores." << endl; } // Iteratate over all CFG nodes/ labels: for(Flow::const_node_iterator labIter = lvAnalysis->getFlow()->nodes_begin(); labIter != lvAnalysis->getFlow()->nodes_end(); ++labIter) { const Label& label = *labIter; // Do not output a function call twice (only the function call return label and not the function call label): if(!lvAnalysis->getLabeler()->isFunctionCallLabel(label)) { /*const*/ SgNode* correspondingNode = lvAnalysis->getLabeler()->getNode(label); ROSE_ASSERT(correspondingNode); if(/*const*/ SgExprStatement* exprStmt = isSgExprStatement(correspondingNode)) { correspondingNode = exprStmt->get_expression(); } /*const*/ SgNode* association = 0; // Check if the corresponding node is an assignment or an initialization: if(isSgAssignOp(correspondingNode)) { association = correspondingNode; } else if(SgVariableDeclaration* varDecl = isSgVariableDeclaration(correspondingNode)) { SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDecl); ROSE_ASSERT(initName); // Check whether there is an initialization that can be eliminated (reference initialization can not be eliminated). if(!SgNodeHelper::isReferenceType(initName->get_type()) && initName->get_initializer()) { association = correspondingNode; } } if(association) { if(option_trace) { cout << endl << "association: " << association->unparseToString() << endl; } VariableIdSet assignedVars = AnalysisAbstractionLayer::defVariables(association, *lvAnalysis->getVariableIdMapping(), fipa); /*const*/ LVLattice& liveVarsLattice = *static_cast<LVLattice*>(lvAnalysis->getPreInfo(label.getId())); if(option_trace) { cout << "live: " << liveVarsLattice.toString(lvAnalysis->getVariableIdMapping()) << endl; cout << "assigned: " << endl; } bool minOneIsLive = false; for(VariableIdSet::const_iterator assignedVarIter = assignedVars.begin(); assignedVarIter != assignedVars.end(); ++assignedVarIter) { if(option_trace) { cout << (*assignedVarIter).toString(*lvAnalysis->getVariableIdMapping()) << endl; } if(liveVarsLattice.exists(*assignedVarIter)) { minOneIsLive = true; break; } } if(!minOneIsLive) { if(option_trace) { cout << "association is dead." << endl; } // assignment to only dead variables found: deadCodeCsvFile << correspondingNode->get_file_info()->get_line() << "," << SPRAY::replace_string(correspondingNode->unparseToString(), ",", "/*comma*/") << endl; } } } } deadCodeCsvFile.close(); } delete lvAnalysis; } if(option_rd_analysis) { cout << "STATUS: creating RD analyzer."<<endl; SPRAY::RDAnalysis* rdAnalysis=new SPRAY::RDAnalysis(); cout << "STATUS: initializing RD analyzer."<<endl; rdAnalysis->setNoTopologicalSort(option_no_topological_sort); rdAnalysis->initialize(root); cout << "STATUS: initializing RD transfer functions."<<endl; rdAnalysis->initializeTransferFunctions(); cout << "STATUS: initializing RD global variables."<<endl; rdAnalysis->initializeGlobalVariables(root); cout << "generating icfg_forward.dot."<<endl; write_file("icfg_forward.dot", rdAnalysis->getFlow()->toDot(rdAnalysis->getLabeler())); std::string funtofind="main"; RoseAst completeast(root); SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind); rdAnalysis->determineExtremalLabels(startFunRoot); rdAnalysis->run(); cout << "INFO: attaching RD-data to AST."<<endl; rdAnalysis->attachInInfoToAst("rd-analysis-in"); rdAnalysis->attachOutInfoToAst("rd-analysis-out"); //printAttributes<RDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"rd-analysis-in"); cout << "INFO: annotating analysis results as comments."<<endl; ROSE_ASSERT(rdAnalysis->getVariableIdMapping()); #if 0 AstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping()); ara.annotateAstAttributesAsCommentsBeforeStatements(root, "rd-analysis-in"); ara.annotateAstAttributesAsCommentsAfterStatements(root, "rd-analysis-out"); #else AnalysisAstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping()); ara.annotateAnalysisPrePostInfoAsComments(root,"rd-analysis",rdAnalysis); #endif #if 0 cout << "INFO: substituting uses with rhs of defs."<<endl; substituteUsesWithAvailableExpRhsOfDef("ud-analysis", root, rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping()); #endif if(option_ud_analysis) { ROSE_ASSERT(option_rd_analysis); cout << "INFO: generating and attaching UD-data to AST."<<endl; createUDAstAttributeFromRDAttribute(rdAnalysis->getLabeler(),"rd-analysis-in", "ud-analysis"); Flow* flow=rdAnalysis->getFlow(); cout<<"Flow label-set size: "<<flow->nodeLabels().size()<<endl; CFAnalysis* cfAnalyzer0=rdAnalysis->getCFAnalyzer(); int red=cfAnalyzer0->reduceBlockBeginNodes(*flow); cout<<"INFO: eliminated "<<red<<" block-begin nodes in ICFG."<<endl; #if 0 cout << "INFO: computing program statistics."<<endl; ProgramStatistics ps(rdAnalysis->getVariableIdMapping(), rdAnalysis->getLabeler(), rdAnalysis->getFlow(), "ud-analysis"); ps.computeStatistics(); //ps.printStatistics(); cout << "INFO: generating resource usage visualization."<<endl; ps.setGenerateWithSource(false); ps.generateResourceUsageICFGDotFile("resourceusageicfg.dot"); flow->resetDotOptions(); #endif cout << "INFO: generating visualization data."<<endl; // generate ICFG visualization cout << "generating icfg.dot."<<endl; write_file("icfg.dot", flow->toDot(rdAnalysis->getLabeler())); // cout << "INFO: generating control dependence graph."<<endl; //Flow cdg=rdAnalysis->getCFAnalyzer()->controlDependenceGraph(*flow); cout << "generating datadependencegraph.dot."<<endl; DataDependenceVisualizer ddvis0(rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping(), "ud-analysis"); //printAttributes<UDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"ud-analysis"); //ddvis._showSourceCode=false; // for large programs ddvis0.generateDefUseDotGraph(root,"datadependencegraph.dot"); flow->resetDotOptions(); cout << "generating icfgdatadependencegraph.dot."<<endl; DataDependenceVisualizer ddvis1(rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping(), "ud-analysis"); ddvis1.includeFlowGraphEdges(flow); ddvis1.generateDefUseDotGraph(root,"icfgdatadependencegraph.dot"); flow->resetDotOptions(); cout << "generating icfgdatadependencegraph_clustered.dot."<<endl; DataDependenceVisualizer ddvis2(rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping(), "ud-analysis"); ddvis2.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfgdatadependencegraph_clustered.dot",true); cout << "generating icfg_clustered.dot."<<endl; DataDependenceVisualizer ddvis3(rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping(), "ud-analysis"); ddvis3.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfg_clustered.dot",false); } } }
void SPRAY::IntervalPropertyState::topifyVariableSet(VariableIdSet varIdSet) { for(VariableIdSet::iterator i=varIdSet.begin();i!=varIdSet.end();++i) { intervals[*i]=SPRAY::NumberIntervalLattice::top(); } }