Exemplo n.º 1
0
void ReturnByRef::returnByRefCollectCalls(RefMap& calls)
{
  RefMap::iterator iter;

  forv_Vec(CallExpr, call, gCallExprs)
  {
    if (FnSymbol* fn = theTransformableFunction(call))
    {
      RefMap::iterator iter = calls.find(fn->id);
      ReturnByRef*     info = NULL;

      if (iter == calls.end())
      {
        info          = new ReturnByRef(fn);
        calls[fn->id] = info;
      }
      else
      {
        info          = iter->second;
      }

      info->addCall(call);
    }
  }
}
Exemplo n.º 2
0
void CacheGitDirectory::registerEntryInRefMap(const std::string& hash,
                                              RefMap& refMap) {
  assert(isInRef());

  /* Find the cache entry that corresponds to this hash.
   * Create a new entry if not found. */
  auto itFind = gitHashMap_.find(hash);
  GitCacheEntry* entry;
  if (itFind == gitHashMap_.end()) {
    entry = new GitCacheEntry();
    entry->hash = hash;
    gitHashMap_[hash] = entry;
  } else {
    entry = itFind->second;
  }

  /* Look in the refMap for any CacheEntry that was already linked to the
   * current git ref. */
  auto itPrevEntry = refMap.find(currentGitRef_);
  if (itPrevEntry != refMap.end()) {
    GitCacheEntry* prevEntry = itPrevEntry->second;
    assert(prevEntry->numGitRefs > 0);
    prevEntry->numGitRefs--;
    if (prevEntry->numGitRefs == 0 && prevEntry != entry) {
      DLOG(INFO) << "deleting " << prevEntry->hash;
      cacheFs_.delEntry(prevEntry->hash);
      gitHashMap_.erase(prevEntry->hash);
      delete prevEntry;
    }
  }

  refMap[currentGitRef_] = entry;
  entry->numGitRefs++;
}
Exemplo n.º 3
0
// Insert pairs into available copies map
// Also, record references when they are created.
static void extractReferences(Expr* expr,
                              RefMap& refs)
{
  // We're only interested in call expressions.
  if (CallExpr* call = toCallExpr(expr))
  {
    // Only the move primitive creates an available pair.
    if (call->isPrimitive(PRIM_MOVE) || call->isPrimitive(PRIM_ASSIGN))
    {
      SymExpr* lhe = toSymExpr(call->get(1)); // Left-Hand Expression
      Symbol* lhs = lhe->var; // Left-Hand Symbol

      if (SymExpr* rhe = toSymExpr(call->get(2))) // Right-Hand Expression
      {
        Symbol* rhs = rhe->var; // Right-Hand Symbol

        if (lhs->type->symbol->hasFlag(FLAG_REF) &&
            rhs->type->symbol->hasFlag(FLAG_REF))
        {
          // This is a ref <- ref assignment.
          // Which means that the lhs is now also a reference to whatever the
          // rhs refers to.
          RefMap::iterator refDef = refs.find(rhs);
          // Refs can come from outside the function (e.g. through arguments),
          // so are not necessarily defined within the function.
          if (refDef != refs.end())
          {
            Symbol* val = refDef->second;
#if DEBUG_CP
            if (debug > 0)
              printf("Creating ref (%s[%d], %s[%d])\n",
                     lhs->name, lhs->id, val->name, val->id);
#endif
            refs.insert(RefMapElem(lhs, val));
          }
        }
      }

      if (CallExpr* rhc = toCallExpr(call->get(2)))
      {
        if (rhc->isPrimitive(PRIM_ADDR_OF))
        {
          SymExpr* rhe = toSymExpr(rhc->get(1));

          // Create the pair lhs <- &rhs.
          Symbol* lhs = lhe->var;
          Symbol* rhs = rhe->var;
#if DEBUG_CP
          if (debug > 0)
            printf("Creating ref (%s[%d], %s[%d])\n",
                   lhs->name, lhs->id, rhs->name, rhs->id);
#endif
          refs.insert(RefMapElem(lhs, rhs));
        }
      }
    }
  }
}
Exemplo n.º 4
0
void ReturnByRef::returnByRefCollectCalls(RefMap& calls, FnSet& fns)
{
  RefMap::iterator iter;

  forv_Vec(CallExpr, call, gCallExprs)
  {
    // Only transform calls that are still in the AST tree
    // (defer statement bodies have been removed at this point
    //  in this pass)
    if (call->inTree()) {

      // Only transform calls to transformable functions
      // The common case is a user-level call to a resolved function
      // Also handle the PRIMOP for a virtual method call
      if (FnSymbol* fn = call->resolvedOrVirtualFunction()) {
       TransformationKind tfKind = transformableFunctionKind(fn);
       if (tfKind == TF_FULL)
       {
        RefMap::iterator iter = calls.find(fn->id);
        ReturnByRef*     info = NULL;

        if (iter == calls.end())
        {
          info          = new ReturnByRef(fn);
          calls[fn->id] = info;
        }
        else
        {
          info          = iter->second;
        }

        info->addCall(call);
       }
       else if (tfKind == TF_ASGN)
       {
         fns.insert(fn);
       }
      }
    }
  }
}