コード例 #1
0
ファイル: TempScopInfo.cpp プロジェクト: fangism/polly
IRAccess
TempScopInfo::buildIRAccess(Instruction *Inst, Loop *L, Region *R,
                            const ScopDetection::BoxedLoopsSetTy *BoxedLoops) {
  unsigned Size;
  Type *SizeType;
  enum IRAccess::TypeKind Type;

  if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
    SizeType = Load->getType();
    Size = TD->getTypeStoreSize(SizeType);
    Type = IRAccess::READ;
  } else {
    StoreInst *Store = cast<StoreInst>(Inst);
    SizeType = Store->getValueOperand()->getType();
    Size = TD->getTypeStoreSize(SizeType);
    Type = IRAccess::MUST_WRITE;
  }

  const SCEV *AccessFunction = SE->getSCEVAtScope(getPointerOperand(*Inst), L);
  const SCEVUnknown *BasePointer =
      dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));

  assert(BasePointer && "Could not find base pointer");
  AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);

  auto AccItr = InsnToMemAcc.find(Inst);
  if (PollyDelinearize && AccItr != InsnToMemAcc.end())
    return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, true,
                    AccItr->second.DelinearizedSubscripts,
                    AccItr->second.Shape->DelinearizedSizes);

  // Check if the access depends on a loop contained in a non-affine subregion.
  bool isVariantInNonAffineLoop = false;
  if (BoxedLoops) {
    SetVector<const Loop *> Loops;
    findLoops(AccessFunction, Loops);
    for (const Loop *L : Loops)
      if (BoxedLoops->count(L))
        isVariantInNonAffineLoop = true;
  }

  bool IsAffine = !isVariantInNonAffineLoop &&
                  isAffineExpr(R, AccessFunction, *SE, BasePointer->getValue());

  SmallVector<const SCEV *, 4> Subscripts, Sizes;
  Subscripts.push_back(AccessFunction);
  Sizes.push_back(SE->getConstant(ZeroOffset->getType(), Size));

  if (!IsAffine && Type == IRAccess::MUST_WRITE)
    Type = IRAccess::MAY_WRITE;

  return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, IsAffine,
                  Subscripts, Sizes);
}
コード例 #2
0
ファイル: ScopDetection.cpp プロジェクト: chapuni/polly
bool ScopDetection::hasAffineMemoryAccesses(DetectionContext &Context) const {
  Region &CurRegion = Context.CurRegion;

  for (const SCEVUnknown *BasePointer : Context.NonAffineAccesses) {
    Value *BaseValue = BasePointer->getValue();
    ArrayShape *Shape = new ArrayShape(BasePointer);
    bool BasePtrHasNonAffine = false;

    // First step: collect parametric terms in all array references.
    SmallVector<const SCEV *, 4> Terms;
    for (const auto &Pair : Context.Accesses[BasePointer]) {
      const SCEVAddRecExpr *AccessFunction =
          dyn_cast<SCEVAddRecExpr>(Pair.second);

      if (AccessFunction)
        AccessFunction->collectParametricTerms(*SE, Terms);
    }

    // Second step: find array shape.
    SE->findArrayDimensions(Terms, Shape->DelinearizedSizes,
                            Context.ElementSize[BasePointer]);

    // No array shape derived.
    if (Shape->DelinearizedSizes.empty()) {
      if (AllowNonAffine)
        continue;

      for (const auto &Pair : Context.Accesses[BasePointer]) {
        const Instruction *Insn = Pair.first;
        const SCEV *AF = Pair.second;

        if (!isAffineExpr(&CurRegion, AF, *SE, BaseValue)) {
          invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Insn,
                                         BaseValue);
          if (!KeepGoing)
            return false;
        }
      }
      continue;
    }

    // Third step: compute the access functions for each subscript.
    //
    // We first store the resulting memory accesses in TempMemoryAccesses. Only
    // if the access functions for all memory accesses have been successfully
    // delinearized we continue. Otherwise, we either report a failure or, if
    // non-affine accesses are allowed, we drop the information. In case the
    // information is dropped the memory accesses need to be overapproximated
    // when translated to a polyhedral representation.
    MapInsnToMemAcc TempMemoryAccesses;
    for (const auto &Pair : Context.Accesses[BasePointer]) {
      const Instruction *Insn = Pair.first;
      const SCEVAddRecExpr *AF = dyn_cast<SCEVAddRecExpr>(Pair.second);
      bool IsNonAffine = false;
      MemAcc *Acc = new MemAcc(Insn, Shape);
      TempMemoryAccesses.insert({Insn, Acc});

      if (!AF) {
        if (isAffineExpr(&CurRegion, Pair.second, *SE, BaseValue))
          Acc->DelinearizedSubscripts.push_back(Pair.second);
        else
          IsNonAffine = true;
      } else {
        AF->computeAccessFunctions(*SE, Acc->DelinearizedSubscripts,
                                   Shape->DelinearizedSizes);
        if (Acc->DelinearizedSubscripts.size() == 0)
          IsNonAffine = true;
        for (const SCEV *S : Acc->DelinearizedSubscripts)
          if (!isAffineExpr(&CurRegion, S, *SE, BaseValue))
            IsNonAffine = true;
      }

      // (Possibly) report non affine access
      if (IsNonAffine) {
        BasePtrHasNonAffine = true;
        if (!AllowNonAffine)
          invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, Pair.second,
                                         Insn, BaseValue);
        if (!KeepGoing && !AllowNonAffine)
          return false;
      }
    }

    if (!BasePtrHasNonAffine)
      InsnToMemAcc.insert(TempMemoryAccesses.begin(), TempMemoryAccesses.end());
  }
  return true;
}