示例#1
0
int Specialization::substituteConstArrayIndexExprsWithConst(VariableIdMapping* variableIdMapping, ExprAnalyzer* exprAnalyzer, const EState* estate, SgNode* root) {
  typedef pair<SgExpression*,int> SubstitutionPair;
  typedef list<SubstitutionPair > SubstitutionList;
  SubstitutionList substitutionList;
  AstMatching m;
  MatchResult res;
  int numConstExprElim=0;
#pragma omp critical(EXPRSUBSTITUTION)
  {
    res=m.performMatching("SgPntrArrRefExp(_,$ArrayIndexExpr)",root);
  }
  if(res.size()>0) {
     for(MatchResult::iterator i=res.begin();i!=res.end();++i) {
         // match found
       SgExpression* arrayIndexExpr=isSgExpression((*i)["$ArrayIndexExpr"]);
       if(arrayIndexExpr) {
         // avoid substituting a constant by a constant
         if(!isSgIntVal(arrayIndexExpr)) {
           list<SingleEvalResultConstInt> evalResultList=exprAnalyzer->evalConstInt(arrayIndexExpr,*estate,true, true);
           // only when we get exactly one result it is considered for substitution
           // there can be multiple const-results which do not allow to replace it with a single const
           if(evalResultList.size()==1) {
             list<SingleEvalResultConstInt>::iterator i=evalResultList.begin();
             ROSE_ASSERT(evalResultList.size()==1);
             AValue varVal=(*i).value();
             if(varVal.isConstInt()) {
               int varIntValue=varVal.getIntValue();
               //cout<<"INFO: const: "<<varIntValue<<" substituting: "<<arrayIndexExpr->unparseToString()<<endl;
               SgNodeHelper::replaceExpression(arrayIndexExpr,SageBuilder::buildIntVal(varIntValue),false);
               numConstExprElim++;
             }
           }
         }
       }
     }
   }
   return numConstExprElim;
 }
示例#2
0
void Specialization::transformArrayProgram(SgProject* root, Analyzer* analyzer) {
  // 1) transform initializers of global variables : a[]={1,2,3} ==> int a_0=1;int a_1=2;int a_2=3;
  // 2) eliminate initializers of pointer variables: int p* = a; ==> \eps
  // 3) replace uses of p[k]: with a_k (where k is a constant)

  //ad 1 and 2)
  VariableIdMapping* variableIdMapping=analyzer->getVariableIdMapping();
  Analyzer::VariableDeclarationList usedGlobalVariableDeclarationList=analyzer->computeUsedGlobalVariableDeclarationList(root);
  cout<<"STATUS: number of used global variables: "<<usedGlobalVariableDeclarationList.size()<<endl;
  list<pair<SgNode*,string> > toReplaceArrayInitializations;
  list<SgVariableDeclaration*> toDeleteDeclarations;
  typedef map<VariableId,VariableId> ArrayPointerMapType;
  ArrayPointerMapType arrayPointer; // var,arrayName
  for(Analyzer::VariableDeclarationList::iterator i=usedGlobalVariableDeclarationList.begin();
      i!=usedGlobalVariableDeclarationList.end();
      ++i) {
    SgVariableDeclaration* decl=*i;
    //cout<<"DEBUG: variableDeclaration:"<<decl->unparseToString()<<endl;
    SgNode* initName0=decl->get_traversalSuccessorByIndex(1); // get-InitializedName
    ROSE_ASSERT(initName0);
    if(SgInitializedName* initName=isSgInitializedName(initName0)) {
      // array initializer
      SgInitializer* arrayInitializer=initName->get_initializer();
      //string arrayName=variableIdMapping->variableName(variableIdMapping->variableId(*i));
      if(isSgAggregateInitializer(arrayInitializer)) {
        string transformedArrayInitializer=flattenArrayInitializer(decl,variableIdMapping);
        toReplaceArrayInitializations.push_back(make_pair(decl,transformedArrayInitializer));
        //SgNodeHelper::replaceAstWithString(decl,transformedArrayInitializer);
      } else {
        //cout<<"initName:"<<astTermWithNullValuesToString(initName)<<endl;
        VariableId lhsVarId=variableIdMapping->variableId(*i);
        string lhsVariableName=variableIdMapping->variableName(lhsVarId);
        SgType* type=variableIdMapping->getType(variableIdMapping->variableId(*i));
        // match: SgInitializedName(SgAssignInitializer(SgVarRefExp))
        // variable on lhs
        // check if variable is a pointer variable
        if(isSgPointerType(type)) {
          AstMatching m;
          MatchResult res;
          res=m.performMatching("SgInitializedName(SgAssignInitializer($varRef=SgVarRefExp))|SgInitializedName(SgAssignInitializer(SgAddressOfOp($varRef=SgVarRefExp)))",initName);
          if(res.size()==1) {
            toDeleteDeclarations.push_back(decl);
            MatchResult::iterator j=res.begin();
            SgVarRefExp* rhsVarRef=isSgVarRefExp((*j)["$varRef"]);
            VariableId rhsVarId=variableIdMapping->variableId(rhsVarRef);
            arrayPointer[lhsVarId]=rhsVarId;
            //cout<<"Inserted pair "<<variableName<<":"<<rhsVarName<<endl;
          }
        }
      }
    }
  }

  typedef list<pair<SgPntrArrRefExp*,ArrayElementAccessData> > ArrayAccessInfoType;
  ArrayAccessInfoType arrayAccesses;
  RoseAst ast(root);
  for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
    SgExpression* exp=isSgExpression(*i);
    if(exp) {
      if(SgPntrArrRefExp* arrAccess=isSgPntrArrRefExp(exp)) {
        ArrayElementAccessData aead(arrAccess,analyzer->getVariableIdMapping());
        ROSE_ASSERT(aead.isValid());
        //VariableId arrayVar=aead.varId;
        //cout<<"array-element: "<<variableIdMapping->variableName(arrayVar);
        if(aead.subscripts.size()==1) {
          //cout<<" ArrayIndex:"<<*aead.subscripts.begin();
          arrayAccesses.push_back(make_pair(arrAccess,aead));
        } else {
          cout<<"Error: ArrayIndex: unknown (dimension>1)";
          exit(1);
        }          
      }
    }
  }
#if 0
  cout<<"Array-Pointer Map:"<<endl;
  for(ArrayPointerMapType::iterator i=arrayPointer.begin();i!=arrayPointer.end();++i) {
    cout<<(*i).first.toString()<<":"<<(*i).second.toString()<<endl;
  }
#endif
  cout<<"STATUS: Replacing array-initializations."<<endl;
  for(list<pair<SgNode*,string> >::iterator i=toReplaceArrayInitializations.begin();i!=toReplaceArrayInitializations.end();++i) {
    //cout<<(*i).first->unparseToString()<<":\n"<<(*i).second<<endl;
    SgNodeHelper::replaceAstWithString((*i).first,"\n"+(*i).second);
  }
  cout<<"STATUS: Transforming pointer declarations."<<endl;
  for(list<SgVariableDeclaration*>::iterator i=toDeleteDeclarations.begin();i!=toDeleteDeclarations.end();++i) {
    //cout<<(*i)->unparseToString()<<endl;
    VariableId declaredPointerVar=variableIdMapping->variableId(*i);
    SgNode* initName0=(*i)->get_traversalSuccessorByIndex(1); // get-InitializedName
    ROSE_ASSERT(initName0);
    if(SgInitializedName* initName=isSgInitializedName(initName0)) {
      // initializer
      SgInitializer* initializer=initName->get_initializer();
      if(SgAssignInitializer* assignInitializer=isSgAssignInitializer(initializer)) {
        //cout<<"var-initializer:"<<initializer->unparseToString()<<astTermWithNullValuesToString(initializer)<<endl;
        SgExpression* assignInitOperand=assignInitializer->get_operand_i();
        if(isSgAddressOfOp(assignInitOperand)) {
          assignInitOperand=isSgExpression(SgNodeHelper::getFirstChild(assignInitOperand));
          ROSE_ASSERT(assignInitOperand);
        }
        if(SgVarRefExp* rhsInitVar=isSgVarRefExp(assignInitOperand)) {
          VariableId arrayVar=variableIdMapping->variableId(rhsInitVar);
          SgExpressionPtrList& arrayInitializerList=variableIdMapping->getInitializerListOfArrayVariable(arrayVar);
          //cout<<"DEBUG: rhs array:"<<arrayInitializerList.size()<<" elements"<<endl;
          int num=0;
          stringstream ss;
          for(SgExpressionPtrList::iterator j=arrayInitializerList.begin();j!=arrayInitializerList.end();++j) {
            ss<<"int "<<variableIdMapping->variableName(declaredPointerVar)<<"_"<<num<<" = "
              <<(*j)->unparseToString()
              <<";\n"
              ;
            num++;
          }
          SgNodeHelper::replaceAstWithString(*i,"\n"+ss.str());
        }
      }
    }
#if 0
    ArrayElementAccessData arrayAccess=
    ROSE_ASSERT(arrayAccess.getDimensions()==1);
    VariableId accessVar=arrayAccess.getVariable();
    int accessSubscript=arrayAccess.getSubscript(0);
#endif
    //SageInterface::removeStatement(*i);
    
    //SgNodeHelper::replaceAstWithString((*i),"POINTER-INIT-ARRAY:"+(*i)->unparseToString()+"...;");
  }
  
  //list<pair<SgPntrArrRefExp*,ArrayElementAccessData> > 
  cout<<"STATUS: Replacing Expressions ... ";
  for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
    if(isSgAssignOp(*i)) {
      if(SgVarRefExp* lhsVar=isSgVarRefExp(SgNodeHelper::getLhs(*i))) {
        if(SgNodeHelper::isPointerVariable(lhsVar)) {
          //cout<<"DEBUG: pointer var on lhs :"<<(*i)->unparseToString()<<endl;

          SgExpression* rhsExp=isSgExpression(SgNodeHelper::getRhs(*i));
          ROSE_ASSERT(rhsExp);
          if(isSgAddressOfOp(rhsExp)) {
            rhsExp=isSgExpression(SgNodeHelper::getFirstChild(rhsExp));
            ROSE_ASSERT(rhsExp);
          }
          if(SgVarRefExp* rhsVar=isSgVarRefExp(rhsExp)) {
            VariableId lhsVarId=variableIdMapping->variableId(lhsVar);
            VariableId rhsVarId=variableIdMapping->variableId(rhsVar);
            SgExpressionPtrList& arrayInitializerList=variableIdMapping->getInitializerListOfArrayVariable(rhsVarId);
            //cout<<"DEBUG: rhs array:"<<arrayInitializerList.size()<<" elements"<<endl;
            int num=0;
            stringstream ss;
            for(SgExpressionPtrList::iterator j=arrayInitializerList.begin();j!=arrayInitializerList.end();++j) {
              ss<<variableIdMapping->variableName(lhsVarId)<<"_"<<num<<" = "
                <<(*j)->unparseToString();

              // workaround for the fact that the ROSE unparser generates a "\n;" for a replaced assignment
              {
                SgExpressionPtrList::iterator j2=j;
                j2++;
                if(j2!=arrayInitializerList.end())
                  ss<<";\n";
              }

              num++;
            }
            SgNodeHelper::replaceAstWithString(*i,ss.str());
            //SgNodeHelper::replaceAstWithString(*i,"COPY-ARRAY("+lhsVar->unparseToString()+"<="+rhsVar->unparseToString()+")");
          }
        } else {
          RoseAst subAst(*i);
          for(RoseAst::iterator j=subAst.begin();j!=subAst.end();++j) {
            if(SgNodeHelper::isArrayAccess(*j)) {
              //cout<<"DEBUG: arrays access on rhs of assignment :"<<(*i)->unparseToString()<<endl;
              transformArrayAccess(*j,analyzer->getVariableIdMapping());
            }
          }
        }
      }
    }
    if(SgNodeHelper::isCond(*i)) {
      RoseAst subAst(*i);
      for(RoseAst::iterator j=subAst.begin();j!=subAst.end();++j) {
        if(SgNodeHelper::isArrayAccess(*j)) {
          transformArrayAccess(*j,analyzer->getVariableIdMapping());
        }
      }
    }
  }
  cout<<" done."<<endl;
#if 0
  for(ArrayAccessInfoType::iterator i=arrayAccesses.begin();i!=arrayAccesses.end();++i) {
    //cout<<(*i).first->unparseToString()<<":"/*<<(*i).second.xxxx*/<<endl;
    ArrayElementAccessData arrayAccess=(*i).second;
    ROSE_ASSERT(arrayAccess.getDimensions()==1);
    VariableId accessVar=arrayAccess.getVariable();
    int accessSubscript=arrayAccess.getSubscript(0);
    // expression is now: VariableId[subscript]
    // information available is: arrayPointer map: VariableId:pointer -> VariableId:array
    // pointerArray

    // if the variable is not a pointer var it will now be added to the stl-map but with
    // a default VariableId. Default variableIds are not valid() IDs.
    // therefor this becomes a cheap check, whether we need to replace the expression or not.
    VariableId mappedVar=arrayPointer[accessVar];
    if(mappedVar.isValid()) {
      // need to replace
      stringstream newAccess;
#if 0
      newAccess<<variableIdMapping->variableName(mappedVar)<<"["<<accessSubscript<<"]";
#else
      newAccess<<variableIdMapping->variableName(accessVar)<<"_"<<accessSubscript<<" ";
#endif
      cout<<"to replace: @"<<(*i).first<<":"<<(*i).first->unparseToString()<<" ==> "<<newAccess.str()<<endl;
      SgNodeHelper::replaceAstWithString((*i).first,newAccess.str());
    }
  }
#endif
  Analyzer::VariableDeclarationList unusedGlobalVariableDeclarationList=analyzer->computeUnusedGlobalVariableDeclarationList(root);
  cout<<"STATUS: deleting unused global variables."<<endl;
  for(Analyzer::VariableDeclarationList::iterator i=unusedGlobalVariableDeclarationList.begin();
      i!=unusedGlobalVariableDeclarationList.end();
      ++i) {
    SgVariableDeclaration* decl=*i;
    SageInterface::removeStatement(decl);
  }
      
}