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++;
            }
        }
Пример #2
0
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());
        }
      }
    }
  }
}