Esempio n. 1
0
  Constant *computeLoadValue(LoadInst *LI, unsigned Iteration) {
    if (!LI)
      return nullptr;
    Value *BaseAddr = LoadBaseAddresses[LI];
    if (!BaseAddr)
      return nullptr;

    auto GV = dyn_cast<GlobalVariable>(BaseAddr);
    if (!GV)
      return nullptr;

    ConstantDataSequential *CDS =
        dyn_cast<ConstantDataSequential>(GV->getInitializer());
    if (!CDS)
      return nullptr;

    const SCEV *BaseAddrSE = SE.getSCEV(BaseAddr);
    const SCEV *S = SE.getSCEV(LI->getPointerOperand());
    const SCEV *OffSE = SE.getMinusSCEV(S, BaseAddrSE);

    APInt StepC, StartC;
    const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(OffSE);
    if (!AR)
      return nullptr;

    if (const SCEVConstant *StepSE =
            dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE)))
      StepC = StepSE->getValue()->getValue();
    else
      return nullptr;

    if (const SCEVConstant *StartSE = dyn_cast<SCEVConstant>(AR->getStart()))
      StartC = StartSE->getValue()->getValue();
    else
      return nullptr;

    unsigned ElemSize = CDS->getElementType()->getPrimitiveSizeInBits() / 8U;
    unsigned Start = StartC.getLimitedValue();
    unsigned Step = StepC.getLimitedValue();

    unsigned Index = (Start + Step * Iteration) / ElemSize;
    if (Index >= CDS->getNumElements())
      return nullptr;

    Constant *CV = CDS->getElementAsConstant(Index);

    return CV;
  }
Esempio n. 2
0
/// Try to fold load I.
bool UnrolledInstAnalyzer::visitLoad(LoadInst &I) {
  Value *AddrOp = I.getPointerOperand();

  auto AddressIt = SimplifiedAddresses.find(AddrOp);
  if (AddressIt == SimplifiedAddresses.end())
    return false;
  ConstantInt *SimplifiedAddrOp = AddressIt->second.Offset;

  auto *GV = dyn_cast<GlobalVariable>(AddressIt->second.Base);
  // We're only interested in loads that can be completely folded to a
  // constant.
  if (!GV || !GV->hasDefinitiveInitializer() || !GV->isConstant())
    return false;

  ConstantDataSequential *CDS =
      dyn_cast<ConstantDataSequential>(GV->getInitializer());
  if (!CDS)
    return false;

  // We might have a vector load from an array. FIXME: for now we just bail
  // out in this case, but we should be able to resolve and simplify such
  // loads.
  if(!CDS->isElementTypeCompatible(I.getType()))
    return false;

  int ElemSize = CDS->getElementType()->getPrimitiveSizeInBits() / 8U;
  if (SimplifiedAddrOp->getValue().getActiveBits() >= 64)
    return false;
  int64_t Index = SimplifiedAddrOp->getSExtValue() / ElemSize;
  if (Index >= CDS->getNumElements()) {
    // FIXME: For now we conservatively ignore out of bound accesses, but
    // we're allowed to perform the optimization in this case.
    return false;
  }

  Constant *CV = CDS->getElementAsConstant(Index);
  assert(CV && "Constant expected.");
  SimplifiedValues[&I] = CV;

  return true;
}