예제 #1
0
//
// Determine the index type for a ParamForLoop.
//
// This implementation creates a range with low/high values and then
// asks for its type.
//
Type* ParamForLoop::indexType()
{
  SymExpr*  lse     = lowExprGet();
  SymExpr*  hse     = highExprGet();
  CallExpr* range    = new CallExpr("chpl_build_bounded_range",
                                    lse->copy(), hse->copy());
  Type*     idxType = 0;

  insertBefore(range);

  resolveCall(range);

  if (FnSymbol* sym = range->isResolved())
  {
    resolveFormals(sym);

    DefExpr* formal = toDefExpr(sym->formals.get(1));

    if (toArgSymbol(formal->sym)->typeExpr)
      idxType = toArgSymbol(formal->sym)->typeExpr->body.tail->typeInfo();
    else
      idxType = formal->sym->type;

    range->remove();
  }
  else
  {
    INT_FATAL("unresolved range");
  }

  return idxType;
}
예제 #2
0
//
// The argument expr is a use of a wide reference. Insert a check to ensure
// that it is on the current locale, then drop its wideness by moving the
// addr field into a non-wide of otherwise the same type. Then, replace its
// use with the non-wide version.
//
static void insertLocalTemp(Expr* expr) {
  SymExpr* se = toSymExpr(expr);
  Expr* stmt = expr->getStmtExpr();
  INT_ASSERT(se && stmt);
  SET_LINENO(se);
  VarSymbol* var = newTemp(astr("local_", se->var->name),
                           se->var->type->getField("addr")->type);
  if (!fNoLocalChecks) {
    stmt->insertBefore(new CallExpr(PRIM_LOCAL_CHECK, se->copy()));
  }
  stmt->insertBefore(new DefExpr(var));
  stmt->insertBefore(new CallExpr(PRIM_MOVE, var, se->copy()));
  se->replace(new SymExpr(var));
}
예제 #3
0
void ReturnByRef::updateAssignmentsFromRefTypeToValue(FnSymbol* fn)
{
  std::vector<CallExpr*> callExprs;

  collectCallExprs(fn, callExprs);

  Map<Symbol*,Vec<SymExpr*>*> defMap;
  Map<Symbol*,Vec<SymExpr*>*> useMap;
  buildDefUseMaps(fn, defMap, useMap);

  for (size_t i = 0; i < callExprs.size(); i++)
  {
    CallExpr* move = callExprs[i];

    if (move->isPrimitive(PRIM_MOVE) == true)
    {
      SymExpr*  symLhs  = toSymExpr (move->get(1));
      CallExpr* callRhs = toCallExpr(move->get(2));

      if (symLhs && callRhs && callRhs->isPrimitive(PRIM_DEREF))
      {
        VarSymbol* varLhs = toVarSymbol(symLhs->symbol());
        SymExpr*   symRhs = toSymExpr(callRhs->get(1));
        VarSymbol* varRhs = toVarSymbol(symRhs->symbol());

        // MPF 2016-10-02: It seems to me that this code should also handle the
        // case that symRhs is an ArgSymbol, but adding that caused problems
        // in the handling of out argument intents.

        if (varLhs != NULL && varRhs != NULL)
        {
          if (isUserDefinedRecord(varLhs->type) == true &&
              varRhs->type                      == varLhs->type->refType)
          {

            // HARSHBARGER 2015-12-11:
            // `init_untyped_var` in the `normalize` pass may insert an
            // initCopy, which means that we should not insert an autocopy
            // for that same variable.
            bool initCopied = false;
            for_uses(use, useMap, varLhs) {
              if (CallExpr* call = toCallExpr(use->parentExpr)) {
                if (FnSymbol* parentFn = call->isResolved()) {
                  if (parentFn->hasFlag(FLAG_INIT_COPY_FN)) {
                    initCopied = true;
                    break;
                  }
                }
              }
            }

            if (!initCopied) {
              SET_LINENO(move);

              SymExpr*  lhsCopy0 = symLhs->copy();
              SymExpr*  lhsCopy1 = symLhs->copy();
              FnSymbol* autoCopy = autoCopyMap.get(varLhs->type);
              CallExpr* copyExpr = new CallExpr(autoCopy, lhsCopy0);
              CallExpr* moveExpr = new CallExpr(PRIM_MOVE,lhsCopy1, copyExpr);

              move->insertAfter(moveExpr);
            }
          }
        }
      }