void OpenMP_PreTransform::purge_local_threadprivates() { ObjectList<Symbol> involved_functions = get_all_functions(_function_sym_list); for (ObjectList<Symbol>::iterator it = involved_functions.begin(); it != involved_functions.end(); it++) { Symbol &funct_sym(*it); AST_t funct_point_of_decl = funct_sym.get_point_of_declaration(); ObjectList<Symbol> local_syms = get_symbols_of_function(_function_sym_list, funct_sym); Source pragma_line, threadprivate_args; pragma_line << "#pragma omp threadprivate(" << threadprivate_args ; TL::ReplaceIdExpression replacement; for (ObjectList<Symbol>::iterator localsym_it = local_syms.begin(); localsym_it != local_syms.end(); localsym_it++) { Symbol &local_sym(*localsym_it); Type type = local_sym.get_type(); Source global_var_name; global_var_name << "__" << funct_sym.get_name() << "_" << _function_num << "_" << local_sym.get_name(); replacement.add_replacement(local_sym, global_var_name); threadprivate_args.append_with_separator(global_var_name, ","); // FIXME - In C++ we have to be careful where we put this new declaration // Templates will mess things -> Scope must be judiciously chosen Source global_decl_src; global_decl_src << "static " << type.get_declaration(local_sym.get_scope(), global_var_name) << ";" ; // FIXME - C++! AST_t global_decl_tree = global_decl_src.parse_global( funct_point_of_decl, _scope_link); // 1. Declare globally just before the function funct_point_of_decl.prepend(global_decl_tree); } pragma_line << ")\n"; // 2. Add the pragma line with all local symbols AST_t pragma_line_tree = pragma_line.parse_global( funct_point_of_decl, _scope_link); funct_point_of_decl.prepend(pragma_line_tree); for (ObjectList<Symbol>::iterator localsym_it = local_syms.begin(); localsym_it != local_syms.end(); localsym_it++) { Symbol &local_sym(*localsym_it); remove_symbol_declaration(local_sym); } FunctionDefinition funct_def(funct_point_of_decl, _scope_link); Statement function_body = funct_def.get_function_body(); // 4. Change old references to the new ones Statement replaced_function_body = replacement.replace(function_body); function_body.get_ast().replace(replaced_function_body.get_ast()); // Next function number _function_num++; } }
void CLVariable::ParseUnusedVars() { std::set<const Variable*> accesses; std::set<const Variable*> expr_vars; for (Function * f : get_all_functions()) { for (Block * b : f->blocks) { Helpers::RecordVarInitialisation(&accesses, b); for (Statement * s : b->stms) { switch(s->eType) { case eAssign: { StatementAssign* as = dynamic_cast<StatementAssign*>(s); const Variable* lhsv = as->get_lhs()->get_var()->get_collective(); Helpers::GetVarsFromExpr(&expr_vars, as->get_expr()); Helpers::RecordVar(&accesses, lhsv); Helpers::RecordMultipleVars(&accesses, &expr_vars); break; } case eReturn: { StatementReturn* rs = dynamic_cast<StatementReturn*>(s); const Variable* rsv = rs->get_var()->get_var()->get_collective(); Helpers::RecordVar(&accesses, rsv); break; } case eFor: { StatementFor* sf = dynamic_cast<StatementFor*>(s); const Variable* initlhsv = sf->get_init()->get_lhs()->get_var()->get_collective(); const Variable* incrlhsv = sf->get_init()->get_lhs()->get_var()->get_collective(); Helpers::GetVarsFromExpr(&expr_vars, sf->get_init()->get_expr()); Helpers::RecordMultipleVars(&accesses, &expr_vars); Helpers::GetVarsFromExpr(&expr_vars, sf->get_test()); Helpers::RecordMultipleVars(&accesses, &expr_vars); Helpers::GetVarsFromExpr(&expr_vars, sf->get_incr()->get_expr()); Helpers::RecordMultipleVars(&accesses, &expr_vars); Helpers::RecordVar(&accesses, initlhsv); Helpers::RecordVar(&accesses, incrlhsv); break; } case eIfElse: { StatementIf* si = dynamic_cast<StatementIf*>(s); Helpers::GetVarsFromExpr(&expr_vars, si->get_test()); Helpers::RecordMultipleVars(&accesses, &expr_vars); break; } case eInvoke: { StatementExpr* se = dynamic_cast<StatementExpr*>(s); Helpers::GetVarsFromExpr(&expr_vars, se->get_call()); Helpers::RecordMultipleVars(&accesses, &expr_vars); break; } case eContinue: { StatementContinue* sc = dynamic_cast<StatementContinue*>(s); Helpers::GetVarsFromExpr(&expr_vars, &sc->test); Helpers::RecordMultipleVars(&accesses, &expr_vars); break; } case eBreak: { StatementBreak* sb = dynamic_cast<StatementBreak*>(s); Helpers::GetVarsFromExpr(&expr_vars, &sb->test); Helpers::RecordMultipleVars(&accesses, &expr_vars); break; } case eGoto: { StatementGoto* sg = dynamic_cast<StatementGoto*>(s); Helpers::GetVarsFromExpr(&expr_vars, &sg->test); Helpers::RecordMultipleVars(&accesses, &expr_vars); break; } case eArrayOp: { StatementArrayOp* sao = dynamic_cast<StatementArrayOp*>(s); const Variable* arrv = sao->array_var->get_collective(); std::set<const Variable*> ctrlv (sao->ctrl_vars.begin(), sao->ctrl_vars.end()); Helpers::GetVarsFromExpr(&expr_vars, sao->init_value); Helpers::RecordMultipleVars(&accesses, &expr_vars); Helpers::RecordVar(&accesses, arrv); Helpers::RecordMultipleVars(&accesses, &ctrlv); break; } case eCLStatement: case eBlock: break; default: assert(0); } } } } for (Function* f : get_all_functions()) { for (Block* b : f->blocks) { for (Variable* v : b->local_vars) { if (std::find(accesses.begin(), accesses.end(), v) == accesses.end()) { b->local_vars.erase(std::remove(b->local_vars.begin(), b->local_vars.end(), v), b->local_vars.end()); } } } } }