Exemple #1
0
void Lint::visitExtractElementInst(ExtractElementInst &I) {
  if (ConstantInt *CI =
        dyn_cast<ConstantInt>(findValue(I.getIndexOperand(),
                                        /*OffsetOk=*/false)))
    Assert1(CI->getValue().ult(I.getVectorOperandType()->getNumElements()),
            "Undefined result: extractelement index out of range", &I);
}
Exemple #2
0
unsigned CostModelAnalysis::getInstructionCost(Instruction *I) const {
  if (!VTTI)
    return -1;

  switch (I->getOpcode()) {
  case Instruction::Ret:
  case Instruction::PHI:
  case Instruction::Br: {
    return VTTI->getCFInstrCost(I->getOpcode());
  }
  case Instruction::Add:
  case Instruction::FAdd:
  case Instruction::Sub:
  case Instruction::FSub:
  case Instruction::Mul:
  case Instruction::FMul:
  case Instruction::UDiv:
  case Instruction::SDiv:
  case Instruction::FDiv:
  case Instruction::URem:
  case Instruction::SRem:
  case Instruction::FRem:
  case Instruction::Shl:
  case Instruction::LShr:
  case Instruction::AShr:
  case Instruction::And:
  case Instruction::Or:
  case Instruction::Xor: {
    return VTTI->getArithmeticInstrCost(I->getOpcode(), I->getType());
  }
  case Instruction::Select: {
    SelectInst *SI = cast<SelectInst>(I);
    Type *CondTy = SI->getCondition()->getType();
    return VTTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy);
  }
  case Instruction::ICmp:
  case Instruction::FCmp: {
    Type *ValTy = I->getOperand(0)->getType();
    return VTTI->getCmpSelInstrCost(I->getOpcode(), ValTy);
  }
  case Instruction::Store: {
    StoreInst *SI = cast<StoreInst>(I);
    Type *ValTy = SI->getValueOperand()->getType();
    return VTTI->getMemoryOpCost(I->getOpcode(), ValTy,
                                 SI->getAlignment(),
                                 SI->getPointerAddressSpace());
  }
  case Instruction::Load: {
    LoadInst *LI = cast<LoadInst>(I);
    return VTTI->getMemoryOpCost(I->getOpcode(), I->getType(),
                                 LI->getAlignment(),
                                 LI->getPointerAddressSpace());
  }
  case Instruction::ZExt:
  case Instruction::SExt:
  case Instruction::FPToUI:
  case Instruction::FPToSI:
  case Instruction::FPExt:
  case Instruction::PtrToInt:
  case Instruction::IntToPtr:
  case Instruction::SIToFP:
  case Instruction::UIToFP:
  case Instruction::Trunc:
  case Instruction::FPTrunc:
  case Instruction::BitCast: {
    Type *SrcTy = I->getOperand(0)->getType();
    return VTTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy);
  }
  case Instruction::ExtractElement: {
    ExtractElementInst * EEI = cast<ExtractElementInst>(I);
    ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
    unsigned Idx = -1;
    if (CI)
      Idx = CI->getZExtValue();
    return VTTI->getVectorInstrCost(I->getOpcode(),
                                    EEI->getOperand(0)->getType(), Idx);
  }
  case Instruction::InsertElement: {
      InsertElementInst * IE = cast<InsertElementInst>(I);
      ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
      unsigned Idx = -1;
      if (CI)
        Idx = CI->getZExtValue();
      return VTTI->getVectorInstrCost(I->getOpcode(),
                                      IE->getType(), Idx);
    }
  default:
    // We don't have any information on this instruction.
    return -1;
  }
}
static void replaceShuffleVectorWithByteSwap64(
    ShuffleVectorInst *SI, SmallVector<int, 16> &RefMasks)
{
    Value *LHS = SI->getOperand(0);
    Value *RHS = SI->getOperand(1);
    VectorType *LHSType = cast<VectorType>(LHS->getType());
    VectorType *RHSType = cast<VectorType>(RHS->getType());
    unsigned LHSWidth = LHSType->getBitWidth();
    errs() << "In Replace: " << LHSWidth << "\n";
    unsigned RHSWidth = RHSType->getBitWidth();

    //ReplaceWork begins
    //TODO:Make it automatic and compact

    unsigned ITEMNUM = LHSWidth / 64;
    VectorType *Ty1 = VectorType::get(
        Type::getInt64Ty(SI->getContext()),
                ITEMNUM);

    BitCastInst *BCI1 = new BitCastInst(
        LHS, Ty1, "", SI);

    //TODO:Remove ShuffleVectorInst
    SmallVector<Constant *, 16> BigMasks;
    for (unsigned i = 0; i < ITEMNUM; ++i) {
        APInt num(32, ITEMNUM - i - 1);
        BigMasks.push_back(
            Constant::getIntegerValue(
                Type::getInt32Ty(SI->getContext()),
                num));
    }
    Constant *Masks = ConstantVector::get(BigMasks);
    ShuffleVectorInst *SVI = new ShuffleVectorInst(
        BCI1, UndefValue::get(BCI1->getType()),
        Masks,//Mask is ConstantVector
        "",
        SI);

    SmallVector<CallInst *, 16> CIS;

    for (unsigned i = 0; i < ITEMNUM; ++i) {
        ConstantInt *CI =
            ConstantInt::get(
                Type::getInt32Ty(
                    SI->getContext()), i);
        ExtractElementInst *EEI = ExtractElementInst::Create(
            SVI, CI, "", SI);
        //EVIS.push_back(EEI);

        Module *M = SI->getParent()->getParent()->getParent();
        Constant *Int = Intrinsic::getDeclaration(
            M, Intrinsic::bswap, EEI->getType());
        Value *Op = EEI;
        CallInst *CaI = CallInst::Create(Int, Op, "", SI);
        CIS.push_back(CaI);
    }

    VectorType *Ty2 = VectorType::get(
        Type::getInt64Ty(SI->getContext()),
        1);

    BitCastInst *BCIW = new BitCastInst(
        CIS[0], Ty2, "", SI);

    Value *V = BCIW;
    for (unsigned i = 1; i < CIS.size(); ++i) {
        Value *Elt = CIS[i];
        InsertElementInst *IEI =
            InsertElementInst::Create(
                V, Elt,
                ConstantInt::get(Type::getInt32Ty(SI->getContext()), 0),
                "", SI);
        V = IEI;
    }



    return ;
}
/// If we have insertion into a vector that is wider than the vector that we
/// are extracting from, try to widen the source vector to allow a single
/// shufflevector to replace one or more insert/extract pairs.
static void replaceExtractElements(InsertElementInst *InsElt,
                                   ExtractElementInst *ExtElt,
                                   InstCombiner &IC) {
  VectorType *InsVecType = InsElt->getType();
  VectorType *ExtVecType = ExtElt->getVectorOperandType();
  unsigned NumInsElts = InsVecType->getVectorNumElements();
  unsigned NumExtElts = ExtVecType->getVectorNumElements();

  // The inserted-to vector must be wider than the extracted-from vector.
  if (InsVecType->getElementType() != ExtVecType->getElementType() ||
      NumExtElts >= NumInsElts)
    return;

  // Create a shuffle mask to widen the extended-from vector using undefined
  // values. The mask selects all of the values of the original vector followed
  // by as many undefined values as needed to create a vector of the same length
  // as the inserted-to vector.
  SmallVector<Constant *, 16> ExtendMask;
  IntegerType *IntType = Type::getInt32Ty(InsElt->getContext());
  for (unsigned i = 0; i < NumExtElts; ++i)
    ExtendMask.push_back(ConstantInt::get(IntType, i));
  for (unsigned i = NumExtElts; i < NumInsElts; ++i)
    ExtendMask.push_back(UndefValue::get(IntType));

  Value *ExtVecOp = ExtElt->getVectorOperand();
  auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
  BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
                                   ? ExtVecOpInst->getParent()
                                   : ExtElt->getParent();

  // TODO: This restriction matches the basic block check below when creating
  // new extractelement instructions. If that limitation is removed, this one
  // could also be removed. But for now, we just bail out to ensure that we
  // will replace the extractelement instruction that is feeding our
  // insertelement instruction. This allows the insertelement to then be
  // replaced by a shufflevector. If the insertelement is not replaced, we can
  // induce infinite looping because there's an optimization for extractelement
  // that will delete our widening shuffle. This would trigger another attempt
  // here to create that shuffle, and we spin forever.
  if (InsertionBlock != InsElt->getParent())
    return;

  auto *WideVec = new ShuffleVectorInst(ExtVecOp, UndefValue::get(ExtVecType),
                                        ConstantVector::get(ExtendMask));

  // Insert the new shuffle after the vector operand of the extract is defined
  // (as long as it's not a PHI) or at the start of the basic block of the
  // extract, so any subsequent extracts in the same basic block can use it.
  // TODO: Insert before the earliest ExtractElementInst that is replaced.
  if (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
    WideVec->insertAfter(ExtVecOpInst);
  else
    IC.InsertNewInstWith(WideVec, *ExtElt->getParent()->getFirstInsertionPt());

  // Replace extracts from the original narrow vector with extracts from the new
  // wide vector.
  for (User *U : ExtVecOp->users()) {
    ExtractElementInst *OldExt = dyn_cast<ExtractElementInst>(U);
    if (!OldExt || OldExt->getParent() != WideVec->getParent())
      continue;
    auto *NewExt = ExtractElementInst::Create(WideVec, OldExt->getOperand(1));
    NewExt->insertAfter(WideVec);
    IC.replaceInstUsesWith(*OldExt, NewExt);
  }
}