Exemple #1
0
void localizeGlobals() {
  if (fNoGlobalConstOpt) return;
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    Map<Symbol*,VarSymbol*> globals;
    std::vector<BaseAST*> asts;
    collect_asts(fn->body, asts);
    for_vector(BaseAST, ast, asts) {
      if (SymExpr* se = toSymExpr(ast)) {
        Symbol* var = se->symbol();
        ModuleSymbol* parentmod = toModuleSymbol(var->defPoint->parentSymbol);
        CallExpr* parentExpr = toCallExpr(se->parentExpr);
        bool inAddrOf = parentExpr && parentExpr->isPrimitive(PRIM_ADDR_OF);
        bool lhsOfMove = parentExpr && isMoveOrAssign(parentExpr) && (parentExpr->get(1) == se);

        // Is var a global constant?
        // Don't replace the var name in its init function since that's
        //      where we're setting the value. Similarly, dont replace them
        //      inside initStringLiterals
        // If the parentSymbol is the rootModule, the var is 'void,'
        //      'false,' '0,' ...
        // Also don't replace it when it's in an addr of primitive.
        if (parentmod &&
            fn != parentmod->initFn &&
            fn != initStringLiterals &&
            !inAddrOf &&
            !lhsOfMove &&
            var->hasFlag(FLAG_CONST) &&
            var->defPoint->parentSymbol != rootModule) {
          VarSymbol* local_global = globals.get(var);
          SET_LINENO(se); // Set the se line number for output
          if (!local_global) {
            const char * newname = astr("local_", var->cname);
            local_global = newTemp(newname, var->type);
            fn->insertAtHead(new CallExpr(PRIM_MOVE, local_global, var));
            fn->insertAtHead(new DefExpr(local_global));

            // Copy string immediates to localized strings so that
            // we can show the string value in comments next to uses.
            if (!llvmCodegen)
              if (VarSymbol* localVarSym = toVarSymbol(var))
                if (Immediate* immediate = localVarSym->immediate)
                  if (immediate->const_kind == CONST_KIND_STRING)
                    local_global->immediate =
                      new Immediate(immediate->v_string, immediate->string_kind);

            globals.put(var, local_global);
          }
          se->replace(new SymExpr(toSymbol(local_global)));
        }
      }
    }
  }
//
// finds outer vars directly used in a function
//
static void
findOuterVars(FnSymbol* fn, SymbolMap* uses) {
  Vec<BaseAST*> asts;
  collect_asts(fn, asts);
  forv_Vec(BaseAST, ast, asts) {
    if (SymExpr* symExpr = toSymExpr(ast)) {
      Symbol* sym = symExpr->var;
      if (toVarSymbol(sym) || toArgSymbol(sym))
        if (isOuterVar(sym, fn))
          uses->put(sym,gNil);
    }
  }
}
static void
findOuterVars(FnSymbol* fn, SymbolMap& uses) {
  std::vector<BaseAST*> asts;

  collect_asts(fn, asts);

  for_vector(BaseAST, ast, asts) {
    if (SymExpr* symExpr = toSymExpr(ast)) {
      Symbol* sym = symExpr->symbol();

      if (isLcnSymbol(sym)) {
        if (!isCorrespCoforallIndex(fn, sym) && isOuterVar(sym, fn))
          uses.put(sym, markUnspecified);
      }
    }
  }
}
Exemple #4
0
//
// finds outer vars directly used in a function
//
static void
findOuterVars(FnSymbol* fn, SymbolMap* uses) {
  std::vector<BaseAST*> asts;

  collect_asts(fn, asts);

  for_vector(BaseAST, ast, asts) {
    if (SymExpr* symExpr = toSymExpr(ast)) {
      Symbol* sym = symExpr->var;

      if (isLcnSymbol(sym)) {
        if (isOuterVar(sym, fn))
          uses->put(sym,gNil);
      }
    }
  }
}
Exemple #5
0
void localizeGlobals() {
  if (fNoGlobalConstOpt) return;
  forv_Vec(FnSymbol, fn, gFnSymbols) {
    Map<Symbol*,VarSymbol*> globals;
    std::vector<BaseAST*> asts;
    collect_asts(fn->body, asts);
    for_vector(BaseAST, ast, asts) {
      if (SymExpr* se = toSymExpr(ast)) {
        Symbol* var = se->var;
        ModuleSymbol* parentmod = toModuleSymbol(var->defPoint->parentSymbol);
        CallExpr* parentExpr = toCallExpr(se->parentExpr);
        bool inAddrOf = parentExpr && parentExpr->isPrimitive(PRIM_ADDR_OF);

        // Is var a global constant?
        // Don't replace the var name in its init function since that's
        //      where we're setting the value. Similarly, dont replace them
        //      inside initStringLiterals
        // If the parentSymbol is the rootModule, the var is 'void,'
        //      'false,' '0,' ...
        // Also don't replace it when it's in an addr of primitive.
        if (parentmod &&
            fn != parentmod->initFn &&
            fn != initStringLiterals &&
            !inAddrOf &&
            var->hasFlag(FLAG_CONST) &&
            var->defPoint->parentSymbol != rootModule) {
          VarSymbol* local_global = globals.get(var);
          SET_LINENO(se); // Set the se line number for output
          if (!local_global) {
            const char * newname = astr("local_", var->cname);
            local_global = newTemp(newname, var->type);
            fn->insertAtHead(new CallExpr(PRIM_MOVE, local_global, var));
            fn->insertAtHead(new DefExpr(local_global));

            globals.put(var, local_global);
          }
          se->replace(new SymExpr(toSymbol(local_global)));
        }
      }
    }
  }
void buildDefaultFunctions() {
  build_chpl_entry_points();

  SET_LINENO(rootModule); // todo - remove reset_ast_loc() calls below?

  std::vector<BaseAST*> asts;
  collect_asts(rootModule, asts);
  for_vector(BaseAST, ast, asts) {
    if (TypeSymbol* type = toTypeSymbol(ast)) {
      // Here we build default functions that are always generated (even when
      // the type symbol has FLAG_NO_DEFAULT_FUNCTIONS attached).
      if (AggregateType* ct = toAggregateType(type->type)) {
        buildFieldAccessorFunctions(ct);

        if (!ct->symbol->hasFlag(FLAG_REF))
          buildDefaultDestructor(ct);
        // Classes should use the nil:<type> _defaultOf method unless they
        // do not inherit from object.  For those types and records, call
        // we need a more complicated _defaultOf method generated by the
        // compiler
        if (!ct->isClass() || ct->symbol->hasFlag(FLAG_NO_OBJECT))
          build_record_init_function(ct);
      }

      if (type->hasFlag(FLAG_NO_DEFAULT_FUNCTIONS))
        continue;

      // Here we build default functions that respect the "no default
      // functions" pragma.
      if (AggregateType* ct = toAggregateType(type->type))
      {
        buildDefaultReadWriteFunctions(ct);

        if (isRecord(ct)) {
          if (!isRecordWrappedType(ct)) {
            build_record_equality_function(ct);
            build_record_inequality_function(ct);
          }
          build_record_assignment_function(ct);
          build_record_cast_function(ct);
          build_record_copy_function(ct);
          build_record_hash_function(ct);
        }
        if (isUnion(ct))
          build_union_assignment_function(ct);
      }
      else if (EnumType* et = toEnumType(type->type)) {
        //buildDefaultReadFunction(et);
        buildStringCastFunction(et);

        build_enum_cast_function(et);
        build_enum_assignment_function(et);
        build_enum_first_function(et);
        build_enum_enumerate_function(et);
      }
      else
      {
        // The type is a simple type.

        // Other simple types are handled explicitly in the module code.
        // But to avoid putting a catch-all case there to implement assignment
        // for extern types that are simple (as far as we can tell), we build
        // definitions for those assignments here.
        if (type->hasFlag(FLAG_EXTERN)) {
          build_extern_init_function(type->type);
          build_extern_assignment_function(type->type);
        }
      }
    }
  }
}