// Return component I, creating a new Value for it if necessary. Value *Scatterer::operator[](unsigned I) { ValueVector &CV = (CachePtr ? *CachePtr : Tmp); // Try to reuse a previous value. if (CV[I]) return CV[I]; IRBuilder<> Builder(BB, BBI); if (PtrTy) { if (!CV[0]) { Type *Ty = PointerType::get(PtrTy->getElementType()->getVectorElementType(), PtrTy->getAddressSpace()); CV[0] = Builder.CreateBitCast(V, Ty, V->getName() + ".i0"); } if (I != 0) CV[I] = Builder.CreateConstGEP1_32(nullptr, CV[0], I, V->getName() + ".i" + Twine(I)); } else { // Search through a chain of InsertElementInsts looking for element I. // Record other elements in the cache. The new V is still suitable // for all uncached indices. for (;;) { InsertElementInst *Insert = dyn_cast<InsertElementInst>(V); if (!Insert) break; ConstantInt *Idx = dyn_cast<ConstantInt>(Insert->getOperand(2)); if (!Idx) break; unsigned J = Idx->getZExtValue(); V = Insert->getOperand(0); if (I == J) { CV[J] = Insert->getOperand(1); return CV[J]; } else if (!CV[J]) { // Only cache the first entry we find for each index we're not actively // searching for. This prevents us from going too far up the chain and // caching incorrect entries. CV[J] = Insert->getOperand(1); } } CV[I] = Builder.CreateExtractElement(V, Builder.getInt32(I), V->getName() + ".i" + Twine(I)); } return CV[I]; }
void Lint::visitInsertElementInst(InsertElementInst &I) { if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(2), /*OffsetOk=*/false))) Assert(CI->getValue().ult(I.getType()->getNumElements()), "Undefined result: insertelement index out of range", &I); }
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; } }
void Lint::visitInsertElementInst(InsertElementInst &I) { if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2)->stripPointerCasts())) Assert1(CI->getValue().ult(I.getType()->getNumElements()), "Undefined result: insertelement index out of range", &I); }