/* * The function * queryNodePragmaDeclarationFromName() * takes as a first parameter a SgNode*. As a second parameter it takes * a SgNode* who must be of type SgName. The SgName contains a std::string which * should be the same as the left side in the pragma or a part of the left * side of the pragma. If the std::string is empty, * there will be an error message. * * #pragma std::stringInSgNode = information * */ Rose_STL_Container<SgNode*> NodeQuery::queryNodePragmaDeclarationFromName(SgNode* node, SgNode* nameNode){ ROSE_ASSERT( nameNode != NULL ); ROSE_ASSERT( node != NULL ); Rose_STL_Container<SgNode*> returnList; //finds the name which should be matched to SgName* sageName = isSgName(nameNode); ROSE_ASSERT( sageName != NULL ); std::string nameToMatch = sageName->str(); ROSE_ASSERT( nameToMatch.length() > 0 ); if(node->variantT() == V_SgPragmaDeclaration){ SgPragmaDeclaration* sagePragmaDeclaration = isSgPragmaDeclaration(node); ROSE_ASSERT( sagePragmaDeclaration ); ROSE_ASSERT( sagePragmaDeclaration->get_pragma() != NULL ); // ROSE_ASSERT( sagePragmaDeclaration->get_pragma()->get_pragma() ); std::string pragmaDeclarationString = sagePragmaDeclaration->get_pragma()->get_pragma(); //extract the part before the leftmost = is pragmaDeclarationString pragmaDeclarationString = pragmaDeclarationString.substr(0,pragmaDeclarationString.find("=")); //if the name-criteria is met accept node if(pragmaDeclarationString.find( nameToMatch ) != pragmaDeclarationString.length() ){ cout << pragmaDeclarationString << endl; returnList.push_back(node); } } return returnList; }
/* * The function * queryPragmaString() * teakes a SgNode* as a parameter and return a list<string>. It is a NameQuery * which query the AST or a subtree of the AST for the string of all the * SgPragma's. * */ Rose_STL_Container< string > queryFindPragmaString (SgNode * node) { Rose_STL_Container< string > returnList; if (node->variantT () == V_SgPragmaDeclaration) { SgPragmaDeclaration *sagePragmaStatement = isSgPragmaDeclaration (node); ROSE_ASSERT (sagePragmaStatement); ROSE_ASSERT (sagePragmaStatement->get_pragma () != NULL); returnList.push_back (sagePragmaStatement->get_pragma ()-> get_pragma ()); } return returnList; }
POETCode* ROSE_2_POET_list(PtrList& l, POETCode* res, SgTemplateInstantiationFunctionDecl* tmp) { static POETCode* tmpPars=0; if (l.size() == 1) { /* return the only element inside the list */ return POETAstInterface::Ast2POET(*l.begin()); } typename PtrList::const_reverse_iterator p = l.rbegin(); if (p == l.rend()) return (res==0)? EMPTY : res; SgNode* prev2 = (SgNode*)*p; POETCode* prev = POETAstInterface::Ast2POET(prev2); for (++p; p != l.rend(); ++p) { SgNode* cur = (SgNode*)*p; SgPragmaDeclaration* info = isSgPragmaDeclaration(cur); if (info!=0) { /* replace template parameters in pragma */ POETAstInterface::set_Ast2POET(prev2, EMPTY); std::string pragma_str = info->get_pragma()->get_pragma(); POETCode *content=STRING(pragma_str); POETCode* tokens = split_string("",content); if (tmp == 0) tmpPars = 0; else { const SgTemplateArgumentPtrList& args= tmp->get_templateArguments(); if (tmpPars == 0) tmpPars=get_template_parameters(tmp->get_templateDeclaration ()->get_string()); POETCode* pars = tmpPars; for (SgTemplateArgumentPtrList::const_iterator p2 = args.begin(); p2 != args.end(); p2++) { POETCode* from = get_head(pars); pars=get_tail(pars); POETCode* to = STRING((*p2)->unparseToString()); tokens = eval_replace(from, to, tokens); } } prev = new POETCode_ext(info, PAIR(tokens, prev)); POETAstInterface::set_Ast2POET(info,prev); } else { res = LIST(prev, res); prev = POETAstInterface::Ast2POET((SgNode*)cur); } } res = LIST(prev,res); return res; }
//! Parse failsafe directives and generate/attach attributes // follow the code in void attachOmpAttributeInfo(SgSourceFile *sageFilePtr) of ompAstConstruction.cpp void FailSafe::parse_directives_to_attributes(SgSourceFile* sageFilePtr) { ROSE_ASSERT(sageFilePtr != NULL); //TODO check language extension flag for turning on this support //if (sageFilePtr->get_failsafe() == false) return if (sageFilePtr->get_Fortran_only()||sageFilePtr->get_F77_only()||sageFilePtr->get_F90_only()| sageFilePtr->get_F95_only() || sageFilePtr->get_F2003_only()) { //TODO handle Fortran later } else { // For C/C++, search pragma declarations for failsafe directives std::vector <SgNode*> all_pragmas = NodeQuery::querySubTree (sageFilePtr, V_SgPragmaDeclaration); std::vector<SgNode*>::iterator iter; for(iter=all_pragmas.begin();iter!=all_pragmas.end();iter++) { SgPragmaDeclaration* pragmaDeclaration = isSgPragmaDeclaration(*iter); ROSE_ASSERT(pragmaDeclaration != NULL); SageInterface::replaceMacroCallsWithExpandedStrings(pragmaDeclaration); string pragmaString = pragmaDeclaration->get_pragma()->get_pragma(); istringstream istr(pragmaString); std::string key; istr >> key; if (key == "failsafe") { FailSafe::AttributeList * previous = FailSafe::getAttributeList (pragmaDeclaration); FailSafe::pragma_list.push_back(pragmaDeclaration); if (previous == NULL) { FailSafe::Attribute* attribute = parse_fail_safe_directive(pragmaDeclaration); FailSafe::addAttribute(attribute, pragmaDeclaration); } // end if NULL } // end if key is failsafe } // end for all_pragmas } // end if }
void MintCudaMidend::mintPragmasFrontendProcessing(SgSourceFile* file) { Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(file, V_SgPragmaDeclaration); Rose_STL_Container<SgNode*>::iterator nodeListIterator = nodeList.begin(); for ( ;nodeListIterator !=nodeList.end(); ++nodeListIterator) { SgPragmaDeclaration* node = isSgPragmaDeclaration(*nodeListIterator); ROSE_ASSERT(node != NULL); switch (node->variantT()) { case V_SgPragmaDeclaration: { //soley checks syntax of mint pragmas MintPragmas::isMintPragma(node); break; } default: break; } } }
void mlmFrontend::visit(SgNode* node) { if (isSgPragmaDeclaration(node) != NULL) { SgPragmaDeclaration * pragDecl = isSgPragmaDeclaration(node); char* end; int type = strtol(pragDecl->get_pragma()->get_pragma().c_str(),&end, 10); if(end == pragDecl->get_pragma()->get_pragma().c_str()) { cout << "pragma has no integer value" << endl; type = -1; } if(type >= 0) { //cout << "type = " << type << endl; mlmAttribute* newAttr = new mlmAttribute(type); mlmFrontend::attachAttribute(pragDecl, newAttr); DeletepragmasList.push_back(pragDecl); } // handle omp parallel, omp for, omp single, ..etc. //createOmpAttributeOld(node); } }
// 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; }
Rose_STL_Container< ControlStructureContainer * >queryFindCommentsInScope (const string stringPrefixToMatch, const string stringToMatch, SgScopeStatement * sageScopeStatement) { ROSE_ASSERT (stringPrefixToMatch.length () > 0); ROSE_ASSERT (stringToMatch.length () > 0); ROSE_ASSERT (sageScopeStatement != NULL); Rose_STL_Container< ControlStructureContainer * >returnList; //find all pragmas who match the stringToMatch //cout << "Before pragma search" << endl; /*list < SgNode * >pragmaStatements = NodeQuery::querySubTree (sageScopeStatement, new SgName (stringToMatch.c_str ()), NodeQuery::PragmaDeclarationFromName); */ //list<SGNode*> pragmaStatements ; //cout << "After pragma search" << endl; /* cout << "BEFORE LIST" << endl; list < SgNode * >pragmaStatements = queryNodePragmaStatementFromName2(sageScopeStatement, new SgName(stringToMatch.c_str())); cout << "AFTER LIST" << endl;*/ //return the pragmas in containers /* for (list < SgNode * >::iterator i = pragmaStatements.begin (); i != pragmaStatements.end (); ++i) { SgPragmaDeclaration *sagePragma = isSgPragmaDeclaration (*i); ROSE_ASSERT (sagePragma); ROSE_ASSERT (sagePragma->get_pragma () != NULL); ROSE_ASSERT (sagePragma->get_pragma ()->get_pragma ()); ControlStructureContainer *container = new ControlStructureContainer (); container->setPragmaString (sagePragma->get_pragma ()->get_pragma ()); container->setAssociatedStatement (sagePragma); returnList.push_back (container); } */ //find all statements in the current scope if (sageScopeStatement->variantT () == V_SgClassDefinition) { SgDeclarationStatementPtrList statementsInScope = sageScopeStatement->getDeclarationList (); SgDeclarationStatementPtrList::iterator i; for (i = statementsInScope.begin (); i != statementsInScope.end (); i++) { SgLocatedNode *locatedNode = isSgLocatedNode (*i); ROSE_ASSERT (locatedNode != NULL); //find all comments attached to current node. AttachedPreprocessingInfoType *comments = locatedNode->getAttachedPreprocessingInfo (); if(locatedNode->variantT() == V_SgPragmaDeclaration){ SgPragmaDeclaration* sagePragmaDeclaration = isSgPragmaDeclaration(locatedNode); ROSE_ASSERT( sagePragmaDeclaration ); ROSE_ASSERT( sagePragmaDeclaration->get_pragma() != NULL ); string pragmaDeclarationString = sagePragmaDeclaration->get_pragma()->get_pragma(); //extract the part before the leftmost = is pragmaDeclarationString pragmaDeclarationString = pragmaDeclarationString.substr(0,pragmaDeclarationString.find("=")); //if the name-criteria is met accept node if(pragmaDeclarationString.find( stringToMatch ) != string::npos ){ cout << pragmaDeclarationString << endl; ControlStructureContainer *container = new ControlStructureContainer (); container->setPragmaString (sagePragmaDeclaration->get_pragma ()->get_pragma ()); container->setAssociatedStatement (sagePragmaDeclaration); returnList.push_back (container); } } if (comments != NULL) { //We need to find comments which fits the criteria printf ("Found attached comments (at %p of type: %s): \n", locatedNode, locatedNode->sage_class_name ()); AttachedPreprocessingInfoType::iterator j; for (j = comments->begin (); j != comments->end (); j++) { ROSE_ASSERT ((*j) != NULL); string comment = (*j)->getString (); //see if comment begins with stringPrefixToMatch string tempString = comment.substr (0, comment.find (' ')); if (tempString == stringPrefixToMatch) { //+stringPrefixToMatch ){ //cout << "Found string" << endl; comment = StringUtility::copyEdit (comment, stringPrefixToMatch, ""); //see if the comment has an element which matches the stringToMatch if (comment.find (stringToMatch) != string::npos) { //puit the matching comment into a container ControlStructureContainer *container = new ControlStructureContainer (); container->setPragmaString (comment); container->setAssociatedStatement (locatedNode); returnList.push_back (container); } } // printf (" Attached Comment (relativePosition=%s):\n %s\n Next comment: \n", // ((*j)->relativePosition == PreprocessingInfo::before) ? "before" : "after",(*j)->getString()); } } } } else { // AS 12/18/03 PS!! The same as the above, but a different iterator. Will replace this when a // different solution has arisen. PS!! SgStatementPtrList statementsInScope = sageScopeStatement->getStatementList (); SgStatementPtrList::iterator i; for (i = statementsInScope.begin (); i != statementsInScope.end (); i++) { SgLocatedNode *locatedNode = isSgLocatedNode (*i); ROSE_ASSERT (locatedNode != NULL); if(locatedNode->variantT() == V_SgPragmaDeclaration){ SgPragmaDeclaration* sagePragmaDeclaration = isSgPragmaDeclaration(locatedNode); ROSE_ASSERT( sagePragmaDeclaration ); ROSE_ASSERT( sagePragmaDeclaration->get_pragma() != NULL ); string pragmaDeclarationString = sagePragmaDeclaration->get_pragma()->get_pragma(); //extract the part before the leftmost = is pragmaDeclarationString pragmaDeclarationString = pragmaDeclarationString.substr(0,pragmaDeclarationString.find("=")); //if the name-criteria is met accept node if(pragmaDeclarationString.find( stringToMatch ) != string::npos ){ cout << pragmaDeclarationString << endl; ControlStructureContainer *container = new ControlStructureContainer (); container->setPragmaString (sagePragmaDeclaration->get_pragma ()->get_pragma ()); container->setAssociatedStatement (sagePragmaDeclaration); returnList.push_back (container); } } //find all comments attached to current node. AttachedPreprocessingInfoType *comments = locatedNode->getAttachedPreprocessingInfo (); if (comments != NULL) { //We need to find comments which fits the criteria //printf ("Found attached comments (at %p of type: %s): \n",locatedNode,locatedNode->sage_class_name()); AttachedPreprocessingInfoType::iterator j; for (j = comments->begin (); j != comments->end (); j++) { ROSE_ASSERT ((*j) != NULL); string comment = (*j)->getString (); //see if comment begins with stringPrefixToMatch string tempString = comment.substr (0, comment.find (' ')); if (tempString == stringPrefixToMatch) { //+stringPrefixToMatch ){ comment = StringUtility::copyEdit (comment, stringPrefixToMatch, ""); cout << "And the string is: " << comment << endl; if (comment.find (stringToMatch) != string::npos) { cout << "And even the string is matched." << endl; //ROSE_ASSERT(comment.find('=') != comment.length()); //string variableName = comment.substr(comment.find(stringToMatch), comment.find('=')); cout << "And the string is a match" << endl; //puit the matching comment into a container ControlStructureContainer *container = new ControlStructureContainer (); container->setPragmaString (comment); container->setAssociatedStatement (locatedNode); returnList.push_back (container); } } /* printf (" Attached Comment (relativePosition=%s):\n %s\n Next comment: \n", ((*j)->relativePosition == PreprocessingInfo::before) ? "before" : "after", (*j)->getString ());*/ } } } } return returnList; } /* End function: queryFindCommentsInScope() */
// 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) { 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())); 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(); SgFunctionDefinition* fundef = fundecl->get_definition(); 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); // thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, new SgAssignInitializer(SgNULL_FILE, thisptr)); thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer); 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); // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl); // DQ (6/23/2006): New test ROSE_ASSERT(assignInitializer->get_parent() != NULL); } std::cout << "Trying to inline function " << fundecl->get_name().str() << std::endl; SgBasicBlock* funbody_raw = fundef->get_body(); SgInitializedNamePtrList& params = fundecl->get_args(); SgInitializedNamePtrList::iterator i; SgExpressionPtrList& funargs = funcall->get_args()->get_expressions(); SgExpressionPtrList::iterator j; //int ctr; // unused variable, Liao std::vector<SgInitializedName*> inits; SgTreeCopy tc; SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc)); ROSE_ASSERT (function_copy); SgBasicBlock* funbody_copy = function_copy->get_body(); SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall); renameLabels(funbody_copy, targetFunction); std::cout << "Original symbol count: " << funbody_raw->get_symbol_table()->size() << std::endl; std::cout << "Copied symbol count: " << funbody_copy->get_symbol_table()->size() << std::endl; // std::cout << "Original symbol count f: " << fundef->get_symbol_table()->size() << std::endl; // std::cout << "Copied symbol count f: " << function_copy->get_symbol_table()->size() << std::endl; // We don't need to keep the copied function definition now that the // labels in it have been moved to the target function. Having it in the // memory pool confuses the AST tests. function_copy->set_declaration(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 ReplaceParameterUseVisitor::paramMapType paramMap; for (i = params.begin(), j = funargs.begin(); i != params.end() && j != funargs.end(); ++i, ++j) { SgAssignInitializer* ai = new SgAssignInitializer(SgNULL_FILE, *j, (*i)->get_type()); ROSE_ASSERT(ai != NULL); ai->set_endOfConstruct(SgNULL_FILE); SgName shadow_name((*i)->get_name()); shadow_name << "__" << ++gensym_counter; SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE,shadow_name,(*i)->get_type(),ai); vardecl->set_definingDeclaration(vardecl); vardecl->set_endOfConstruct(SgNULL_FILE); vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE); printf ("Built new SgVariableDeclaration #2 = %p = %s initializer = %p \n",vardecl,shadow_name.str(),(*(vardecl->get_variables().begin()))->get_initializer()); vardecl->set_parent(funbody_copy); SgInitializedName* init = (vardecl->get_variables()).back(); // init->set_endOfConstruct(SgNULL_FILE); inits.push_back(init); ai->set_parent(init); init->set_scope(funbody_copy); funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + (i - params.begin()), vardecl); SgVariableSymbol* sym = new SgVariableSymbol(init); paramMap[*i] = sym; funbody_copy->insert_symbol(shadow_name, sym); sym->set_parent(funbody_copy->get_symbol_table()); } 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() = %zu \n",funbody_raw->get_statements().size()); printf ("funbody_copy->get_statements().size() = %zu \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 // printf ("Exiting as a test after testing the symbol table \n"); // ROSE_ASSERT(false); 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 // std::cout << "funbody_copy is " << funbody_copy->unparseToString() << std::endl; ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy); // std::cout << "funbody_copy 2 is " << funbody_copy->unparseToString() << std::endl; replaceExpressionWithStatement(funcall, &previsitor); // std::cout << "Inline succeeded " << funcall->get_parent()->unparseToString() << std::endl; return true; }
void MintCudaMidend::processDataTransferPragmas(SgNode* parallel_reg, MintHostSymToDevInitMap_t& hostToDevVars) { //1. first handle the copy pragmas preceeding the parallel region //2. then handle the pragmas inside of the parallel region //3. second handle the copy pragmas proceeding the parallel region //1. first handle the copy pragmas preceeding the parallel region SgStatement* prev = getPreviousStatement(isSgStatement(parallel_reg)); vector <SgStatement*> copyList; while(prev != NULL) { SgPragmaDeclaration* pragma = isSgPragmaDeclaration(prev); if(pragma != NULL && MintPragmas::isTransferToFromDevicePragma(pragma)){ copyList.push_back(prev); } else break; prev = getPreviousStatement(prev); //continue processing copy pragmas }//end of while for(vector<SgStatement*>::reverse_iterator it=copyList.rbegin() ; it!= copyList.rend(); it++ ) { SgPragmaDeclaration* pragma = isSgPragmaDeclaration(*it); MintTrfParams_t params = MintPragmas::getTransferParameters(pragma, hostToDevVars); if(params.trfType == MINT_DATA_TRF_TO_DEV_PRAGMA){ CudaMemoryManagement::issueDataTransferToDevice(pragma, params, hostToDevVars); #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << pragma->get_file_info()->get_line() << endl << " Issue Data Transfers to Device " << "(dest: "<< params.dst << " ,src: "<< params.src << ")"<< endl << endl; #endif } /* else { cout << " WARNING:Mint: @ Line " << pragma->get_file_info()->get_line() << endl << " Expecting a copy to device..." << endl << " Want to merge two parallel regions? or change the transfer type?" << endl << endl; } */ } //this is the INSIDE list //2.step then handle the pragmas inside of the parallel region Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(parallel_reg, V_SgPragmaDeclaration); Rose_STL_Container<SgNode*>::iterator nodeListIterator = nodeList.begin(); for ( ;nodeListIterator !=nodeList.end(); ++nodeListIterator) { SgPragmaDeclaration* node = isSgPragmaDeclaration(*nodeListIterator); ROSE_ASSERT(node != NULL); if(MintPragmas::isTransferToFromDevicePragma(node)){ bool inside = true; MintTrfParams_t params = MintPragmas::getTransferParameters(node, hostToDevVars); if(params.trfType == MINT_DATA_TRF_TO_DEV_PRAGMA){ CudaMemoryManagement::issueDataTransferToDevice(node, params, hostToDevVars, inside); #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << node->get_file_info()->get_line() << endl << " Issue Data Transfers to Device " << "(dest: "<< params.dst << " ,src: "<< params.src << ")"<< endl << endl; #endif } else if (params.trfType == MINT_DATA_TRF_FROM_DEV_PRAGMA){ CudaMemoryManagement::issueDataTransferFromDevice(node, params, hostToDevVars, inside); #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << node->get_file_info()->get_line() << endl << " Issue Data Transfers to Host " << "(dest: "<< params.dst << " ,src: "<< params.src << ")"<< endl << endl; #endif } else { cout << " ERROR:Mint: @ Line " << node->get_file_info()->get_line() << endl << " Unrecognized transfer type " << endl << endl; ROSE_ABORT(); } } } //3. step handle the copy pragmas proceeding the parallel region SgStatement* post = getNextStatement(isSgStatement(parallel_reg)); copyList.clear(); while(post != NULL) { SgPragmaDeclaration* pragma = isSgPragmaDeclaration(post); if(pragma != NULL && MintPragmas::isTransferToFromDevicePragma(pragma)){ copyList.push_back(post); } else break; post = getNextStatement(post); //continue processing copy pragmas }//end of while //here we want to free the allocated memory for all the hostToDevVars vars //post statement is where we are going to free them. CudaMemoryManagement::freeParallelRegionVars(post, hostToDevVars); //We want to keep a list of variables that we freed //because next step (step 3) may add new variables to free //We will free them afterwords MintHostSymToDevInitMap_t hostToDevVars_tmp; for(MintHostSymToDevInitMap_t::iterator it = hostToDevVars.begin() ; it != hostToDevVars.end() ; it++ ) { SgVariableSymbol* host_sym = it->first ; SgInitializedName* dev_name = it->second; hostToDevVars_tmp [host_sym] = dev_name; } for(vector<SgStatement*>::iterator it=copyList.begin() ; it!= copyList.end(); it++ ) { SgPragmaDeclaration* pragma = isSgPragmaDeclaration(*it); MintTrfParams_t params = MintPragmas::getTransferParameters(pragma, hostToDevVars); if(params.trfType == MINT_DATA_TRF_FROM_DEV_PRAGMA){ CudaMemoryManagement::issueDataTransferFromDevice(pragma, params, hostToDevVars); #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << pragma->get_file_info()->get_line() << endl << " Issue Data Transfers form Device " << "(dest: "<< params.dst << " ,src: "<< params.src << ")"<< endl << endl; #endif } /* else { cout << " WARNING:Mint: @ Line " << pragma->get_file_info()->get_line() << endl << " Expecting a copy to device..." << endl << " Want to merge two parallel regions? or change the transfer type?" << endl << endl; } */ } MintHostSymToDevInitMap_t hostToDevVars_freeList; for(MintHostSymToDevInitMap_t::iterator it = hostToDevVars.begin() ; it != hostToDevVars.end() ; it++ ) { //this is new variable, need to free this one SgVariableSymbol* host_sym = it->first ; if(hostToDevVars_tmp.find(host_sym) == hostToDevVars_tmp.end() ) { SgInitializedName* dev_name = it->second; hostToDevVars_freeList [host_sym] = dev_name; } } //here we want to free the allocated memory for all the hostToDevVars vars //post statement is where we are going to free them. CudaMemoryManagement::freeParallelRegionVars(post, hostToDevVars_freeList); }