本文整理汇总了C++中GetElementPtrInst::idx_begin方法的典型用法代码示例。如果您正苦于以下问题:C++ GetElementPtrInst::idx_begin方法的具体用法?C++ GetElementPtrInst::idx_begin怎么用?C++ GetElementPtrInst::idx_begin使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GetElementPtrInst
的用法示例。
在下文中一共展示了GetElementPtrInst::idx_begin方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: isGEPOffsetConstant
/// \brief Check whether a GEP's indices are all constant.
///
/// Respects any simplified values known during the analysis of this callsite.
bool CallAnalyzer::isGEPOffsetConstant(GetElementPtrInst &GEP) {
for (User::op_iterator I = GEP.idx_begin(), E = GEP.idx_end(); I != E; ++I)
if (!isa<Constant>(*I) && !SimplifiedValues.lookup(*I))
return false;
return true;
}
示例2: BitCastInst
// Returns a clone of `I` with its operands converted to those specified in
// ValueWithNewAddrSpace. Due to potential cycles in the data flow graph, an
// operand whose address space needs to be modified might not exist in
// ValueWithNewAddrSpace. In that case, uses undef as a placeholder operand and
// adds that operand use to UndefUsesToFix so that caller can fix them later.
//
// Note that we do not necessarily clone `I`, e.g., if it is an addrspacecast
// from a pointer whose type already matches. Therefore, this function returns a
// Value* instead of an Instruction*.
static Value *cloneInstructionWithNewAddressSpace(
Instruction *I, unsigned NewAddrSpace,
const ValueToValueMapTy &ValueWithNewAddrSpace,
SmallVectorImpl<const Use *> *UndefUsesToFix) {
Type *NewPtrType =
I->getType()->getPointerElementType()->getPointerTo(NewAddrSpace);
if (I->getOpcode() == Instruction::AddrSpaceCast) {
Value *Src = I->getOperand(0);
// Because `I` is flat, the source address space must be specific.
// Therefore, the inferred address space must be the source space, according
// to our algorithm.
assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
if (Src->getType() != NewPtrType)
return new BitCastInst(Src, NewPtrType);
return Src;
}
// Computes the converted pointer operands.
SmallVector<Value *, 4> NewPointerOperands;
for (const Use &OperandUse : I->operands()) {
if (!OperandUse.get()->getType()->isPointerTy())
NewPointerOperands.push_back(nullptr);
else
NewPointerOperands.push_back(operandWithNewAddressSpaceOrCreateUndef(
OperandUse, NewAddrSpace, ValueWithNewAddrSpace, UndefUsesToFix));
}
switch (I->getOpcode()) {
case Instruction::BitCast:
return new BitCastInst(NewPointerOperands[0], NewPtrType);
case Instruction::PHI: {
assert(I->getType()->isPointerTy());
PHINode *PHI = cast<PHINode>(I);
PHINode *NewPHI = PHINode::Create(NewPtrType, PHI->getNumIncomingValues());
for (unsigned Index = 0; Index < PHI->getNumIncomingValues(); ++Index) {
unsigned OperandNo = PHINode::getOperandNumForIncomingValue(Index);
NewPHI->addIncoming(NewPointerOperands[OperandNo],
PHI->getIncomingBlock(Index));
}
return NewPHI;
}
case Instruction::GetElementPtr: {
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
GetElementPtrInst *NewGEP = GetElementPtrInst::Create(
GEP->getSourceElementType(), NewPointerOperands[0],
SmallVector<Value *, 4>(GEP->idx_begin(), GEP->idx_end()));
NewGEP->setIsInBounds(GEP->isInBounds());
return NewGEP;
}
case Instruction::Select: {
assert(I->getType()->isPointerTy());
return SelectInst::Create(I->getOperand(0), NewPointerOperands[1],
NewPointerOperands[2], "", nullptr, I);
}
default:
llvm_unreachable("Unexpected opcode");
}
}
示例3: instrumentGetElementPtr
bool EfficiencySanitizer::instrumentGetElementPtr(Instruction *I, Module &M) {
GetElementPtrInst *GepInst = dyn_cast<GetElementPtrInst>(I);
bool Res = false;
if (GepInst == nullptr || GepInst->getNumIndices() == 1) {
++NumIgnoredGEPs;
return false;
}
Type *SourceTy = GepInst->getSourceElementType();
StructType *StructTy = nullptr;
ConstantInt *Idx;
// Check if GEP calculates address from a struct array.
if (isa<StructType>(SourceTy)) {
StructTy = cast<StructType>(SourceTy);
Idx = dyn_cast<ConstantInt>(GepInst->getOperand(1));
if ((Idx == nullptr || Idx->getSExtValue() != 0) &&
!shouldIgnoreStructType(StructTy) && StructTyMap.count(StructTy) != 0)
Res |= insertCounterUpdate(I, StructTy, getArrayCounterIdx(StructTy));
}
// Iterate all (except the first and the last) idx within each GEP instruction
// for possible nested struct field address calculation.
for (unsigned i = 1; i < GepInst->getNumIndices(); ++i) {
SmallVector<Value *, 8> IdxVec(GepInst->idx_begin(),
GepInst->idx_begin() + i);
Type *Ty = GetElementPtrInst::getIndexedType(SourceTy, IdxVec);
unsigned CounterIdx = 0;
if (isa<ArrayType>(Ty)) {
ArrayType *ArrayTy = cast<ArrayType>(Ty);
StructTy = dyn_cast<StructType>(ArrayTy->getElementType());
if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
continue;
// The last counter for struct array access.
CounterIdx = getArrayCounterIdx(StructTy);
} else if (isa<StructType>(Ty)) {
StructTy = cast<StructType>(Ty);
if (shouldIgnoreStructType(StructTy) || StructTyMap.count(StructTy) == 0)
continue;
// Get the StructTy's subfield index.
Idx = cast<ConstantInt>(GepInst->getOperand(i+1));
assert(Idx->getSExtValue() >= 0 &&
Idx->getSExtValue() < StructTy->getNumElements());
CounterIdx = getFieldCounterIdx(StructTy) + Idx->getSExtValue();
}
Res |= insertCounterUpdate(I, StructTy, CounterIdx);
}
if (Res)
++NumInstrumentedGEPs;
else
++NumIgnoredGEPs;
return Res;
}
示例4: visitGetElementPtrInst
void ArrayIndexChecker::visitGetElementPtrInst(GetElementPtrInst& I) {
DEBUG(dbgs() << "ArrayIndexChecker: visiting GEP " << I << "\n");
visitValue(*I.getPointerOperand());
for (auto Idx = I.idx_begin(), E = I.idx_end(); Idx != E; ++Idx) {
visitValue(**Idx);
}
auto pos = std::find(ptr_value_vec_.begin(), ptr_value_vec_.end(), &I);
assert(pos != ptr_value_vec_.end());
index_t varIdx = pos - ptr_value_vec_.begin();
assert(idx2addr_.find(varIdx) != idx2addr_.end());
if (addr2version_[idx2addr_[varIdx]] != 0)
throw ArrayIndexIsNotConstant;;
DEBUG(dbgs() << "ArrayIndexChecker: visited GEP\n");
}
示例5: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// Find all GEPs, and simplify them.
//
// Inputs:
// M - A reference to the LLVM module to transform
//
// Outputs:
// M - The transformed LLVM module.
//
// Return value:
// true - The module was modified.
// false - The module was not modified.
//
bool SimplifyGEP::runOnModule(Module& M) {
TD = &getAnalysis<TargetData>();
preprocess(M);
for (Module::iterator F = M.begin(); F != M.end(); ++F){
for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
if(!(isa<GetElementPtrInst>(I)))
continue;
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
Value *PtrOp = GEP->getOperand(0);
Value *StrippedPtr = PtrOp->stripPointerCasts();
// Check if the GEP base pointer is enclosed in a cast
if (StrippedPtr != PtrOp) {
const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType());
bool HasZeroPointerIndex = false;
if (ConstantInt *C = dyn_cast<ConstantInt>(GEP->getOperand(1)))
HasZeroPointerIndex = C->isZero();
// Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ...
// into : GEP [10 x i8]* X, i32 0, ...
//
// Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ...
// into : GEP i8* X, ...
//
// This occurs when the program declares an array extern like "int X[];"
if (HasZeroPointerIndex) {
const PointerType *CPTy = cast<PointerType>(PtrOp->getType());
if (const ArrayType *CATy =
dyn_cast<ArrayType>(CPTy->getElementType())) {
// GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == StrippedPtrTy->getElementType()) {
// -> GEP i8* X, ...
SmallVector<Value*, 8> Idx(GEP->idx_begin()+1, GEP->idx_end());
GetElementPtrInst *Res =
GetElementPtrInst::Create(StrippedPtr, Idx, GEP->getName(), GEP);
Res->setIsInBounds(GEP->isInBounds());
GEP->replaceAllUsesWith(Res);
continue;
}
if (const ArrayType *XATy =
dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){
// GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ?
if (CATy->getElementType() == XATy->getElementType()) {
// -> GEP [10 x i8]* X, i32 0, ...
// At this point, we know that the cast source type is a pointer
// to an array of the same type as the destination pointer
// array. Because the array type is never stepped over (there
// is a leading zero) we can fold the cast into this GEP.
GEP->setOperand(0, StrippedPtr);
continue;
}
}
}
} else if (GEP->getNumOperands() == 2) {
// Transform things like:
// %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V
// into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
Type *SrcElTy = StrippedPtrTy->getElementType();
Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
if (TD && SrcElTy->isArrayTy() &&
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
TD->getTypeAllocSize(ResElTy)) {
Value *Idx[2];
Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
Idx[1] = GEP->getOperand(1);
Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
GEP->getName(), GEP);
// V and GEP are both pointer types --> BitCast
GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
continue;
}
// Transform things like:
// getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp
// (where tmp = 8*tmp2) into:
// getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) {
uint64_t ArrayEltSize =
TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
// Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We
// allow either a mul, shift, or constant here.
//.........这里部分代码省略.........
示例6: StoreInst
//.........这里部分代码省略.........
I2->setName(I->getName()+"."+Twine(i));
new StoreInst(I2++, Idx, InsertPt);
}
// Anything that used the arg should now use the alloca.
I->replaceAllUsesWith(TheAlloca);
TheAlloca->takeName(I);
AA.replaceWithNewValue(I, TheAlloca);
continue;
}
if (I->use_empty()) {
AA.deleteValue(I);
continue;
}
// Otherwise, if we promoted this argument, then all users are load
// instructions (or GEPs with only load users), and all loads should be
// using the new argument that we added.
ScalarizeTable &ArgIndices = ScalarizedElements[I];
while (!I->use_empty()) {
if (LoadInst *LI = dyn_cast<LoadInst>(I->use_back())) {
assert(ArgIndices.begin()->empty() &&
"Load element should sort to front!");
I2->setName(I->getName()+".val");
LI->replaceAllUsesWith(I2);
AA.replaceWithNewValue(LI, I2);
LI->eraseFromParent();
DEBUG(dbgs() << "*** Promoted load of argument '" << I->getName()
<< "' in function '" << F->getName() << "'\n");
} else {
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->use_back());
IndicesVector Operands;
Operands.reserve(GEP->getNumIndices());
for (User::op_iterator II = GEP->idx_begin(), IE = GEP->idx_end();
II != IE; ++II)
Operands.push_back(cast<ConstantInt>(*II)->getSExtValue());
// GEPs with a single 0 index can be merged with direct loads
if (Operands.size() == 1 && Operands.front() == 0)
Operands.clear();
Function::arg_iterator TheArg = I2;
for (ScalarizeTable::iterator It = ArgIndices.begin();
*It != Operands; ++It, ++TheArg) {
assert(It != ArgIndices.end() && "GEP not handled??");
}
std::string NewName = I->getName();
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
NewName += "." + utostr(Operands[i]);
}
NewName += ".val";
TheArg->setName(NewName);
DEBUG(dbgs() << "*** Promoted agg argument '" << TheArg->getName()
<< "' of function '" << NF->getName() << "'\n");
// All of the uses must be load instructions. Replace them all with
// the argument specified by ArgNo.
while (!GEP->use_empty()) {
LoadInst *L = cast<LoadInst>(GEP->use_back());
L->replaceAllUsesWith(TheArg);
AA.replaceWithNewValue(L, TheArg);
L->eraseFromParent();
}
AA.deleteValue(GEP);
GEP->eraseFromParent();
}
}
// Increment I2 past all of the arguments added for this promoted pointer.
for (unsigned i = 0, e = ArgIndices.size(); i != e; ++i)
++I2;
}
// Notify the alias analysis implementation that we inserted a new argument.
if (ExtraArgHack)
AA.copyValue(Constant::getNullValue(Type::getInt32Ty(F->getContext())),
NF->arg_begin());
// Tell the alias analysis that the old function is about to disappear.
AA.replaceWithNewValue(F, NF);
NF_CGN->stealCalledFunctionsFrom(CG[F]);
// Now that the old function is dead, delete it. If there is a dangling
// reference to the CallgraphNode, just leave the dead function around for
// someone else to nuke.
CallGraphNode *CGN = CG[F];
if (CGN->getNumReferences() == 0)
delete CG.removeFunctionFromModule(CGN);
else
F->setLinkage(Function::ExternalLinkage);
return NF_CGN;
}
示例7: ConvertOperandToType
//.........这里部分代码省略.........
}
// Perform the conversion now...
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(NewVal->getType(),Index,Indices,TD,&It);
assert(ElTy != 0 && "GEP Conversion Failure!");
Res = new GetElementPtrInst(NewVal, Indices, Name);
assert(Res->getType() == PointerType::get(ElTy) &&
"ConvertibleToGet failed!");
}
#if 0
if (I->getType() == PointerType::get(Type::SByteTy)) {
// Convert a getelementptr sbyte * %reg111, uint 16 freely back to
// anything that is a pointer type...
//
BasicBlock::iterator It = I;
// Check to see if the second argument is an expression that can
// be converted to the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(NewVal->getType(), I->getOperand(1),
Indices, TD, &It);
assert(ElTy != 0 && "GEP Conversion Failure!");
Res = new GetElementPtrInst(NewVal, Indices, Name);
} else {
// Convert a getelementptr ulong * %reg123, uint %N
// to getelementptr long * %reg123, uint %N
// ... where the type must simply stay the same size...
//
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
std::vector<Value*> Indices(GEP->idx_begin(), GEP->idx_end());
Res = new GetElementPtrInst(NewVal, Indices, Name);
}
#endif
break;
case Instruction::PHI: {
PHINode *OldPN = cast<PHINode>(I);
PHINode *NewPN = new PHINode(NewTy, Name);
VMC.ExprMap[I] = NewPN;
while (OldPN->getNumOperands()) {
BasicBlock *BB = OldPN->getIncomingBlock(0);
Value *OldVal = OldPN->getIncomingValue(0);
ValueHandle OldValHandle(VMC, OldVal);
OldPN->removeIncomingValue(BB, false);
Value *V = ConvertExpressionToType(OldVal, NewTy, VMC, TD);
NewPN->addIncoming(V, BB);
}
Res = NewPN;
break;
}
case Instruction::Call: {
Value *Meth = I->getOperand(0);
std::vector<Value*> Params(I->op_begin()+1, I->op_end());
if (Meth == OldVal) { // Changing the function pointer?
const PointerType *NewPTy = cast<PointerType>(NewVal->getType());
const FunctionType *NewTy = cast<FunctionType>(NewPTy->getElementType());
if (NewTy->getReturnType() == Type::VoidTy)
Name = ""; // Make sure not to name a void call!
示例8: IHandle
//.........这里部分代码省略.........
while (OldPN->getNumOperands()) {
BasicBlock *BB = OldPN->getIncomingBlock(0);
Value *OldVal = OldPN->getIncomingValue(0);
ValueHandle OldValHandle(VMC, OldVal);
OldPN->removeIncomingValue(BB, false);
Value *V = ConvertExpressionToType(OldVal, Ty, VMC, TD);
NewPN->addIncoming(V, BB);
}
Res = NewPN;
break;
}
case Instruction::Malloc: {
Res = ConvertMallocToType(cast<MallocInst>(I), Ty, Name, VMC, TD);
break;
}
case Instruction::GetElementPtr: {
// GetElementPtr's are directly convertible to a pointer type if they have
// a number of zeros at the end. Because removing these values does not
// change the logical offset of the GEP, it is okay and fair to remove them.
// This can change this:
// %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0 ; <%List **>
// %t2 = cast %List * * %t1 to %List *
// into
// %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
//
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
// Check to see if there are zero elements that we can remove from the
// index array. If there are, check to see if removing them causes us to
// get to the right type...
//
std::vector<Value*> Indices(GEP->idx_begin(), GEP->idx_end());
const Type *BaseType = GEP->getPointerOperand()->getType();
const Type *PVTy = cast<PointerType>(Ty)->getElementType();
Res = 0;
while (!Indices.empty() &&
Indices.back() == Constant::getNullValue(Indices.back()->getType())){
Indices.pop_back();
if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) {
if (Indices.size() == 0)
Res = new CastInst(GEP->getPointerOperand(), BaseType); // NOOP CAST
else
Res = new GetElementPtrInst(GEP->getPointerOperand(), Indices, Name);
break;
}
}
if (Res == 0 && GEP->getNumOperands() == 2 &&
GEP->getType() == PointerType::get(Type::SByteTy)) {
// Otherwise, we can convert a GEP from one form to the other iff the
// current gep is of the form 'getelementptr sbyte*, unsigned N
// and we could convert this to an appropriate GEP for the new type.
//
const PointerType *NewSrcTy = PointerType::get(PVTy);
BasicBlock::iterator It = I;
// Check to see if 'N' is an expression that can be converted to
// the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(NewSrcTy, I->getOperand(1),
Indices, TD, &It);
if (ElTy) {
示例9: ExpressionConvertibleToType
// ExpressionConvertibleToType - Return true if it is possible
bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty,
ValueTypeCache &CTMap, const TargetData &TD) {
// Expression type must be holdable in a register.
if (!Ty->isFirstClassType())
return false;
ValueTypeCache::iterator CTMI = CTMap.find(V);
if (CTMI != CTMap.end()) return CTMI->second == Ty;
// If it's a constant... all constants can be converted to a different
// type.
//
if (isa<Constant>(V) && !isa<GlobalValue>(V))
return true;
CTMap[V] = Ty;
if (V->getType() == Ty) return true; // Expression already correct type!
Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return false; // Otherwise, we can't convert!
switch (I->getOpcode()) {
case Instruction::Cast:
// We can convert the expr if the cast destination type is losslessly
// convertible to the requested type.
if (!Ty->isLosslesslyConvertibleTo(I->getType())) return false;
// We also do not allow conversion of a cast that casts from a ptr to array
// of X to a *X. For example: cast [4 x %List *] * %val to %List * *
//
if (const PointerType *SPT =
dyn_cast<PointerType>(I->getOperand(0)->getType()))
if (const PointerType *DPT = dyn_cast<PointerType>(I->getType()))
if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
if (AT->getElementType() == DPT->getElementType())
return false;
break;
case Instruction::Add:
case Instruction::Sub:
if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false;
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD) ||
!ExpressionConvertibleToType(I->getOperand(1), Ty, CTMap, TD))
return false;
break;
case Instruction::Shr:
if (!Ty->isInteger()) return false;
if (Ty->isSigned() != V->getType()->isSigned()) return false;
// FALL THROUGH
case Instruction::Shl:
if (!Ty->isInteger()) return false;
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD))
return false;
break;
case Instruction::Load: {
LoadInst *LI = cast<LoadInst>(I);
if (!ExpressionConvertibleToType(LI->getPointerOperand(),
PointerType::get(Ty), CTMap, TD))
return false;
break;
}
case Instruction::PHI: {
PHINode *PN = cast<PHINode>(I);
// Be conservative if we find a giant PHI node.
if (PN->getNumIncomingValues() > 32) return false;
for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i)
if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD))
return false;
break;
}
case Instruction::Malloc:
if (!MallocConvertibleToType(cast<MallocInst>(I), Ty, CTMap, TD))
return false;
break;
case Instruction::GetElementPtr: {
// GetElementPtr's are directly convertible to a pointer type if they have
// a number of zeros at the end. Because removing these values does not
// change the logical offset of the GEP, it is okay and fair to remove them.
// This can change this:
// %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0 ; <%List **>
// %t2 = cast %List * * %t1 to %List *
// into
// %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
//
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
const PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy) return false; // GEP must always return a pointer...
const Type *PVTy = PTy->getElementType();
// Check to see if there are zero elements that we can remove from the
// index array. If there are, check to see if removing them causes us to
// get to the right type...
//
std::vector<Value*> Indices(GEP->idx_begin(), GEP->idx_end());
const Type *BaseType = GEP->getPointerOperand()->getType();
//.........这里部分代码省略.........
示例10: while
bool Aa::LowerGepPass::runOnFunction(Function &F)
{
const llvm::Type *ptr_int_type = TD->getIntPtrType(F.getContext());
for (Function::iterator bi = F.begin(), be = F.end(); bi != be; ++bi) {
BasicBlock *bb = bi;
BasicBlock::iterator ii = bb->begin();
while (ii != bb->end()) {
GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(ii);
BasicBlock::iterator gi = ii++;
if (!gep) {
continue;
}
for (llvm::Value::use_iterator ui = gep->use_begin(), ue = gep->use_end();
ui != ue; ++ui) {
Use &u = ui.getUse();
IOCode ioc = get_io_code(u);
if (ioc == NOT_IO)
continue;
u.set(CastInst::CreatePointerCast(gep->getPointerOperand()
, gep->getType()
, "", gep));
}
assert(gep->hasIndices() && "GEP without indices??");
llvm::Value *ptr = gep->getPointerOperand();
const Type *ctype = ptr->getType();
// deal with the base pointer first
llvm::Value *base = gep->getPointerOperand();
std::string base_name = gep->getNameStr() + ".base";
llvm::Value *address = new PtrToIntInst(base, ptr_int_type, base_name + ".cast", gi);
unsigned i = 0;
for (User::op_iterator oi = gep->idx_begin(), oe = gep->idx_end();
oi != oe; ++oi, ++i) {
llvm::Value *index = *oi;
llvm::Value *offset = NULL;
std::stringstream index_name;
index_name << gep->getNameStr() << ".idx." << i;
if (const SequentialType *qtype = dyn_cast<SequentialType>(ctype)) {
// multiply index by size of element
unsigned element_size = getTypePaddedSize(TD, qtype->getElementType());
const llvm::IntegerType *index_type = cast<IntegerType>(index->getType());
ConstantInt *cint = ConstantInt::get(index_type, element_size);
assert(cint && "uh oh!");
offset = BinaryOperator::Create(Instruction::Mul
, cint
, index
, index_name.str()
, gi);
ctype = qtype->getElementType();
} else if (const StructType *stype = dyn_cast<StructType>(ctype)) {
// calculate offset into the struct
const StructLayout *layout = TD->getStructLayout(stype);
unsigned idx = cast<ConstantInt>(index)->getValue().getZExtValue();
unsigned struct_offset = layout->getElementOffset(idx);
offset = ConstantInt::get(ptr_int_type, struct_offset);
ctype = stype->getElementType(idx);
} else
assert(false && "unhandled offset into composite type");
// add offset to the address
assert(address && "uh oh!");
std::stringstream add_name;
add_name << gep->getNameStr() << ".lvl." << i;
if (offset->getType() != address->getType()) {
offset = CastInst::CreateIntegerCast(offset, address->getType()
, false, offset->getName() + ".resized"
, gi);
}
address = BinaryOperator::Create(Instruction::Add
, address, offset
, add_name.str(), gi);
}
if (address->getType() != ptr_int_type)
address = CastInst::CreateIntegerCast(address, ptr_int_type
, false, address->getName() + ".final", gi);
Instruction *new_ptr = new IntToPtrInst(address, gep->getType()
, gep->getName() + ".cast");
ReplaceInstWithInst(bb->getInstList(), gi, new_ptr);
}
}
return true;
}
示例11: while
//
// Methods: insertBadIndexing()
//
// Description:
// This method modifieds GEP indexing expressions so that their indices are
// (most likely) below the bounds of the object pointed to by the source
// pointer. It does this by modifying the first index to be -1.
//
// Return value:
// true - One or more changes were made to the program.
// false - No changes were made to the program.
//
bool
FaultInjector::insertBadIndexing (Function & F) {
// Worklist of allocation sites to rewrite
std::vector<GetElementPtrInst *> WorkList;
//
// Find GEP instructions that index into an array. Add these to the
// worklist.
//
for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
BasicBlock & BB = *fI;
for (BasicBlock::iterator I = BB.begin(), bE = BB.end(); I != bE; ++I) {
if (GetElementPtrInst * GEP = dyn_cast<GetElementPtrInst>(I)) {
// Skip if we should not insert a fault.
if (!doFault()) continue;
WorkList.push_back (GEP);
}
}
}
// Flag whether the program was modified
bool modified = (WorkList.size() > 0);
//
// Iterator through the worklist and transform each GEP.
//
while (WorkList.size()) {
GetElementPtrInst * GEP = WorkList.back();
WorkList.pop_back();
//
// Print out where the fault will be inserted in the source code.
//
printSourceInfo ("Bad indexing", GEP);
// The index arguments to the new GEP
std::vector<Value *> args;
//
// Create a copy of the GEP's indices.
//
User::op_iterator i = GEP->idx_begin();
if (i == GEP->idx_end()) continue;
args.push_back (ConstantInt::get (Int32Type, INT_MAX, true));
for (++i; i != GEP->idx_end(); ++i) {
args.push_back (*i);
}
//
// Create the new GEP instruction.
//
Value * Pointer = GEP->getPointerOperand();
Twine name = GEP->getName() + "badindex";
GetElementPtrInst * NewGEP = GetElementPtrInst::Create (Pointer,
args.begin(),
args.end(),
name,
GEP);
GEP->replaceAllUsesWith (NewGEP);
GEP->eraseFromParent();
++BadIndices;
}
return modified;
}
示例12: CS
//.........这里部分代码省略.........
if (ByValArgsToTransform.count(&*I)) {
// In the callee, we create an alloca, and store each of the new incoming
// arguments into the alloca.
Instruction *InsertPt = &NF->begin()->front();
// Just add all the struct element types.
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
Value *TheAlloca = new AllocaInst(AgTy, DL.getAllocaAddrSpace(), nullptr,
I->getParamAlignment(), "", InsertPt);
StructType *STy = cast<StructType>(AgTy);
Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(F->getContext()), 0),
nullptr};
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
Idxs[1] = ConstantInt::get(Type::getInt32Ty(F->getContext()), i);
Value *Idx = GetElementPtrInst::Create(
AgTy, TheAlloca, Idxs, TheAlloca->getName() + "." + Twine(i),
InsertPt);
I2->setName(I->getName() + "." + Twine(i));
new StoreInst(&*I2++, Idx, InsertPt);
}
// Anything that used the arg should now use the alloca.
I->replaceAllUsesWith(TheAlloca);
TheAlloca->takeName(&*I);
// If the alloca is used in a call, we must clear the tail flag since
// the callee now uses an alloca from the caller.
for (User *U : TheAlloca->users()) {
CallInst *Call = dyn_cast<CallInst>(U);
if (!Call)
continue;
Call->setTailCall(false);
}
continue;
}
if (I->use_empty())
continue;
// Otherwise, if we promoted this argument, then all users are load
// instructions (or GEPs with only load users), and all loads should be
// using the new argument that we added.
ScalarizeTable &ArgIndices = ScalarizedElements[&*I];
while (!I->use_empty()) {
if (LoadInst *LI = dyn_cast<LoadInst>(I->user_back())) {
assert(ArgIndices.begin()->second.empty() &&
"Load element should sort to front!");
I2->setName(I->getName() + ".val");
LI->replaceAllUsesWith(&*I2);
LI->eraseFromParent();
DEBUG(dbgs() << "*** Promoted load of argument '" << I->getName()
<< "' in function '" << F->getName() << "'\n");
} else {
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->user_back());
IndicesVector Operands;
Operands.reserve(GEP->getNumIndices());
for (User::op_iterator II = GEP->idx_begin(), IE = GEP->idx_end();
II != IE; ++II)
Operands.push_back(cast<ConstantInt>(*II)->getSExtValue());
// GEPs with a single 0 index can be merged with direct loads
if (Operands.size() == 1 && Operands.front() == 0)
Operands.clear();
Function::arg_iterator TheArg = I2;
for (ScalarizeTable::iterator It = ArgIndices.begin();
It->second != Operands; ++It, ++TheArg) {
assert(It != ArgIndices.end() && "GEP not handled??");
}
std::string NewName = I->getName();
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
NewName += "." + utostr(Operands[i]);
}
NewName += ".val";
TheArg->setName(NewName);
DEBUG(dbgs() << "*** Promoted agg argument '" << TheArg->getName()
<< "' of function '" << NF->getName() << "'\n");
// All of the uses must be load instructions. Replace them all with
// the argument specified by ArgNo.
while (!GEP->use_empty()) {
LoadInst *L = cast<LoadInst>(GEP->user_back());
L->replaceAllUsesWith(&*TheArg);
L->eraseFromParent();
}
GEP->eraseFromParent();
}
}
// Increment I2 past all of the arguments added for this promoted pointer.
std::advance(I2, ArgIndices.size());
}
return NF;
}