Exemplo n.º 1
0
void StaticConstructorTraversal::visit(SgNode *n) {

  // Get declared variables
  SgInitializedName *vName = isSgInitializedName(n);

  if (vName && !isAcreIgnore(vName->get_declaration())) {
    Sg_File_Info *fInfo = vName->get_file_info();
    SgScopeStatement *scope = vName->get_scope();
    
    // Find global variables (variables in namespaces count, e.g. std)
    if (!fInfo->isCompilerGenerated() && (isSgGlobal(scope) || isSgNamespaceDefinitionStatement(scope))) {

      // Walk typedefs until reach pointer to base type  
      SgTypedefType *tdType = isSgTypedefType(vName->get_type());
      while (tdType && isSgTypedefType(tdType->get_base_type())) 
        tdType = isSgTypedefType(tdType->get_base_type());
      
      // Determine if type is a class (i.e. type with a constructor)
      SgClassType *cType = isSgClassType(vName->get_type());
      if (tdType)
        cType = isSgClassType(tdType->get_base_type());
      
      // Output location of globals with a static constructor
      if (cType) {
        *out << "Static Constructor Violation: " << fInfo->get_filename() << " @ " << fInfo->get_line() << "\n";
      }
    }
  }
}
Exemplo n.º 2
0
SgExpression* SSA_UnfilteredCfg::buildVariableReference(const VarName& var, SgScopeStatement* scope)
{
    ROSE_ASSERT(var.size() > 0);

    SgExpression* varsSoFar = SageBuilder::buildVarRefExp(var.front(), scope);

    for (size_t i = 0; i < var.size(); i++)
    {
        SgInitializedName* initName = var[i];
        if (initName == var.back())
        {
            break;
        }

        SgVarRefExp* nextVar = SageBuilder::buildVarRefExp(var[i + 1], scope);

        if (SageInterface::isPointerType(initName->get_type()))
        {
            varsSoFar = SageBuilder::buildArrowExp(varsSoFar, nextVar);
        }
        else
        {
            varsSoFar = SageBuilder::buildDotExp(varsSoFar, nextVar);
        }
    }

    return varsSoFar;
}
InheritedAttribute
BugSeeding::evaluateInheritedAttribute (
     SgNode* astNode,
     InheritedAttribute inheritedAttribute )
   {
  // Use this if we only want to seed bugs in loops
     bool isLoop = inheritedAttribute.isLoop           ||
                   (isSgForStatement(astNode) != NULL) ||
                   (isSgWhileStmt(astNode) != NULL)    ||
                   (isSgDoWhileStmt(astNode) != NULL);
  // Add Fortran support
     isLoop = isLoop || (isSgFortranDo(astNode) != NULL);

  // Mark future noes in this subtree as being part of a loop
     inheritedAttribute.isLoop = isLoop;

  // To test this on simple codes, optionally allow it to be applied everywhere
     bool applyEveryWhere = true;

     if (isLoop == true || applyEveryWhere == true)
        {
       // The inherited attribute is true iff we are inside a loop and this is a SgPntrArrRefExp.
          SgPntrArrRefExp *arrayReference = isSgPntrArrRefExp(astNode);
          if (arrayReference != NULL)
             {
            // Mark as a vulnerability
               inheritedAttribute.isVulnerability = true;

            // Now change the array index (to seed the buffer overflow bug)
               SgVarRefExp* arrayVarRef = isSgVarRefExp(arrayReference->get_lhs_operand());
               ROSE_ASSERT(arrayVarRef != NULL);
               ROSE_ASSERT(arrayVarRef->get_symbol() != NULL);
               SgInitializedName* arrayName = isSgInitializedName(arrayVarRef->get_symbol()->get_declaration());
               ROSE_ASSERT(arrayName != NULL);
               SgArrayType* arrayType = isSgArrayType(arrayName->get_type());
               ROSE_ASSERT(arrayType != NULL);
               SgExpression* arraySize = arrayType->get_index();

               SgTreeCopy copyHelp;
            // Make a copy of the expression used to hold the array size in the array declaration.
               SgExpression* arraySizeCopy = isSgExpression(arraySize->copy(copyHelp));
               ROSE_ASSERT(arraySizeCopy != NULL);

            // This is the existing index expression
               SgExpression* indexExpression = arrayReference->get_rhs_operand();
               ROSE_ASSERT(indexExpression != NULL);

            // Build a new expression: "array[n]" --> "array[n+arraySizeCopy]", where the arraySizeCopy is a size of "array"
               SgExpression* newIndexExpression = buildAddOp(indexExpression,arraySizeCopy);

            // Substitute the new expression for the old expression
               arrayReference->set_rhs_operand(newIndexExpression);
             }
        }

     return inheritedAttribute;
   }
Exemplo n.º 4
0
int main(int argc, char** argv) {

   SgProject* proj = frontend(argc, argv);

  // Set up the struct layout chain
  initUpcSizes(); 
  CustomizedPrimitiveTypeLayoutGenerator gen1_upc(NULL,&upc_sizes);
  NonpackedTypeLayoutGenerator gen_upc(&gen1_upc);

  // Process every type used in a variable or parameter declaration
  vector<SgNode*> initNames = NodeQuery::querySubTree(proj, V_SgInitializedName);
  for (size_t i = 0; i < initNames.size(); ++i) {
    SgInitializedName* in = isSgInitializedName(initNames[i]);
    SgType* t = in->get_type();
    if (isSgTypeEllipse(t)) continue;
    cout << in->get_name().getString() << " has type " << t->unparseToString() << ":\n";
    cout << "For a customized UPC platform:\n";
    cout << gen_upc.layoutType(t) << "\n";
    size_t size = gen_upc.layoutType(t).size;
    size_t element_size=size;
    if (isSgArrayType(t)) 
      element_size = gen_upc.layoutType(
                SageInterface::getArrayElementType(isSgArrayType(t))).size;

#if 0
    if (isSgArrayType(t))
    {
      cout<<"Found an array, output its element type info."<<endl;
      cout<< gen_upc.layoutType(SageInterface::getArrayElementType(isSgArrayType(t)))<<endl;
      // Array of shared UPC elements

    }
#endif    
    if (isUpcSharedType(t))
    { 
      size_t block_bytes = SageInterface::getUpcSharedBlockSize(t);
      if (!isSgArrayType(t) || block_bytes == 0)
        { block_bytes = size; }
      else
        {block_bytes = min (block_bytes*element_size, size);}
      size_t num_blocks = (size % block_bytes==0)?(size/block_bytes):size/block_bytes +1;
      int hasThreads=0;
      if (isSgArrayType(t))
        if (isUpcArrayWithThreads(isSgArrayType(t)))
          hasThreads =1;

      cout<<"Found a shared UPC type: block bytes="<<block_bytes
          <<" Number of block="<<num_blocks
          <<" Multiply by THREADS="<<hasThreads
          <<" Element size="<<element_size
          <<endl;
    } // UPC shared types

  } // end for
  return 0;
}
Exemplo n.º 5
0
/** Returns true if the given function declares any local variables that are of a pointer or array type. */
bool LanguageRestrictions::containsDeclarationsOfPointerVariables(SgFunctionDefinition* functionDefinition)
{
    Rose_STL_Container<SgNode*> localDeclarations = NodeQuery::querySubTree(functionDefinition, V_SgInitializedName);
    foreach (SgNode* initNameNode, localDeclarations)
    {
        SgInitializedName* initializedName = isSgInitializedName(initNameNode);
        SgType* varType = initializedName->get_type();

        if (isSgPointerType(varType) || isSgArrayType(varType))
        {
            return true;
        }
    }
Exemplo n.º 6
0
void
CompassAnalyses::StaticConstructorInitialization::Traversal::
visit(SgNode* node)
   { 
  // Test for static initialization of variables of type class, such initializations where they are 
  // static or appear in global scope can be called in an order dependent upon the compiler and this 
  // can lead to subtle bugs in large scale applications.

     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global or namespace variable or an static class member
                 // This might also have to be a test for other scopes as well.
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL || isSgNamespaceDefinitionStatement(scope) != NULL)
                       {
                      // printf ("Found a global variable defining a class = %p \n",initializedName);
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         output->addOutput(new CheckerOutput(initializedName));
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                           // printf ("Found a static data member defining a class = %p \n",initializedName);
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              output->addOutput(new CheckerOutput(initializedName));
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }

   } //End of the visit function.
Exemplo n.º 7
0
 // Only keep desired types
 std::set<SgInitializedName* > filterVariables(const std::set<SgInitializedName* > & input)
 {
   std::set<SgInitializedName* > result; 
   std::set<SgInitializedName*>::iterator it;

   for (it=input.begin(); it!=input.end(); it++)
   {
     SgInitializedName* iname = (*it);
     if (isSgArrayType (iname->get_type()))
       result.insert(iname);
 //    cout<<scalar_or_array (iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
   }
   return result; 
 }
Exemplo n.º 8
0
void
Traversal::visit(SgNode* node)
   {
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

  // Look for variable declarations appearing in global scope!
  // if (variableDeclaration != NULL && isSgGlobal(variableDeclaration->get_parent()) != NULL)
     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global variable or an static class member
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL)
                       {
                         printf ("Found a global variable defining a class \n");
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         outputPositionInformation(variableDeclaration);
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                              printf ("Found a static data member defining a class \n");
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              outputPositionInformation(variableDeclaration);
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }
   }
void BasicProgmemTransform::transformCharArrayInitialization(SgFunctionDeclaration *func) {
	/* *
	 * Translates statements of the form:
	 * char arr[n] = "some string"; to:
	 * char arr[n];
	 * strcpy_P(arr, <progmem placeholder>);
	 * */
	Rose_STL_Container<SgNode *> initNames = NodeQuery::querySubTree(func, V_SgInitializedName);
	for(auto &item: initNames) {
		SgInitializedName *initName = isSgInitializedName(item);
		if(initName->get_initializer() == NULL) {
			continue;
		}
		SgVariableDeclaration * varDecl = isSgVariableDeclaration(initName->get_declaration());
		if(varDecl == NULL) {
			continue;
		}
		SgAssignInitializer *assignInit = isSgAssignInitializer(initName->get_initializer());
		if(assignInit == NULL) {
			continue;
		}
		SgType *type = initName->get_type();
		SgType *eleType = SageInterface::getElementType(type);
		if(isSgArrayType(type) && eleType != NULL && isSgTypeChar(eleType)) {
			SgStringVal* strVal = isSgStringVal(assignInit->get_operand());
			std::string str = strVal->get_value();
			int arrSize = getDeclaredArraySize(isSgArrayType(type));
			if(arrSize == 0) {
				//char arr[] = "something";
				int size = str.length() + 1;
				SgArrayType *type = SageBuilder::buildArrayType(SageBuilder::buildCharType(), SageBuilder::buildIntVal(size));
				initName->set_type(type);
			}
			varDecl->reset_initializer(NULL);
			SgVariableDeclaration *placeholder = getVariableDeclPlaceholderForString(str);
			SgVarRefExp *ref = SageBuilder::buildVarRefExp(placeholder);
			std::stringstream instr;
			instr << "\n strcpy_P(" << initName->get_name().getString();
			instr <<  ", " << ref->get_symbol()->get_name().getString() << ");\n";
			SageInterface::attachComment(varDecl, instr.str(), PreprocessingInfo::after);
			printf("transformed %s\n", initName->unparseToString().c_str());
		}

	}
}
Exemplo n.º 10
0
    virtual void visit(SgNode* n) {
        if (isSgVarRefExp(n)) {
            SgVarRefExp* copy_vr = isSgVarRefExp(n);
            assert (copy_vr->get_symbol());
            SgInitializedName* copy = copy_vr->get_symbol()->get_declaration();
            assert (copy);
            if (!SageInterface::isReferenceType(copy->get_type()))
                return; // Fail if non-reference

            SgInitializer* copyinit = copy->get_initializer();
            SgNode* copyscope_ =
                copy->get_parent()->get_parent();
            while (!isSgScopeStatement(copyscope_))
                copyscope_ = copyscope_->get_parent();
            // cout << "copyscope is a " << copyscope_->sage_class_name() << endl;
            // SgScopeStatement* copyscope = isSgScopeStatement(copyscope_);
            if (isSgAssignInitializer(copyinit)) {
                SgAssignInitializer* init = isSgAssignInitializer(copyinit);
                SgExpression* orig_expr = init->get_operand();
                // cout << "orig is " << orig_expr->unparseToString() << ", copy is " << copy->get_name().str() << endl;
                bool shouldReplace = false;
                if (isSgVarRefExp(orig_expr)) {
                    SgVarRefExp* orig_vr = isSgVarRefExp(orig_expr);
                    // cout << "Found potential copy from " << orig_vr->get_symbol()->get_name().str() << " to " << copy_vr->get_symbol()->get_name().str() << endl;
                    SgInitializedName* orig = orig_vr->get_symbol()->get_declaration();
                    assert (orig);
                    SgNode* origscope = orig->get_parent()->get_parent();
                    assert (origscope);
                    shouldReplace = true;
                }
                if (shouldReplace) {
                    assert (orig_expr);
                    SgExpression* orig_copy =
                        isSgExpression(orig_expr /*->copy(SgTreeCopy()) */);
                    assert (orig_copy);
                    orig_copy->set_parent(copy_vr->get_parent());
                    isSgExpression(copy_vr->get_parent())->
                    replace_expression(copy_vr, orig_copy);
                }
            }
        }
    }
Exemplo n.º 11
0
StructLayoutInfo NonpackedTypeLayoutGenerator::layoutType(SgType* t) const {
  switch (t->variantT()) {
    case V_SgClassType: { // Also covers structs and unions
      SgClassDeclaration* decl = isSgClassDeclaration(isSgClassType(t)->get_declaration());
      ROSE_ASSERT (decl);
      decl = isSgClassDeclaration(decl->get_definingDeclaration());
      ROSE_ASSERT (decl);
      SgClassDefinition* def = decl->get_definition();
      ROSE_ASSERT (def);
      StructLayoutInfo layout;
      size_t currentOffset = 0;
      const SgBaseClassPtrList& bases = def->get_inheritances();
      for (SgBaseClassPtrList::const_iterator i = bases.begin();
           i != bases.end(); ++i) {
        SgBaseClass* base = *i;
        SgClassDeclaration* basecls = base->get_base_class();
        layoutOneField(basecls->get_type(), base, false, currentOffset, layout);
      }
      const SgDeclarationStatementPtrList& body = def->get_members();
      bool isUnion = (decl->get_class_type() == SgClassDeclaration::e_union);
      for (SgDeclarationStatementPtrList::const_iterator i = body.begin();
           i != body.end(); ++i) {
        SgDeclarationStatement* mem = *i;
        SgVariableDeclaration* vardecl = isSgVariableDeclaration(mem);
        SgClassDeclaration* classdecl = isSgClassDeclaration(mem);
        bool isUnnamedUnion = classdecl ? classdecl->get_isUnNamed() : false;
        if (vardecl) {
          if (!vardecl->get_declarationModifier().isDefault()) continue; // Static fields and friends
          ROSE_ASSERT (!vardecl->get_bitfield());
          const SgInitializedNamePtrList& vars = isSgVariableDeclaration(mem)->get_variables();
          for (SgInitializedNamePtrList::const_iterator j = vars.begin();
               j != vars.end(); ++j) {
            SgInitializedName* var = *j;
            layoutOneField(var->get_type(), var, isUnion, currentOffset, layout);
          }
        } else if (isUnnamedUnion) {
          layoutOneField(classdecl->get_type(), classdecl, isUnion, currentOffset, layout);
        } // else continue;
      }
      if (layout.alignment != 0 && layout.size % layout.alignment != 0) {
        size_t paddingNeeded = layout.alignment - (layout.size % layout.alignment);
        if (!isUnion) {
          layout.fields.push_back(StructLayoutEntry(NULL, layout.size, paddingNeeded));
        }
        layout.size += paddingNeeded;
      }
      return layout;
    }
    case V_SgArrayType: {
      StructLayoutInfo layout = this->beginning->layoutType(isSgArrayType(t)->get_base_type());
      layout.fields.clear();
      SgExpression* numElements = isSgArrayType(t)->get_index();

      //Adjustment for UPC array like a[100*THREADS],treat it as a[100]
      // Liao, 8/7/2008
      if (isUpcArrayWithThreads(isSgArrayType(t)))
      {
        SgMultiplyOp* multiply = isSgMultiplyOp(isSgArrayType(t)->get_index());
        ROSE_ASSERT(multiply);

     // DQ (9/26/2011): Do constant folding if required.
     // SageInterface::constantFolding(multiply);

        numElements = multiply->get_lhs_operand();
      }  
      if (!isSgValueExp(numElements)) {
        cerr << "Error: trying to compute static size of an array with non-constant size" << endl;
        abort();
      }
      layout.size *= SageInterface::getIntegerConstantValue(isSgValueExp(numElements));
      return layout;
    }
    case V_SgTypeComplex: {
    //"Each complex type has the same representation and alignment requirements as 
    //an array type containing exactly two elements of the corresponding real type"
      StructLayoutInfo layout = this->beginning->layoutType(isSgTypeComplex(t)->get_base_type());
      layout.size *= 2;
      return layout;
    }
    case V_SgTypeImaginary: {
      StructLayoutInfo layout = this->beginning->layoutType(isSgTypeImaginary(t)->get_base_type());
      return layout;
    }

    default: return ChainableTypeLayoutGenerator::layoutType(t);
  }
}
Exemplo n.º 12
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
   {
#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     SgGlobal* globalScope = TransformationSupport::getGlobalScope(funcall);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

     SgExpression* funname = funcall->get_function();
     SgExpression* funname2 = isSgFunctionRefExp(funname);
     SgDotExp* dotexp = isSgDotExp(funname);
     SgArrowExp* arrowexp = isSgArrowExp(funname);
     SgExpression* thisptr = 0;
     if (dotexp || arrowexp)
        {
          funname2 = isSgBinaryOp(funname)->get_rhs_operand();
          if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
              SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
              ROSE_ASSERT (isSgInitializer(ai->get_operand()));
#if 1
              printf ("ai = %p ai->isTransformation() = %s \n",ai,ai->isTransformation() ? "true" : "false");
#endif
              SgInitializedName* in = isSgInitializedName(ai->get_parent());
              ROSE_ASSERT (in);
              removeRedundantCopyInConstruction(in);
              lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
          } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
          } else {
            assert (false);
          }
        }

     if (!funname2)
        {
       // std::cout << "Inline failed: not a call to a named function" << std::endl;
          return false; // Probably a call through a fun ptr
        }

     SgFunctionSymbol* funsym = 0;
     if (isSgFunctionRefExp(funname2))
          funsym = isSgFunctionRefExp(funname2)->get_symbol();
       else
          if (isSgMemberFunctionRefExp(funname2))
               funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
            else
               assert (false);

     assert (funsym);
     if (isSgMemberFunctionSymbol(funsym) &&
         isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
        {
       // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
          return false;
        }

     SgFunctionDeclaration* fundecl = funsym->get_declaration();
     fundecl = fundecl ? isSgFunctionDeclaration(fundecl->get_definingDeclaration()) : NULL;

     SgFunctionDefinition* fundef = fundecl ? fundecl->get_definition() : NULL;
     if (!fundef)
        {
       // std::cout << "Inline failed: no definition is visible" << std::endl;
          return false; // No definition of the function is visible
        }
     if (!allowRecursion)
        {
          SgNode* my_fundef = funcall;
          while (my_fundef && !isSgFunctionDefinition(my_fundef))
             {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
               my_fundef = my_fundef->get_parent();
               ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
             }
       // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
          assert (isSgFunctionDefinition(my_fundef));
          if (isSgFunctionDefinition(my_fundef) == fundef)
             {
               std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
               return false;
             }
        }

     SgVariableDeclaration* thisdecl = 0;
     SgName thisname("this__");
     thisname << ++gensym_counter;
     SgInitializedName* thisinitname = 0;
     if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
        {
          assert (thisptr != NULL);
          SgType* thisptrtype = thisptr->get_type();
          const SgSpecialFunctionModifier& specialMod = 
            funsym->get_declaration()->get_specialFunctionModifier();
          if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
          }
          SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
       // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
          thisptrtype = new SgModifierType(thisptrtype);
          isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
       // }
       // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
          SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
          assignInitializer->set_endOfConstruct(SgNULL_FILE);
#if 1
          printf ("before new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
#if 1
          printf ("(after new SgVariableDeclaration(): assignInitializer = %p assignInitializer->isTransformation() = %s \n",assignInitializer,assignInitializer->isTransformation() ? "true" : "false");
#endif
          thisdecl->set_endOfConstruct(SgNULL_FILE);
          thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
          thisdecl->set_definingDeclaration(thisdecl);

          thisinitname = (thisdecl->get_variables()).back();
          //thisinitname = lastElementOfContainer(thisdecl->get_variables());
          // thisinitname->set_endOfConstruct(SgNULL_FILE);
          assignInitializer->set_parent(thisinitname);
          markAsTransformation(assignInitializer);

       // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

       // DQ (6/23/2006): New test
          ROSE_ASSERT(assignInitializer->get_parent() != NULL);
        }

     // Get the list of actual argument expressions from the function call, which we'll later use to initialize new local
     // variables in the inlined code.  We need to detach the actual arguments from the AST here since we'll be reattaching
     // them below (otherwise we would violate the invariant that the AST is a tree).
     SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);
     SgExpressionPtrList funargs = funcall->get_args()->get_expressions();
     funcall->get_args()->get_expressions().clear();
     BOOST_FOREACH (SgExpression *actual, funargs)
         actual->set_parent(NULL);

     // Make a copy of the to-be-inlined function so we're not modifying and (re)inserting the original.
     SgBasicBlock* funbody_raw = fundef->get_body();
     SgInitializedNamePtrList& params = fundecl->get_args();
     std::vector<SgInitializedName*> inits;
     SgTreeCopy tc;
     SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
     ROSE_ASSERT (function_copy);
     SgBasicBlock* funbody_copy = function_copy->get_body();

     renameLabels(funbody_copy, targetFunction);
     ASSERT_require(funbody_raw->get_symbol_table()->size() == funbody_copy->get_symbol_table()->size());

     // We don't need to keep the copied SgFunctionDefinition now that the labels in it have been moved to the target function
     // (having it in the memory pool confuses the AST tests), but we must not delete the formal argument list or the body
     // because we need them below.
     if (function_copy->get_declaration()) {
         ASSERT_require(function_copy->get_declaration()->get_parent() == function_copy);
         function_copy->get_declaration()->set_parent(NULL);
         function_copy->set_declaration(NULL);
     }
     if (function_copy->get_body()) {
         ASSERT_require(function_copy->get_body()->get_parent() == function_copy);
         function_copy->get_body()->set_parent(NULL);
         function_copy->set_body(NULL);
     }
     delete function_copy;
     function_copy = NULL;
#if 0
     SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
     pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaBegin->set_parent(pragmaBeginDecl);
     pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
     funbody_copy->prepend_statement(pragmaBeginDecl);
     pragmaBeginDecl->set_parent(funbody_copy);
#endif

     // In the to-be-inserted function body, create new local variables with distinct non-conflicting names, one per formal
     // argument and having the same type as the formal argument. Initialize those new local variables with the actual
     // arguments.  Also, build a paramMap that maps each formal argument (SgInitializedName) to its corresponding new local
     // variable (SgVariableSymbol).
     ReplaceParameterUseVisitor::paramMapType paramMap;
     SgInitializedNamePtrList::iterator formalIter = params.begin();
     SgExpressionPtrList::iterator actualIter = funargs.begin();
     for (size_t argNumber=0;
          formalIter != params.end() && actualIter != funargs.end();
          ++argNumber, ++formalIter, ++actualIter) {
         SgInitializedName *formalArg = *formalIter;
         SgExpression *actualArg = *actualIter;

         // Build the new local variable.
         // FIXME[Robb P. Matzke 2014-12-12]: we need a better way to generate a non-conflicting local variable name
         SgAssignInitializer* initializer = new SgAssignInitializer(SgNULL_FILE, actualArg, formalArg->get_type());
         ASSERT_not_null(initializer);
         initializer->set_endOfConstruct(SgNULL_FILE);
#if 1
         printf ("initializer = %p initializer->isTransformation() = %s \n",initializer,initializer->isTransformation() ? "true" : "false");
#endif
         SgName shadow_name(formalArg->get_name());
         shadow_name << "__" << ++gensym_counter;
         SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE, shadow_name, formalArg->get_type(), initializer);
         vardecl->set_definingDeclaration(vardecl);
         vardecl->set_endOfConstruct(SgNULL_FILE);
         vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
         vardecl->set_parent(funbody_copy);

         // Insert the new local variable into the (near) beginning of the to-be-inserted function body.  We insert them in the
         // order their corresponding actuals/formals appear, although the C++ standard does not require this order of
         // evaluation.
         SgInitializedName* init = vardecl->get_variables().back();
         inits.push_back(init);
         initializer->set_parent(init);
         init->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + argNumber, vardecl);
         SgVariableSymbol* sym = new SgVariableSymbol(init);
         paramMap[formalArg] = sym;
         funbody_copy->insert_symbol(shadow_name, sym);
         sym->set_parent(funbody_copy->get_symbol_table());
     }

     // Similarly for "this". We create a local variable in the to-be-inserted function body that will be initialized with the
     // caller's "this".
     if (thisdecl) {
         thisdecl->set_parent(funbody_copy);
         thisinitname->set_scope(funbody_copy);
         funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
         SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
         funbody_copy->insert_symbol(thisname, thisSym);
         thisSym->set_parent(funbody_copy->get_symbol_table());
         ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
     }
     ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

     SgName end_of_inline_name = "rose_inline_end__";
     end_of_inline_name << ++gensym_counter;
     SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
     end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
     printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

  // Need to set the parent of funbody_copy to avoid error.
     funbody_copy->set_parent(funbody_raw->get_parent());

     printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

     printf ("funbody_raw->get_statements().size()  = %" PRIuPTR " \n",funbody_raw->get_statements().size());
     printf ("funbody_copy->get_statements().size() = %" PRIuPTR " \n",funbody_copy->get_statements().size());

     printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
     printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

     printf ("Output the symbol table for funbody_raw \n");
     funbody_raw->get_symbol_table()->print("debugging copy problem");

  // printf ("Output the symbol table for funbody_copy \n");
  // funbody_copy->get_symbol_table()->print("debugging copy problem");

     SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
     ROSE_ASSERT(project_copy != NULL);

     const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
     generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

     funbody_copy->append_statement(end_of_inline_label);
     end_of_inline_label->set_scope(targetFunction);
     SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
     end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
     targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);

     // To ensure that there is some statement after the label
     SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
     dummyStatement->set_endOfConstruct(SgNULL_FILE);
     funbody_copy->append_statement(dummyStatement);
     dummyStatement->set_parent(funbody_copy);
#if 0
     SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
     SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
     pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
     pragmaEnd->set_parent(pragmaEndDecl);
     pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
     funbody_copy->append_statement(pragmaEndDecl);
     pragmaEndDecl->set_parent(funbody_copy);
#endif

     ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
     replaceExpressionWithStatement(funcall, &previsitor);

     // Make sure the AST is consistent. To save time, we'll just fix things that we know can go wrong. For instance, the
     // SgAsmExpression.p_lvalue data member is required to be true for certain operators and is set to false in other
     // situations. Since we've introduced new expressions into the AST we need to adjust their p_lvalue according to the
     // operators where they were inserted.
     markLhsValues(targetFunction);
#ifdef NDEBUG
     AstTests::runAllTests(SageInterface::getProject());
#endif

#if 0
  // DQ (4/6/2015): Adding code to check for consitancy of checking the isTransformed flag.
     ROSE_ASSERT(funcall != NULL);
     ROSE_ASSERT(funcall->get_parent() != NULL);
     ROSE_ASSERT(globalScope != NULL);
  // checkTransformedFlagsVisitor(funcall->get_parent());
     checkTransformedFlagsVisitor(globalScope);
#endif

  // DQ (4/7/2015): This fixes something I was required to fix over the weekend and which is fixed more directly, I think.
  // Mark the things we insert as being transformations so they get inserted into the output by backend()
     markAsTransformation(funbody_copy);

     return true;
   }
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                 // For sudo_exec_pty.c also look for siginfo
                    if (className == "sigaction" || className == "siginfo")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;

                           // We are puting out all macros anytime we see either type.  This might be too much...

                           // From the sigaction.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef sa_handler\n",directiveType);
                              addMacro(associatedStatement,"#undef sa_sigaction\n",directiveType);

                           // From the siginfo.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef si_pid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_uid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_timerid\n",directiveType);
                              addMacro(associatedStatement,"#undef si_overrun\n",directiveType);
                              addMacro(associatedStatement,"#undef si_status\n", directiveType);
                              addMacro(associatedStatement,"#undef si_utime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_stime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_value\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_int\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_ptr\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_addr\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_band\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_fd\n",     directiveType);
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

#if 0
  // DQ (12/30/2013): Comments and CPP directives have not yet been attached to the AST, so we can't process them here.

  // SgLocatedNode* locatedNode = isSgLocatedNode(node);
  // if (locatedNode != NULL)
     SgStatement* stmt = isSgStatement(node);
     if (stmt != NULL)
        {
       // Find all #define statements and look for self referencing macros

          int numberOfComments = -1;
          if (stmt->getAttachedPreprocessingInfo() != NULL)
               numberOfComments = stmt->getAttachedPreprocessingInfo()->size();

          std::string s = std::string(" --- startOfConstruct: file = " ) + stmt->get_startOfConstruct()->get_filenameString()
             + " raw filename = " + stmt->get_startOfConstruct()->get_raw_filename()
             + " raw line = "     + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_line())
             + " raw column = "   + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_col())
             + " #comments = "    + StringUtility::numberToString(numberOfComments)
             + " \n ";

          AttachedPreprocessingInfoType* comments = stmt->getAttachedPreprocessingInfo();

          if (comments != NULL)
             {
               printf ("Found attached comments (at %p of type: %s): \n",stmt,stmt->class_name().c_str());
               AttachedPreprocessingInfoType::iterator i;
               for (i = comments->begin(); i != comments->end(); i++)
                  {
                    ROSE_ASSERT ( (*i) != NULL );
                    printf ("          Attached Comment (relativePosition=%s): %s\n",
                         ((*i)->getRelativePosition() == PreprocessingInfo::before) ? "before" : "after",
                         (*i)->getString().c_str());
                    printf ("Comment/Directive getNumberOfLines = %d getColumnNumberOfEndOfString = %d \n",(*i)->getNumberOfLines(),(*i)->getColumnNumberOfEndOfString());
                    (*i)->get_file_info()->display("comment/directive location");
                  }
             }
            else
             {
               printf ("No attached comments (at %p of type: %s): \n",stmt,stmt->class_name().c_str());
             }
        }
#endif
   }
Exemplo n.º 14
0
StencilEvaluation_SynthesizedAttribute
StencilEvaluationTraversal::evaluateSynthesizedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     StencilEvaluation_SynthesizedAttribute return_synthesizedAttribute;

#if 0
     printf ("In StencilEvaluationTraversal::evaluateSynthesizedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundStencilOffsetFSM = false;
     SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode);
     if (constructorInitializer != NULL && inheritedAttribute.stencilOffsetFSM != NULL)
        {
#if 0
          printf ("Found pair<Shift,double>(x,y): set then in the synthesizedAttribute: astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif
          return_synthesizedAttribute.stencilOffsetFSM       = inheritedAttribute.stencilOffsetFSM;
          return_synthesizedAttribute.stencilCoeficientValue = inheritedAttribute.stencilCoeficientValue;
#if 0
          printf ("return_synthesizedAttribute.stencilCoeficientValue = %f \n",return_synthesizedAttribute.stencilCoeficientValue);
#endif
          foundStencilOffsetFSM = true;
        }

  // There should only be a single child set with a pair<Shift,double>(x,y) object.
     for (size_t i = 0; i < synthesizedAttributeList.size(); i++)
        {
          if (synthesizedAttributeList[i].stencilOffsetFSM != NULL)
             {
            // Check that the return_synthesizedAttribute.stencilOffsetFSM has not already been set.
            // This could happend if we allows nesting of pair<Shift,double>(x,y) within itself (not allowed).
#if 0
               printf ("synthesizedAttributeList[i].stencilOffsetFSM != NULL \n");
#endif
            // ROSE_ASSERT(foundStencilOffsetFSM == false);
               if (foundStencilOffsetFSM == false)
                  {
#if 0
                    printf ("foundStencilOffsetFSM == false \n");
#endif
                 // ROSE_ASSERT(return_synthesizedAttribute.stencilOffsetFSM == NULL);
                    if (return_synthesizedAttribute.stencilOffsetFSM == NULL)
                       {
#if 0
                         printf ("return_synthesizedAttribute.stencilOffsetFSM != NULL \n");
#endif
                         return_synthesizedAttribute.stencilOffsetFSM = synthesizedAttributeList[i].stencilOffsetFSM;
                         return_synthesizedAttribute.stencilCoeficientValue = synthesizedAttributeList[i].stencilCoeficientValue;
                       }

                    foundStencilOffsetFSM = true;
                  }
             }
        }

  // This allows us to find the variables of type vector<Point> and vector<double> used as an alternative way
  // to specify a stencil (using the Stencil constructor that takes these variables as input arguments).
  // It relies upon a previous traversal to have identified the inputs to Stencil constructor.
  // This support is incomplete while I focus on the alternative approach to the specification of the stencil
  // using intremental union of a stencil with a pair<Shift,double>() template instantiation.
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode);
     if (variableDeclaration != NULL)
        {
       // Get the SgInitializedName from the SgVariableDeclaration.
          SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration);
#if 0
          printf ("In evaluateInheritedAttribute(): case SgInitializedName from variable declaration: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
#endif
          bool foundStencilDeclaration = false;
          if (find(stencilInputInitializedNameList.begin(),stencilInputInitializedNameList.end(),initializedName) != stencilInputInitializedNameList.end())
             {
#if 0
               printf ("Found declaration associated with stencil input: initializedName = %p = %s name = %s \n",initializedName,initializedName->class_name().c_str(),initializedName->get_name().str());
#endif
            // Build the finite state machine for the stencil and add it to the map using the name (in SgInitializedName) as a key.
            // For now we assume that the stencil specification is using the default construction.
               if (initializedName->get_initptr() != NULL)
                  {
                    printf ("FIXME: This declaration of a stencil appears to have constrcutor arguments (this not the default constuctor as interprest below). \n");
#if 0
                    ROSE_ASSERT(false);
#endif
                  }

               foundStencilDeclaration = true;
             }
            else
             {
            // Verify that this is a Stencil declaration.
               SgClassType* classType = isSgClassType(initializedName->get_type());
               if (classType != NULL)
                  {
                 // Check if this is associated with a template instantiation.
                    SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classType->get_declaration());
                    if (templateInstantiationDecl != NULL)
                       {
#if 0
                         printf ("case SgTemplateInstaiationDecl: class name = %s \n",classType->get_name().str());
                         printf ("case SgTemplateInstaiationDecl: templateInstantiationDecl->get_templateName() = %s \n",templateInstantiationDecl->get_templateName().str());
#endif
                         if (templateInstantiationDecl->get_templateName() == "Stencil")
                            {
#if 0
                              printf ("This is verified to be associated with the Stencil template class \n");
#endif
                              foundStencilDeclaration = true;
                            }
                       }
                  }
             }

          if (foundStencilDeclaration == true)
             {
               string name = initializedName->get_name();
               ROSE_ASSERT(stencilMap.find(name) == stencilMap.end());
            // stencilMap[name] = new StencilFSM();
               StencilFSM* stencilFSM = new StencilFSM();
               ROSE_ASSERT(stencilFSM != NULL);
               stencilMap[name] = stencilFSM;
               ROSE_ASSERT(stencilMap.find(name) != stencilMap.end());
#if 0
               printf ("Added StencilFSM to stencilMap using name = %s \n",name.c_str());
#endif
#if 0
               printf ("Trigger an event on the stencilFSM ========================== %p \n",stencilFSM);
               printf ("   --- Use the return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
               if (return_synthesizedAttribute.stencilOffsetFSM != NULL)
                  {
                 // Trigger the event to add the stencil offset to the stencil.
                 // Trigger the event on the finite state machine using the elements saved in the synthesized attribute.
                    StencilFSM stencil_rhs (*(return_synthesizedAttribute.stencilOffsetFSM),return_synthesizedAttribute.stencilCoeficientValue);

                 // This reproduces the same semantics in our finite state machine as the Stencil class's operator+()
                 // in the stencil specification. but this permits use to accumulate the state at compile time.
                    stencilFSM->operator+(stencil_rhs);

                 // We have now used these values so avoid letting then be used again.
                    return_synthesizedAttribute.stencilOffsetFSM       = NULL;
                    return_synthesizedAttribute.stencilCoeficientValue = 0.0;
                  }
#if 0
               stencilFSM->display("after FSM stencil default construction plus union event: StencilEvaluationTraversal::evaluateSynthesizedAttribute()");
#endif
#if 0
               printf ("Exiting as a test! \n");
               ROSE_ASSERT(false);
#endif
             }
        }

  // Recognize member function calls on "Stencil" objects so that we can trigger events on those associated finite state machines.
     bool isTemplateClass = true;
     bool isTemplateFunctionInstantiation = true;
     SgInitializedName* initializedNameUsedToCallMemberFunction = NULL;
     SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Stencil",isTemplateClass,"operator+",isTemplateFunctionInstantiation);
     if (return_synthesizedAttribute.stencilOffsetFSM != NULL && functionCallExp != NULL)
        {
       // This is the DSL specific part of the synthesized attribute evaluation.

          ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL);
          string name = initializedNameUsedToCallMemberFunction->get_name();
#if 0
          printf ("This is verified to be the operator+ member function of the Stencil templated class (so this corresponds to an event in the Stencil finite state machine) \n");
          printf ("   --- stencil object name = %s \n",name.c_str());
#endif
       // Lookup the stencil FSM in the map of stencil FSMs using the name as the key.
          ROSE_ASSERT(stencilMap.find(name) != stencilMap.end());
          StencilFSM* stencilFSM = stencilMap[name];
          ROSE_ASSERT(stencilFSM != NULL);
#if 0
          printf ("Trigger an event on the stencilFSM ========================== %p \n",stencilFSM);
          printf ("   --- Use the return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
       // Make sure we have the input parameter for the stencil's finite state machine.
          ROSE_ASSERT(return_synthesizedAttribute.stencilOffsetFSM != NULL);

       // Trigger the event on the finite state machine using the elements saved in the synthesized attribute.
          StencilFSM stencil_rhs (*(return_synthesizedAttribute.stencilOffsetFSM),return_synthesizedAttribute.stencilCoeficientValue);

       // This reproduces the same semantics in our finite state machine as the Stencil class's operator+()
       // in the stencil specification. but this permits use to accumulate the state at compile time.
          stencilFSM->operator+(stencil_rhs);

       // We have now used these values so avoid letting then be used again.
          return_synthesizedAttribute.stencilOffsetFSM       = NULL;
          return_synthesizedAttribute.stencilCoeficientValue = 0.0;
#if 0
          stencilFSM->display("after FSM stencil union event: StencilEvaluationTraversal::evaluateSynthesizedAttribute()");
#endif
        }

#if 0
     printf ("Leaving StencilEvaluationTraversal::evaluateSynthesizedAttribute(): return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
#if 0
     printf ("Leaving StencilEvaluationTraversal::evaluateSynthesizedAttribute(): return_synthesizedAttribute.stencilCoeficientValue = %f \n",return_synthesizedAttribute.stencilCoeficientValue);
#endif

     return return_synthesizedAttribute;
   }
Exemplo n.º 15
0
//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;
}
Exemplo n.º 16
0
  NodeQuerySynthesizedAttributeType
NodeQuery::querySolverVariableTypes (SgNode * astNode)
{
  ROSE_ASSERT (astNode != NULL);
  NodeQuerySynthesizedAttributeType returnNodeList;
  /*
     SgVariableDeclaration* sageVariableDeclaration = isSgVariableDeclaration(astNode);

     if(sageVariableDeclaration != NULL)
     {
     SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables();


     printf ("\nHere is a function declaration :Line = %d Columns = %d \n", ROSE:: getLineNumber (isSgLocatedNode(astNode) ), ROSE:: getColumnNumber ( isSgLocatedNode(astNode) ));
     cout << "The filename is:" << ROSE::getFileName(isSgLocatedNode(astNode)) << endl;


     typedef SgInitializedNamePtrList::iterator LI;

     for ( LI i = sageInitializedNameList.begin(); i != sageInitializedNameList.end(); ++i) {
     SgType* sageElementType = i->get_type();
     ROSE_ASSERT( sageElementType != NULL);

     cout << "The class name is: " << sageElementType->sage_class_name() << endl;
     returnNodeList.push_back( sageElementType );

     }
     cout << endl << "End printout of this Initialized Name list" << endl;


     }

   */
  // SgVarRefExp *sageVarRefExp = isSgVarRefExp (astNode);

  switch (astNode->variantT ())
  {

    case V_SgVariableDeclaration:
      {
        SgVariableDeclaration *sageVariableDeclaration =
          isSgVariableDeclaration (astNode);
        ROSE_ASSERT (sageVariableDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList =
          sageVariableDeclaration->get_variables ();

#if DEBUG_NODEQUERY
        printf ("\nIn filename: %s ",
            ROSE::getFileName (isSgLocatedNode (astNode)));
        printf ("\nHere is a variable :Line = %d Columns = %d \n",
            ROSE::getLineNumber (isSgLocatedNode (astNode)),
            ROSE::getColumnNumber (isSgLocatedNode (astNode)));
        //cout << "The typename of the variable is: " << typeName << endl;
#endif

        typedef SgInitializedNamePtrList::iterator variableIterator;
        SgType *typeNode;

        for (variableIterator variableListElement =
            sageInitializedNameList.begin ();
            variableListElement != sageInitializedNameList.end ();
            ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          ROSE_ASSERT (elmVar != NULL);
          typeNode = elmVar->get_type ();
          ROSE_ASSERT (typeNode != NULL);
          returnNodeList.push_back (typeNode);
        }
        break;
      }                         /* End case V_SgVariableDeclaration */

    case V_SgFunctionDeclaration:
    case V_SgMemberFunctionDeclaration:
      {
        SgFunctionDeclaration * sageFunctionDeclaration =
          isSgFunctionDeclaration (astNode);
        ROSE_ASSERT (sageFunctionDeclaration != NULL);

        SgInitializedNamePtrList sageInitializedNameList =
          sageFunctionDeclaration->get_args ();
        SgType *typeNode;

        typedef SgInitializedNamePtrList::iterator variableIterator;

        for (variableIterator variableListElement =
            sageInitializedNameList.begin ();
            variableListElement != sageInitializedNameList.end ();
            ++variableListElement)
        {
          SgInitializedName* elmVar = *variableListElement;

          ROSE_ASSERT (elmVar != NULL);
          typeNode = elmVar->get_type ();
          ROSE_ASSERT (typeNode != NULL);
          returnNodeList.push_back (typeNode);

        }

        break;
      }

    default:
      {
        // DQ (8/20/2005): Added default to avoid compiler warnings about unrepresented cases
      }
  }                             /* End switch case astNode */



  return returnNodeList;
}                               /* End function querySolverType() */
/**
 * \brief Return true if methodDecl overrides virtualMethodDecl.
 * \param methodDecl  a method declaration.
 * \param virtualMethodDecl a method declaration.
 * \return Returns true if virtualMethodDecl is declared as a virtual
 *         method and methodDecl has the same type signature and name
 *         as virtualMethodDecl.  
 * 
 * NB:  It is assumed that the class defining virtualMethodDecl is a base
 *      class of the class defining methodDecl.
 */
bool
methodOverridesVirtualMethod(SgMemberFunctionDeclaration *methodDecl, 
			     SgMemberFunctionDeclaration *virtualMethodDecl)
{
  if ( !isVirtual(virtualMethodDecl) )
    return false;

  //  std::cout << "looks virtual" << std::endl;

#if 0
  // Hmmm ... couldn't we just compare mangled names?
  // No, we can't because this includes the scope info, which will
  // differ between classes.
  std::cout << "methodDecl: " << methodDecl->get_mangled_name().str() << std::endl;
  std::cout << "virtualMethodDecl: " << virtualMethodDecl->get_mangled_name().str() << std::endl;
  return ( methodDecl->get_mangled_name() == virtualMethodDecl->get_mangled_name() );

#else
  if ( methodDecl->get_name() != virtualMethodDecl->get_name() )
    return false;
  
  SgType *methodReturnType = methodDecl->get_orig_return_type();
  SgType *virtualMethodReturnType = virtualMethodDecl->get_orig_return_type();

  if ( methodReturnType != virtualMethodReturnType )
    return false;

  int numMethodParams = 0;
  int numVirtualMethodParams = 0;

  SgFunctionParameterList *methodParameterList = 
    methodDecl->get_parameterList(); 

  if (methodParameterList != NULL) {
    numMethodParams = methodParameterList->get_args().size();
  }

  SgFunctionParameterList *virtualMethodParameterList = 
    virtualMethodDecl->get_parameterList(); 

  if (virtualMethodParameterList != NULL) {
    numVirtualMethodParams = virtualMethodParameterList->get_args().size();
  }

  if ( numMethodParams != numVirtualMethodParams )
    return false;

  if ( numMethodParams == 0 )
    return true;

  const SgInitializedNamePtrList &methodFormalParams = 
    methodParameterList->get_args(); 
  const SgInitializedNamePtrList &virtualMethodFormalParams = 
    virtualMethodParameterList->get_args(); 
  SgInitializedNamePtrList::const_iterator methodIt;
  SgInitializedNamePtrList::const_iterator virtualMethodIt;
  for(methodIt = methodFormalParams.begin(), 
	virtualMethodIt = virtualMethodFormalParams.begin();
      methodIt != methodFormalParams.end(); ++methodIt, ++virtualMethodIt) { 
      
      SgInitializedName* methodFormalParam = *methodIt;  
      ROSE_ASSERT(methodFormalParam != NULL); 

      SgInitializedName* virtualMethodFormalParam = *virtualMethodIt;  
      ROSE_ASSERT(virtualMethodFormalParam != NULL); 
      
      if ( methodFormalParam->get_type() != 
	   virtualMethodFormalParam->get_type() )
	return false;

  }

  return true;
#endif
}
/**
 * \brief Return true if methodDecl overrides virtualMethodDecl.
 * \param methodDecl  a method declaration.
 * \param virtualMethodDecl a method declaration.
 * \return Returns true if virtualMethodDecl is declared as a virtual
 *         method and methodDecl has the same type signature and name
 *         as virtualMethodDecl.  
 * 
 * NB:  It is assumed that the class defining virtualMethodDecl is a base
 *      class of the class defining methodDecl.
 */
bool
methodOverridesVirtualMethod(SgMemberFunctionDeclaration *methodDecl, 
			     SgMemberFunctionDeclaration *virtualMethodDecl)
{
  if ( !isVirtual(virtualMethodDecl) )
    return false;

#if 1
  // Hmmm ... couldn't we just compare mangled names?
  return ( methodDecl->get_mangled_name() == virtualMethodDecl->get_mangled_name() );

#else
  if ( methodDecl->get_name() != virtualMethodDecl->get_name() )
    return false;
  
  SgType *methodReturnType = methodDecl->get_orig_return_type();
  SgType *virtualMethodReturnType = virtualMethodDecl->get_orig_return_type();

  if ( methodReturnType != virtualMethodReturnType )
    return false;

  int numMethodParams = 0;
  int numVirtualMethodParams = 0;

  SgFunctionParameterList *methodParameterList = 
    methodDecl->get_parameterList(); 

  if (methodParameterList != NULL) {
    numMethodParams = methodParameterList->get_args().size();
  }

  SgFunctionParameterList *virtualMethodParameterList = 
    virtualMethodDecl->get_parameterList(); 

  if (virtualMethodParameterList != NULL) {
    numVirtualMethodParams = virtualMethodParameterList->get_args().size();
  }

  if ( numMethodParams != numVirtualMethodParams )
    return false;

  if ( numMethodParams == 0 )
    return true;

  const SgInitializedNamePtrList &methodFormalParams = 
    methodParameterList->get_args(); 
  const SgInitializedNamePtrList &virtualMethodFormalParams = 
    virtualMethodParameterList->get_args(); 
  SgInitializedNamePtrList::const_iterator methodIt;
  SgInitializedNamePtrList::const_iterator virtualMethodIt;
  for(methodIt = methodFormalParams.begin(), 
	virtualMethodIt = virtualMethodFormalParams.begin();
      methodIt != methodFormalParams.end(); ++methodIt, ++virtualMethodIt) { 
      
      SgInitializedName* methodFormalParam = *methodIt;  
      ROSE_ASSERT(methodFormalParam != NULL); 

      SgInitializedName* virtualMethodFormalParam = *virtualMethodIt;  
      ROSE_ASSERT(virtualMethodFormalParam != NULL); 
      
      if ( methodFormalParam->get_type() != 
	   virtualMethodFormalParam->get_type() )
	return false;

  }

  return true;
#endif
}
Exemplo n.º 19
0
set<SgInitializedName*> computeLiveVars(SgStatement* stmt, const X86CTranslationPolicy& conv, map<SgLabelStatement*, set<SgInitializedName*> >& liveVarsForLabels, set<SgInitializedName*> currentLiveVars, bool actuallyRemove) {
  switch (stmt->variantT()) {
    case V_SgBasicBlock: {
      const SgStatementPtrList& stmts = isSgBasicBlock(stmt)->get_statements();
      for (size_t i = stmts.size(); i > 0; --i) {
        currentLiveVars = computeLiveVars(stmts[i - 1], conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      }
      return currentLiveVars;
    }
    case V_SgPragmaDeclaration: return currentLiveVars;
    case V_SgDefaultOptionStmt: return currentLiveVars;
    case V_SgCaseOptionStmt: {
      return computeLiveVars(isSgCaseOptionStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
    }
    case V_SgLabelStatement: {
      liveVarsForLabels[isSgLabelStatement(stmt)] = currentLiveVars;
      return currentLiveVars;
    }
    case V_SgGotoStatement: {
      return liveVarsForLabels[isSgGotoStatement(stmt)->get_label()];
    }
    case V_SgSwitchStatement: {
      SgSwitchStatement* s = isSgSwitchStatement(stmt);
      SgBasicBlock* swBody = isSgBasicBlock(s->get_body());
      ROSE_ASSERT (swBody);
      const SgStatementPtrList& bodyStmts = swBody->get_statements();
      set<SgInitializedName*> liveForBody; // Assumes any statement in the body is possible
      for (size_t i = 0; i < bodyStmts.size(); ++i) {
        setUnionInplace(liveForBody, computeLiveVars(bodyStmts[i], conv, liveVarsForLabels, currentLiveVars, actuallyRemove));
      }
      return computeLiveVars(s->get_item_selector(), conv, liveVarsForLabels, liveForBody, actuallyRemove);
    }
    case V_SgContinueStmt: {
      return makeAllPossibleVars(conv);
    }
    case V_SgIfStmt: {
      set<SgInitializedName*> liveForBranches = computeLiveVars(isSgIfStmt(stmt)->get_true_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      setUnionInplace(liveForBranches, (isSgIfStmt(stmt)->get_false_body() != NULL ? computeLiveVars(isSgIfStmt(stmt)->get_false_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove) : set<SgInitializedName*>()));
      return computeLiveVars(isSgIfStmt(stmt)->get_conditional(), conv, liveVarsForLabels, liveForBranches, actuallyRemove);
    }
    case V_SgWhileStmt: {
      while (true) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, false);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, false);
        setUnionInplace(currentLiveVars, liveVarsSave);
        if (liveVarsSave == currentLiveVars) break;
      }
      if (actuallyRemove) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, true);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, true);
        setUnionInplace(currentLiveVars, liveVarsSave);
      }
      return currentLiveVars;
    }
    case V_SgBreakStmt: return set<SgInitializedName*>();
    case V_SgExprStatement: {
      SgExpression* e = isSgExprStatement(stmt)->get_expression();
      switch (e->variantT()) {
        case V_SgAssignOp: {
          SgVarRefExp* lhs = isSgVarRefExp(isSgAssignOp(e)->get_lhs_operand());
          ROSE_ASSERT (lhs);
          SgInitializedName* in = lhs->get_symbol()->get_declaration();
          if (currentLiveVars.find(in) == currentLiveVars.end()) {
            if (actuallyRemove) {
              // cerr << "Removing assignment " << e->unparseToString() << endl;
              isSgStatement(stmt->get_parent())->remove_statement(stmt);
            }
            return currentLiveVars;
          } else {
            currentLiveVars.erase(in);
            getUsedVariables(isSgAssignOp(e)->get_rhs_operand(), currentLiveVars);
            return currentLiveVars;
          }
        }
        case V_SgFunctionCallExp: {
          getUsedVariables(e, currentLiveVars);
          SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function());
          ROSE_ASSERT (fr);
          if (fr->get_symbol()->get_declaration() == conv.interruptSym->get_declaration()) {
            setUnionInplace(currentLiveVars, makeAllPossibleVars(conv));
            return currentLiveVars;
          } else {
            return currentLiveVars;
          }
        }
        default: {
          getUsedVariables(e, currentLiveVars);
          return currentLiveVars;
        }
      }
    }
    case V_SgVariableDeclaration: {
      ROSE_ASSERT (isSgVariableDeclaration(stmt)->get_variables().size() == 1);
      SgInitializedName* in = isSgVariableDeclaration(stmt)->get_variables()[0];
      bool isConst = isConstType(in->get_type());
      if (currentLiveVars.find(in) == currentLiveVars.end() && isConst) {
        if (actuallyRemove) {
          // cerr << "Removing decl " << stmt->unparseToString() << endl;
          isSgStatement(stmt->get_parent())->remove_statement(stmt);
        }
        return currentLiveVars;
      } else {
        currentLiveVars.erase(in);
        if (in->get_initializer()) {
          getUsedVariables(in->get_initializer(), currentLiveVars);
        }
        return currentLiveVars;
      }
    }
    default: cerr << "computeLiveVars: " << stmt->class_name() << endl; abort();
  }
}
Exemplo n.º 20
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);
        
      }
    }
}
Exemplo n.º 21
0
int main( int argc, char * argv[] )
{
// Option to linearize the array.
  Rose_STL_Container<std::string> localCopy_argv = CommandlineProcessing::generateArgListFromArgcArgv(argc, argv);
  int newArgc;
  char** newArgv = NULL;
  vector<string> argList = localCopy_argv;
  if (CommandlineProcessing::isOption(argList,"-f2c:","linearize",true) == true)
  {
    isLinearlizeArray = true;
  }
  CommandlineProcessing::generateArgcArgvFromList(argList,newArgc, newArgv);
// Build the AST used by ROSE
  SgProject* project = frontend(newArgc,newArgv);
  AstTests::runAllTests(project);   

  if (SgProject::get_verbose() > 2)
    generateAstGraph(project,8000,"_orig");
  
  // Traversal with Memory Pool to search for variableDeclaration
  variableDeclTraversal translateVariableDeclaration;
  traverseMemoryPoolVisitorPattern(translateVariableDeclaration);
  for(vector<SgVariableDeclaration*>::iterator dec=variableDeclList.begin(); dec!=variableDeclList.end(); ++dec)
  {
    /*
       For the Fortran AST, a single variableDeclaration can be shared by multiple variables.
       This violated the normalization rules for C unparser.  Therefore, we have to transform it.
    */
    SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(*dec);
    ROSE_ASSERT(variableDeclaration);
    if((variableDeclaration->get_variables()).size() != 1)
    {
      updateVariableDeclarationList(variableDeclaration);
      statementList.push_back(variableDeclaration);
      removeList.push_back(variableDeclaration);
    }
  }

  // reset the vector that collects all variable declaration. We need to walk through memory pool again to find types
  
  variableDeclList.clear();
  traverseMemoryPoolVisitorPattern(translateVariableDeclaration);
  for(vector<SgVariableDeclaration*>::iterator dec=variableDeclList.begin(); dec!=variableDeclList.end(); ++dec)
  {
    SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(*dec);
    ROSE_ASSERT(variableDeclaration);
    SgInitializedNamePtrList initializedNameList = variableDeclaration->get_variables();
    for(SgInitializedNamePtrList::iterator i=initializedNameList.begin(); i!=initializedNameList.end();++i)
    {
      SgInitializedName* initiallizedName = isSgInitializedName(*i);
      SgType* baseType = initiallizedName->get_type();
      if(baseType->variantT() == V_SgArrayType)
      {
        SgArrayType* arrayBase = isSgArrayType(baseType);
        // At this moment, we are still working on the Fortran-stype AST.  Therefore, there is no nested types for multi-dim array.
        if(arrayBase->findBaseType()->variantT() == V_SgTypeString)
        {
          arrayBase->reset_base_type(translateType(arrayBase->findBaseType()));
          arrayBase->set_rank(arrayBase->get_rank()+1);
        }
      }
      else
      {
        initiallizedName->set_type(translateType(baseType));
      }
    }
  }

  // replace the AttributeSpecificationStatement 
  Rose_STL_Container<SgNode*> AttributeSpecificationStatement = NodeQuery::querySubTree (project,V_SgAttributeSpecificationStatement);
  for (Rose_STL_Container<SgNode*>::iterator i = AttributeSpecificationStatement.begin(); i != AttributeSpecificationStatement.end(); i++)
  {
    SgAttributeSpecificationStatement* attributeSpecificationStatement = isSgAttributeSpecificationStatement(*i);
    ROSE_ASSERT(attributeSpecificationStatement);
    translateAttributeSpecificationStatement(attributeSpecificationStatement);
    statementList.push_back(attributeSpecificationStatement);
    removeList.push_back(attributeSpecificationStatement);
  }

  // replace the parameter reference
  parameterTraversal translateParameterRef;
  traverseMemoryPoolVisitorPattern(translateParameterRef);
  for(vector<SgVarRefExp*>::iterator i=parameterRefList.begin(); i!=parameterRefList.end(); ++i)
  {
    SgVarRefExp* parameterRef = isSgVarRefExp(*i);
    if(parameterSymbolList.find(parameterRef->get_symbol()) != parameterSymbolList.end())
    {
      SgExpression* newExpr = isSgExpression(deepCopy(parameterSymbolList.find(parameterRef->get_symbol())->second));
      ROSE_ASSERT(newExpr);
      newExpr->set_parent(parameterRef->get_parent());
      replaceExpression(parameterRef,
                        newExpr,
                        false);
    }
  }

  /*
     Parameters will be replaced by #define, all the declarations should be removed
  */
  for(map<SgVariableSymbol*,SgExpression*>::iterator i=parameterSymbolList.begin();i!=parameterSymbolList.end();++i)
  {
    SgVariableSymbol* symbol = i->first;
    SgInitializedName* initializedName = symbol->get_declaration();
    SgVariableDeclaration* decl = isSgVariableDeclaration(initializedName->get_parent());
    statementList.push_back(decl);
    removeList.push_back(decl);
  }


  // Traversal with Memory Pool to search for arrayType
  arrayTypeTraversal translateArrayType;
  traverseMemoryPoolVisitorPattern(translateArrayType);
  for(vector<SgArrayType*>::iterator i=arrayTypeList.begin(); i!=arrayTypeList.end(); ++i)
  {
    if(isLinearlizeArray)
    {
      linearizeArrayDeclaration(*i);
    }
    else
    {
      translateArrayDeclaration(*i);
    }
  }

  // Traversal with Memory Pool to search for pntrArrRefExp
  pntrArrRefTraversal translatePntrArrRefExp;
  traverseMemoryPoolVisitorPattern(translatePntrArrRefExp);
  for(vector<SgPntrArrRefExp*>::iterator i=pntrArrRefList.begin(); i!=pntrArrRefList.end(); ++i)
  {
    if(isLinearlizeArray)
    {
      linearizeArraySubscript(*i);
    }
    else
    {
      translateArraySubscript(*i);
    }
  }


  Rose_STL_Container<SgNode*> functionList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration);
  for (Rose_STL_Container<SgNode*>::iterator i = functionList.begin(); i != functionList.end(); i++)
  {
    if((isSgProcedureHeaderStatement(*i) != NULL) ||
       (isSgProgramHeaderStatement(*i) != NULL)){
      SgFunctionDeclaration* functionBody = isSgFunctionDeclaration(*i);
      bool hasReturnVal = false;
      if(isSgProcedureHeaderStatement(functionBody))
      {
        hasReturnVal = isSgProcedureHeaderStatement(functionBody)->isFunction();
      }
      fixFortranSymbolTable(functionBody->get_definition(),hasReturnVal);
    }
  } 

  // Traversal with Memory Pool to search for equivalenceStatement
  equivalencelTraversal translateEquivalenceStmt;
  traverseMemoryPoolVisitorPattern(translateEquivalenceStmt);
  for(vector<SgEquivalenceStatement*>::iterator i=equivalenceList.begin(); i!=equivalenceList.end(); ++i)
  {
    SgEquivalenceStatement* equivalenceStatement = isSgEquivalenceStatement(*i);
    ROSE_ASSERT(equivalenceStatement);
    translateEquivalenceStatement(equivalenceStatement);
    statementList.push_back(equivalenceStatement);
    removeList.push_back(equivalenceStatement);
  }



  // Simple traversal, bottom-up, to translate the rest
  f2cTraversal f2c;
  f2c.traverseInputFiles(project,postorder);

  // removing all the unsed statement from AST
  for(vector<SgStatement*>::iterator i=statementList.begin(); i!=statementList.end(); ++i)
  {
    removeStatement(*i);
    (*i)->set_parent(NULL);
  }
      
  // deepDelete the removed nodes 
  for(vector<SgNode*>::iterator i=removeList.begin(); i!=removeList.end(); ++i)
  {
    deepDelete(*i);
  }
      
/*
  1. There should be no Fortran-specific AST nodes in the whole
     AST graph after the translation. 
  
  TODO: make sure translator generating clean AST 
*/
    //generateDOT(*project);
  if (SgProject::get_verbose() > 2)
    generateAstGraph(project,8000);
  return backend(project);
}
Exemplo n.º 22
0
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                    if (className == "sigaction")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;
                              std::string macroString = "#undef sa_handler\n";
                              std::string filenameString = "macro_call_fixupSelfReferentialMacrosInAST";
                              int line_no = 1;
                              int col_no  = 1;
                              int nol     = 1;
                              PreprocessingInfo::RelativePositionType relPos = PreprocessingInfo::before;

                              PreprocessingInfo* macro = new PreprocessingInfo(directiveType,macroString,filenameString,line_no,col_no,nol,relPos);

                           // printf ("Attaching CPP directive %s to IR node %p as attributes. \n",PreprocessingInfo::directiveTypeName(macro->getTypeOfDirective()).c_str(),associatedStatement);
                              associatedStatement->addToAttachedPreprocessingInfo(macro);
#if 0
                              printf ("Exiting as a test! \n");
                              ROSE_ASSERT(false);
#endif
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

   }
Exemplo n.º 23
0
Detection_InheritedAttribute
DetectionTraversal::evaluateInheritedAttribute (SgNode* astNode, Detection_InheritedAttribute inheritedAttribute )
   {
#if 0
     printf ("In DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

  // DQ (2/3/2016): Recognize IR nodes that are representative of target DSL abstractions.
     bool foundTargetDslAbstraction = DSL_Support::isDslAbstraction(astNode);

#if 1
     printf ("In DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s: foundTargetDslAbstraction = %s \n",astNode,astNode->class_name().c_str(),foundTargetDslAbstraction ? "true" : "false");
#endif

#if 0
  // OLD CODE (represented by DSL_Support::isDslAbstraction() function).

  // Detection of stencil declaration and stencil operator.
  // Where the stencil specification is using std::vectors as parameters to the constructor, we have to first
  // find the stencil declaration and read the associated SgVarRefExp to get the variable names used.  
  // Then a finite state machine can be constructed for each of the input variables so that we can 
  // interpret the state when the stencil operator is constructed.
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode);
     if (variableDeclaration != NULL)
        {
       // Get the SgInitializedName from the SgVariableDeclaration.
          SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration);

          SgType* base_type = initializedName->get_type()->findBaseType();
          ROSE_ASSERT(base_type != NULL);

       // SgClassType* classType = isSgClassType(initializedName->get_type());
          SgClassType* classType = isSgClassType(base_type);

          if (classType != NULL)
             {
#if 1
               printf ("In DetectionTraversal::evaluateInheritedAttribute(): case SgClassType: class name = %s \n",classType->get_name().str());
#endif
            // Check if this is associated with a template instantiation.
               SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classType->get_declaration());
               if (templateInstantiationDecl != NULL)
                  {
#if 1
                    printf ("case SgTemplateInstaiationDecl: class name = %s \n",classType->get_name().str());
                    printf ("case SgTemplateInstaiationDecl: templateInstantiationDecl->get_templateName() = %s \n",templateInstantiationDecl->get_templateName().str());
#endif
                 // inheritedAttribute.set_StencilDeclaration(templateInstantiationDecl->get_templateName() == "Stencil");
                 // inheritedAttribute.set_StencilOperatorDeclaration(templateInstantiationDecl->get_templateName() == "StencilOperator");

                    if (templateInstantiationDecl->get_templateName() == "Stencil")
                       {
                      // DQ (2/8/2015): Ignore compiler generated IR nodes (from template instantiations, etc.).
                      // Note that simpleCNS.cpp generates one of these from it's use of the tuple template and associated template instantations.

                      // DQ: Test the DSL support.
                         ROSE_ASSERT(isMatchingClassType(classType,"Stencil",true) == true);

                         checkAndResetToMakeConsistantCompilerGenerated(initializedName);

                         if (initializedName->isCompilerGenerated() == false)
                            {
                           // Save the SgInitializedName associated with the stencil.
                           // stencilInitializedNameList.push_back(initializedName);
                           // inheritedAttribute.set_StencilDeclaration(true);
                           // foundStencilVariable = true;
#if 1
                              printf ("Detected Stencil<> typed variable: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
                           // printf ("   --- stencilInitializedNameList.size() = %zu \n",stencilInitializedNameList.size());
#endif
#if 1
                              initializedName->get_file_info()->display("In DetectionTraversal::evaluateInheritedAttribute(): initializedName : debug");
#endif
#if 0
                              Stencil_Attribute* dslAttribute = new Stencil_Attribute();
#if 1
                              printf ("Adding (Stencil) dslAttribute = %p \n",dslAttribute);
#endif
                              ROSE_ASSERT(dslAttribute != NULL);

                           // virtual void addNewAttribute (std::string s, AstAttribute *a);   
                              initializedName->addNewAttribute(StencilVariable,dslAttribute);
#endif
                            }
                       }
                  }

               SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration());
               if (classDeclaration != NULL)
                  {
                    if (classDeclaration->get_name() == "Point")
                       {
                      // Save the SgInitializedName associated with the Point type.
#if 0
                         printf ("Detected Point<> typed variable: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
#endif
                         checkAndResetToMakeConsistantCompilerGenerated(initializedName);

                         if (initializedName->isCompilerGenerated() == false)
                            {
                           // pointInitializedNameList.push_back(initializedName);
#if 0
                              Point_Attribute* dslAttribute = new Point_Attribute();
                              printf ("Adding (Point) dslAttribute = %p \n",dslAttribute);
                              ROSE_ASSERT(dslAttribute != NULL);

                           // virtual void addNewAttribute (std::string s, AstAttribute *a);   
                              initializedName->addNewAttribute(PointVariable,dslAttribute);
#endif
                            }
                       }
                  }
             }
        }
#endif

#if 1
     printf ("Leaving DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

  // Construct the return attribute from the modified input attribute.
     return Detection_InheritedAttribute(inheritedAttribute);
   }
InterleaveAcrossArraysCheckSynthesizedAttributeType
interleaveAcrossArraysCheck::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes )
{
    //cout << " Node: " << n->unparseToString() << endl;

    InterleaveAcrossArraysCheckSynthesizedAttributeType localResult;

    for (SynthesizedAttributesList::reverse_iterator child = childAttributes.rbegin(); child != childAttributes.rend(); child++)
    {
        InterleaveAcrossArraysCheckSynthesizedAttributeType childResult = *child;
        localResult.isArrayRef |= childResult.isArrayRef;
        localResult.isFunctionRefExp |= childResult.isFunctionRefExp;
    }


    if(isSgVariableDeclaration(n))
    {
        SgVariableDeclaration* varDecl = isSgVariableDeclaration(n);
        SgInitializedNamePtrList & varList = varDecl->get_variables();

        for(SgInitializedNamePtrList::iterator initIter = varList.begin(); initIter!=varList.end() ; initIter++)
        {
            SgInitializedName* var = *initIter;
            ROSE_ASSERT(var!=NULL);
            SgType *variableType = var->get_type();
            ROSE_ASSERT (variableType != NULL);
            string type = TransformationSupport::getTypeName(variableType);
            string variableName = var->get_name().str();

            //Case 6
            if(outputName == variableName)
            {
                cout << " ERROR: Substituting Array " << outputName << " already declared in the file." << endl;
                ROSE_ABORT();
            }

            if(type!="doubleArray" && type !="floatArray" && type!="intArray")
                return localResult;

#if DEBUG
            cout << " Var Name: " << variableName << " Type: " << type << endl;
#endif

            storeArrayReference(var, variableName, type );
        }
    }
    else if(isSgPntrArrRefExp(n))
    {
        SgVarRefExp* varRefExp = isSgVarRefExp(isSgPntrArrRefExp(n)->get_lhs_operand());

        if(varRefExp != NULL)
        {
            SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
            ROSE_ASSERT (variableSymbol != NULL);
            SgInitializedName* initializedName = variableSymbol->get_declaration();
            ROSE_ASSERT (initializedName != NULL);
            string variableName = initializedName->get_name().str();
            SgType* type = variableSymbol->get_type();
            ROSE_ASSERT (type != NULL);
            string typeName = TransformationSupport::getTypeName(type);

            // A++ Supported Arrays
            if(typeName !="doubleArray" && typeName !="floatArray" && typeName !="intArray")
                return localResult;

            // Check if variableName matches the input list
            if(transformation->containsInput(variableName))
                localResult.isArrayRef = true;
        }
    }
    else if(isSgFunctionCallExp(n))
    {
        // Case 1
        // Check for array being present in function Call
        if(localResult.isFunctionRefExp && localResult.isArrayRef)
        {
            cout << " ERROR: Array Reference present in a function call " << endl;
            ROSE_ABORT();
        }
    }
    else if(isSgFunctionRefExp(n))
    {
        localResult.isFunctionRefExp = true;
    }
    else if(isSgStatement(n))
    {
        //Case 2
        if(isContigousDecl)
        {
            cout << " ERROR: Array Declaration are not contigous. " << endl;
            ROSE_ABORT();
        }
    }
    return localResult;
}
Exemplo n.º 25
0
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                 // For sudo_exec_pty.c also look for siginfo
                    if (className == "sigaction" || className == "siginfo")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;

                           // We are puting out all macros anytime we see either type.  This might be too much...

                           // From the sigaction.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef sa_handler\n",directiveType);
                              addMacro(associatedStatement,"#undef sa_sigaction\n",directiveType);

                           // From the siginfo.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef si_pid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_uid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_timerid\n",directiveType);
                              addMacro(associatedStatement,"#undef si_overrun\n",directiveType);
                              addMacro(associatedStatement,"#undef si_status\n", directiveType);
                              addMacro(associatedStatement,"#undef si_utime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_stime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_value\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_int\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_ptr\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_addr\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_band\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_fd\n",     directiveType);
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

   }
Exemplo n.º 26
0
void MintCudaMidend::processLoopsInParallelRegion(SgNode* parallelRegionNode, 
						 MintHostSymToDevInitMap_t hostToDevVars,
						 ASTtools::VarSymSet_t& deviceSyms, 
						 MintSymSizesMap_t& trfSizes,
						 std::set<SgInitializedName*>& readOnlyVars,
						 const SgVariableSymbol* dev_struct)
{
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(parallelRegionNode, V_SgStatement);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();

  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
    {
      SgStatement* node = isSgStatement(*nodeListIterator);
   
      ROSE_ASSERT(node != NULL);
      switch (node->variantT())
        {
        case V_SgOmpForStatement:
          {
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
            cout << "  Processing Omp For Statement" << endl << endl;
#endif
	    //DataTransferSizes::findTransferSizes(node, trfSizes);
	
	    bool isBoundaryCond = LoweringToCuda::isBoundaryConditionLoop(node);
	    
	    SgFunctionDeclaration* kernel;
	
	    MintForClauses_t clauseList; 

	    //kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, readOnlyVars,clauseList, dev_struct) ;  	    
	    kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, clauseList, dev_struct) ;  	    

	    //swap anyways // x swapping is buggy, need to fix that before allowing x as well
	    if(clauseList.chunksize.x == 1 && ( clauseList.chunksize.z != 1 || clauseList.chunksize.y != 1 ))
	      {
		//if(MintOptions::GetInstance()->isSwapOpt())
		CudaOptimizer::swapLoopAndIf(kernel, clauseList);
	      }
	    if (!isBoundaryCond && MintOptions::GetInstance()->optimize())
	      //if (MintOptions::GetInstance()->optimize())
	      {
		cout << "\n\n  INFO:Mint: Optimization is ON. Optimizing ...\n\n" ;

		CudaOptimizer::optimize(kernel, clauseList);
	      } 
	    //  MintTools::printAllStatements(isSgNode(kernel));
	    //MintArrayInterface::linearizeArrays(kernel);
	    break;
          }
	default:
	  {
	    //cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    //cout << "  Currently we only handle for loops" << endl << endl;
	    
	    //do nothing
	    //currently we only handle for loops
	    break;
	  }
	}
    }
  
  
  for (ASTtools::VarSymSet_t::const_iterator i = deviceSyms.begin (); i!= deviceSyms.end (); ++i)
    {     
      SgVariableSymbol* sym= const_cast<SgVariableSymbol*> (*i);

      SgInitializedName* name = sym->get_declaration();
      SgType* type = name->get_type();
     
      if(isSgArrayType(type) || isSgPointerType(type)){
	
	//Check if is of the fields of the struct
	if(hostToDevVars.find(sym) == hostToDevVars.end())
	  {
	    string name_str = name->get_name().str();
	    
	    cerr << "  ERR:Mint: Ooops! Did you forget to insert a copy pragma for the variable ("<< name_str << ") ?"<< endl;
	    cerr << "  ERR:Mint: Please insert the copy pragma and compile again "<< endl;
	    cerr << "  INFO:Mint: Note that copy pragmas should appear right before and after a parallel region" << endl;
	    ROSE_ABORT();
	  }
      }
      }
}
Exemplo n.º 27
0
  // Count the load and store bytes for the 
  // I think we can only return expressions to calculate the value, not the actual values,
  // since sizeof(type) is machine dependent
  //   Consider both scalar and  array accesses by default. Consider both floating point and integer types by default.
  // return a pair of expressions:  
  //       load_byte_exp, and 
  //       store_byte_exp
  // Algorithm: 
  //    1.  Call side effect analysis to find read/write variables, some reference may trigger both read and write accesses
  //        Accesses to the same array/scalar variable are grouped into one read (or write) access
  //         e.g. array[i][j],  array[i][j+1],  array[i][j-1], etc are counted a single access
  //    2.  Group accesses based on the types (same type?  increment the same counter to shorten expression length)
  //    4.  Iterate on the results to generate expression like  2*sizeof(float) + 5* sizeof(double)
  // As an approximate, we use simple analysis here assuming no function calls.
  std::pair <SgExpression*, SgExpression*> CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars /* = true */, bool includeIntType /* = true */)
  {
    std::pair <SgExpression*, SgExpression*> result; 
    assert (input != NULL);
   // the input is essentially the loop body, a scope statement
    SgScopeStatement* scope = isSgScopeStatement(input);

    // We need to record the associated loop info.
    //SgStatement* loop= NULL;
    SgForStatement* forloop = isSgForStatement(scope->get_scope());
    SgFortranDo* doloop = isSgFortranDo(scope->get_scope());

    if (forloop)
    {
      //loop = forloop;
    }
    else if (doloop)
    {  
      //loop = doloop;
    }
    else
    {
      cerr<<"Error in CountLoadStoreBytes (): input is not loop body type:"<< input->class_name()<<endl;
      assert(false);
    }

    //Plan A: use and extend Qing's side effect analysis
    std::set<SgInitializedName*> readVars;
    std::set<SgInitializedName*> writeVars;

    bool success = SageInterface::collectReadWriteVariables (isSgStatement(input), readVars, writeVars);
    if (success!= true)
    {
       cout<<"Warning: CountLoadStoreBytes(): failed to collect load/store, mostly due to existence of function calls inside of loop body @ "<<input->get_file_info()->get_line()<<endl;
    }

    std::set<SgInitializedName*>::iterator it;
    if (debug)
      cout<<"debug: found read variables (SgInitializedName) count = "<<readVars.size()<<endl;
    for (it=readVars.begin(); it!=readVars.end(); it++)
    {
      SgInitializedName* iname = (*it);
      if (debug)
        cout<<scalar_or_array (iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
    }

    if (!includeScalars )
      readVars =  filterVariables (readVars);
    if (debug)
      cout<<"debug: found write variables (SgInitializedName) count = "<<writeVars.size()<<endl;
    for (it=writeVars.begin(); it!=writeVars.end(); it++)
    {
      SgInitializedName* iname = (*it);
      if (debug)
        cout<<scalar_or_array(iname->get_type()) <<" "<<iname->get_name()<<"@"<<iname->get_file_info()->get_line()<<endl;
    }
    if (!includeScalars )
      writeVars =  filterVariables (writeVars);
    result.first =  calculateBytes (readVars, scope, true);
    result.second =  calculateBytes (writeVars, scope, false);
    return result;
  }
Exemplo n.º 28
0
InheritedAttribute
visitorTraversal::evaluateInheritedAttribute(SgNode* n, InheritedAttribute inheritedAttribute)
   {
    Sg_File_Info* s = n->get_startOfConstruct();
    Sg_File_Info* e = n->get_endOfConstruct();
    Sg_File_Info* f = n->get_file_info();
    for(int x=0; x < inheritedAttribute.depth; ++x) {
        printf(" ");
    }
    if(s != NULL && e != NULL && !isSgLabelStatement(n)) { 
        printf ("%s (%d, %d, %d)->(%d, %d): %s",n->sage_class_name(),s->get_file_id()+1,s->get_raw_line(),s->get_raw_col(),e->get_raw_line(),e->get_raw_col(),  verbose ? n->unparseToString().c_str() : "" );
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
        SgExprStatement * exprStmt = isSgExprStatement(n);
        if(exprStmt != NULL) {
            printf(" [expr type: %s]", exprStmt->get_expression()->sage_class_name());           
            SgFunctionCallExp * fcall = isSgFunctionCallExp(exprStmt->get_expression());
            if(fcall != NULL) {
               SgExpression * funcExpr = fcall->get_function();
               if(funcExpr != NULL) {
                    printf(" [function expr: %s]", funcExpr->class_name().c_str());
               }
               SgFunctionDeclaration * fdecl = fcall->getAssociatedFunctionDeclaration();
               if(fdecl != NULL) {
                    printf(" [called function: %s]", fdecl->get_name().str());
               }
            }
        }
        if(isSgFunctionDeclaration(n)) {
            printf(" [declares function: %s]", isSgFunctionDeclaration(n)->get_name().str());
        }
        SgStatement * sgStmt = isSgStatement(n);
        if(sgStmt != NULL) {
            printf(" [scope: %s, %p]", sgStmt->get_scope()->sage_class_name(), sgStmt->get_scope());
        }
        //SgLabelStatement * lblStmt = isSgLabelStatement(n);
        //if(lblStmt != NULL) {
        //    SgStatement * lblStmt2 = lblStmt->get_statement();
        //}
    } else if (f != NULL) {
		SgInitializedName * iname = isSgInitializedName(n);
		if(iname != NULL) {
            SgType* inameType = iname->get_type();
			printf("%s (%d, %d, %d): %s [type: %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(),n->unparseToString().c_str(),inameType->class_name().c_str());
			SgDeclarationStatement * ds = isSgDeclarationStatement(iname->get_parent());
			if(ds != NULL) {
				if(ds->get_declarationModifier().get_storageModifier().isStatic()) {
					printf(" static");
				}
			}
			
			SgArrayType * art = isSgArrayType(iname->get_type());
			if(art != NULL) {
				printf(" %d", art->get_rank());
			}
			
			printf("]");
            if(isSgAsmDwarfConstruct(n)) {
                printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
            }
            } else {
        	printf("%s (%d, %d, %d): %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(), verbose ? n->unparseToString().c_str() : "");
		}
    } else {
        printf("%s : %s", n->sage_class_name(), verbose ? n->unparseToString().c_str() : "");
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
    }
    printf(" succ# %lu", n->get_numberOfTraversalSuccessors());
	printf("\n");
     return InheritedAttribute(inheritedAttribute.depth+1);
   }
Exemplo n.º 29
0
void
FixupTemplateArguments::visit ( SgNode* node )
   {
     ROSE_ASSERT(node != NULL);

     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);
     if (variableDeclaration != NULL)
        {
       // Check the type of the variable declaration, and any template arguments if it is a template type with template arguments.
       // SgType* type = variableDeclaration->get_type();
       // ROSE_ASSERT(type != NULL);
          SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration);
          ROSE_ASSERT(initializedName != NULL);
          SgType* type = initializedName->get_type();
          ROSE_ASSERT(type != NULL);
#if 0
          printf ("\n**************************************************************************** \n");
          printf ("FixupTemplateArguments::visit(): variableDeclaration = %p = %s initializedName = %s \n",variableDeclaration,variableDeclaration->class_name().c_str(),initializedName->get_name().str());
          printf ("   --- type = %p = %s \n",type,type->class_name().c_str());
          string filename = initializedName->get_file_info()->get_filename();
          int linenumber  = initializedName->get_file_info()->get_line();
          printf ("   --- filename = %s line = %d \n",filename.c_str(),linenumber);
#endif
          SgScopeStatement* targetScope = variableDeclaration->get_scope();
          ROSE_ASSERT(targetScope != NULL);
#if 0
          printf ("In FixupTemplateArguments::visit(): targetScope for variableDeclaration = %p = %s \n",targetScope,targetScope->class_name().c_str());
#endif

       // DQ (2/16/2017): Don't process code in template instantiations.
          SgTemplateInstantiationDefn*               templateInstantiationDefn              = isSgTemplateInstantiationDefn(targetScope);
          SgFunctionDeclaration*                     functionDeclaration                    = TransformationSupport::getFunctionDeclaration(targetScope);
          SgTemplateInstantiationFunctionDecl*       templateInstantiationFunctionDec       = isSgTemplateInstantiationFunctionDecl(functionDeclaration);
          SgTemplateInstantiationMemberFunctionDecl* templateInstantiationMemberFunctionDec = isSgTemplateInstantiationMemberFunctionDecl(functionDeclaration);
       // if (templateInstantiationDefn == NULL)
          if (templateInstantiationDefn == NULL && templateInstantiationFunctionDec == NULL && templateInstantiationMemberFunctionDec == NULL)
             {
#if 1
            // DQ (2/15/2017): When this is run, we cause transformations that cause ROSE to have an infinte loop.
            // Since this is a second (redundant) invocaion, we likely should just not run this.  But it is not 
            // clear if this truely fixes the problem that I am seeing.
               bool result = contains_private_type(type,targetScope);

            // DQ (3/25/2017): Added a trivial use to eliminate Clang warning about the return value not being used.
            // But it might be that we should not run the function, however this is a complex subject from last month 
            // that I don't wish to revisit at the moment while being focused om eliminating warnings from Clang.
               ROSE_ASSERT(result == true || result == false);
#endif
#if 0
               if (result == true)
                  {
                    printf ("******** contains private type: variableDeclaration = %p = %s initializedName = %s \n",variableDeclaration,variableDeclaration->class_name().c_str(),initializedName->get_name().str());
                  }
#endif
             }
#if 0
          printf ("DONE: FixupTemplateArguments::visit(): variableDeclaration = %p = %s initializedName = %s \n",variableDeclaration,variableDeclaration->class_name().c_str(),initializedName->get_name().str());
#endif
#if 0
          printf ("Exiting as a test! \n");
          ROSE_ASSERT(false);
#endif
        }
   }
int main(int argc, char **argv)
{
  SgProject *project = frontend(argc, argv);
  
  // Instantiate a class hierarchy wrapper.
  ClassHierarchyWrapper classHierarchy( project );

#if 0
  std::list<SgNode *> nodes2 = NodeQuery::querySubTree(project,
						      V_SgVariableDefinition);

  for (std::list<SgNode *>::iterator it = nodes2.begin();
       it != nodes2.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgVariableDefinition *varDefn =
      isSgVariableDefinition(n);
    ROSE_ASSERT(varDefn != NULL);

    std::cout << "Var defn: " << varDefn->unparseToCompleteString() << std::endl;

  }

  std::list<SgNode *> nodes1 = NodeQuery::querySubTree(project,
						      V_SgVariableDeclaration);

  for (std::list<SgNode *>::iterator it = nodes1.begin();
       it != nodes1.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgVariableDeclaration *varDecl =
      isSgVariableDeclaration(n);
    ROSE_ASSERT(varDecl != NULL);

    SgInitializedNamePtrList &variables =
      varDecl->get_variables();
    SgInitializedNamePtrList::iterator varIter;
    for (varIter = variables.begin(); 
	 varIter != variables.end(); ++varIter) {
      
      SgNode *var = *varIter;
      ROSE_ASSERT(var != NULL);
      
      SgInitializedName *initName =
	isSgInitializedName(var);
      ROSE_ASSERT(initName != NULL);
      
      if ( isSgClassType(initName->get_type()) ) {

	SgClassType *classType = isSgClassType(initName->get_type());
	ROSE_ASSERT(classType != NULL);

	SgDeclarationStatement *declStmt = classType->get_declaration();
	ROSE_ASSERT(declStmt != NULL);
	
	SgClassDeclaration *classDeclaration = isSgClassDeclaration(declStmt);
	ROSE_ASSERT(classDeclaration != NULL);
      
	//	std::cout << "From var decl got: " << classDeclaration->unparseToCompleteString() << std::endl;

	SgClassDefinition *classDefinition =
	  classDeclaration->get_definition();
	if ( classDefinition != NULL ) {
	  std::cout << "From var decl got: " << classDefinition->unparseToCompleteString() << std::endl;
	}

      }

    }
    

  }

  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgClassDeclaration);

  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgClassDeclaration *classDeclaration1 =
      isSgClassDeclaration(n);
    ROSE_ASSERT(classDeclaration1 != NULL);

    SgDeclarationStatement *definingDecl =
      classDeclaration1->get_definingDeclaration();
    if ( definingDecl == NULL )
      continue;
    
    SgClassDeclaration *classDeclaration =
      isSgClassDeclaration(definingDecl);
    ROSE_ASSERT(classDeclaration != NULL);


    SgClassDefinition *classDefinition =
      classDeclaration->get_definition();
    ROSE_ASSERT(classDefinition != NULL);

    std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl;

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

    // Iterate over all subclasses.
    for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	 subclassIt != subclasses.end(); ++subclassIt) {
      
      SgClassDefinition *subclass = *subclassIt;
      ROSE_ASSERT(subclass != NULL);
      
      std::cout << "subclass" << std::endl;

    }

  }
#endif
#if 1
#if 0
  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgClassDefinition);

  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgClassDefinition *classDefinition =
      isSgClassDefinition(n);
    ROSE_ASSERT(classDefinition != NULL);

    std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl;

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

    // Iterate over all subclasses.
    for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	 subclassIt != subclasses.end(); ++subclassIt) {
      
      SgClassDefinition *subclass = *subclassIt;
      ROSE_ASSERT(subclass != NULL);
      
      std::cout << "subclass" << std::endl;

    }

  }
#else
  // Collect all function/method invocations.
  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgFunctionCallExp);

  unsigned int numCallSites = 0;
  unsigned int numMonomorphicCallSites = 0;
  unsigned int numPossibleResolutions = 0;

  // Visit each call site.
  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgFunctionCallExp *functionCallExp =
      isSgFunctionCallExp(n);
    ROSE_ASSERT(functionCallExp != NULL);

    // We are only interested in examining method invocations.
    bool isDotExp = false;
    bool isLhsRefOrPtr = false;

    //    std::cout << "method?: " << functionCallExp->unparseToCompleteString() << std::endl;

    if ( !isMethodCall(functionCallExp, isDotExp, isLhsRefOrPtr) )
      continue;
    
    //    std::cout << "method: " << functionCallExp->unparseToCompleteString() << std::endl;

    numCallSites++;

    if ( isDotExp && !isLhsRefOrPtr ) {
      // If this is a dot expression (i.e., a.foo()), we can
      // statically determine its type-- unless the left-hand
      // side is a reference type.
      numMonomorphicCallSites++;
      numPossibleResolutions++;
      //      std::cout << "dot: " << functionCallExp->unparseToCompleteString() << std::endl;
      continue;
    }

    //    std::cout << "methodPtr: " << functionCallExp->unparseToCompleteString() << std::endl;

    // Retrieve the static function declaration.
    SgFunctionDeclaration *functionDeclaration = 
      getFunctionDeclaration(functionCallExp);

    // Ensure it is actually a method declaration.
    SgMemberFunctionDeclaration *memberFunctionDeclaration =
      isSgMemberFunctionDeclaration(functionDeclaration);
    ROSE_ASSERT(memberFunctionDeclaration != NULL);

    unsigned int numResolutionsForMethod = 0;

    // Certainly can be resolved to the static method (unless it
    // is pure virtual).
    if ( !isPureVirtual(memberFunctionDeclaration) ) {
      numResolutionsForMethod++;
    }

#if 0
    if ( ( isVirtual(functionDeclaration) ) ||
	 ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) {
#else
      if ( isVirtual(functionDeclaration) ) {
#endif      
      //      std::cout << "tracking: " << functionDeclaration->unparseToString() << std::endl;

      SgClassDefinition *classDefinition = 
	isSgClassDefinition(memberFunctionDeclaration->get_scope());
      ROSE_ASSERT(classDefinition != NULL);
      
      SgClassDefinitionPtrList subclasses = 
	classHierarchy.getSubclasses(classDefinition);

      // Iterate over all subclasses.
      for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	   subclassIt != subclasses.end(); ++subclassIt) {

	SgClassDefinition *subclass = *subclassIt;
	ROSE_ASSERT(subclass != NULL);

	//	std::cout << "subclass" << std::endl;

	// Iterate over all of the methods defined in this subclass.
	SgDeclarationStatementPtrList &decls =
	  subclass->get_members();
	for (SgDeclarationStatementPtrList::iterator declIter = decls.begin();
	     declIter != decls.end(); ++declIter) {

	  SgDeclarationStatement *declStmt = *declIter;
	  ROSE_ASSERT(declStmt != NULL);

	  SgMemberFunctionDeclaration *method =
	    isSgMemberFunctionDeclaration(declStmt);
	  if ( method == NULL ) {
	    continue;
	  }

	  //	  std::cout << "checking overrides" << std::endl;
	  // Determine whether subclass of the class defining this
	  // method overrides the method.
#if 1
	  if ( matchingFunctions(method,
				       memberFunctionDeclaration) ) {
	    //	    std::cout << "overries" << std::endl;
	    // Do not consider a pure virtual method to be an 
	    // overriding method (since it can not be invoked).
	    if ( !isPureVirtual(method) ) {
	      numResolutionsForMethod++;
	    }
	  }
#else
	  if ( methodOverridesVirtualMethod(method, 
					    memberFunctionDeclaration) ) {
	    //	    std::cout << "overries" << std::endl;
	    numResolutionsForMethod++;
	  }
#endif
	}

      }

      if ( numResolutionsForMethod <= 1 )
	numMonomorphicCallSites++;
      numPossibleResolutions += numResolutionsForMethod;

      if ( ( numResolutionsForMethod ) > 1 ) {
	std::cout << "Method invocation has " << numResolutionsForMethod << " possible resolutions " << std::endl;
	std::cout << functionCallExp->unparseToCompleteString() << std::endl;
      }
    }

  }
#endif
#endif
  return 0;
}