本文整理汇总了C++中function::arg_iterator::use_empty方法的典型用法代码示例。如果您正苦于以下问题:C++ arg_iterator::use_empty方法的具体用法?C++ arg_iterator::use_empty怎么用?C++ arg_iterator::use_empty使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类function::arg_iterator
的用法示例。
在下文中一共展示了arg_iterator::use_empty方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: StoreInst
/// DoPromotion - This method actually performs the promotion of the specified
/// arguments, and returns the new function. At this point, we know that it's
/// safe to do so.
CallGraphNode *ArgPromotion::DoPromotion(Function *F,
SmallPtrSet<Argument*, 8> &ArgsToPromote,
SmallPtrSet<Argument*, 8> &ByValArgsToTransform) {
// Start by computing a new prototype for the function, which is the same as
// the old function, but has modified arguments.
const FunctionType *FTy = F->getFunctionType();
std::vector<const Type*> Params;
typedef std::set<IndicesVector> ScalarizeTable;
// ScalarizedElements - If we are promoting a pointer that has elements
// accessed out of it, keep track of which elements are accessed so that we
// can add one argument for each.
//
// Arguments that are directly loaded will have a zero element value here, to
// handle cases where there are both a direct load and GEP accesses.
//
std::map<Argument*, ScalarizeTable> ScalarizedElements;
// OriginalLoads - Keep track of a representative load instruction from the
// original function so that we can tell the alias analysis implementation
// what the new GEP/Load instructions we are inserting look like.
std::map<IndicesVector, LoadInst*> OriginalLoads;
// Attributes - Keep track of the parameter attributes for the arguments
// that we are *not* promoting. For the ones that we do promote, the parameter
// attributes are lost
SmallVector<AttributeWithIndex, 8> AttributesVec;
const AttrListPtr &PAL = F->getAttributes();
// Add any return attributes.
if (Attributes attrs = PAL.getRetAttributes())
AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
// First, determine the new argument list
unsigned ArgIndex = 1;
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
++I, ++ArgIndex) {
if (ByValArgsToTransform.count(I)) {
// Simple byval argument? Just add all the struct element types.
const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
const StructType *STy = cast<StructType>(AgTy);
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
Params.push_back(STy->getElementType(i));
++NumByValArgsPromoted;
} else if (!ArgsToPromote.count(I)) {
// Unchanged argument
Params.push_back(I->getType());
if (Attributes attrs = PAL.getParamAttributes(ArgIndex))
AttributesVec.push_back(AttributeWithIndex::get(Params.size(), attrs));
} else if (I->use_empty()) {
// Dead argument (which are always marked as promotable)
++NumArgumentsDead;
} else {
// Okay, this is being promoted. This means that the only uses are loads
// or GEPs which are only used by loads
// In this table, we will track which indices are loaded from the argument
// (where direct loads are tracked as no indices).
ScalarizeTable &ArgIndices = ScalarizedElements[I];
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
++UI) {
Instruction *User = cast<Instruction>(*UI);
assert(isa<LoadInst>(User) || isa<GetElementPtrInst>(User));
IndicesVector Indices;
Indices.reserve(User->getNumOperands() - 1);
// Since loads will only have a single operand, and GEPs only a single
// non-index operand, this will record direct loads without any indices,
// and gep+loads with the GEP indices.
for (User::op_iterator II = User->op_begin() + 1, IE = User->op_end();
II != IE; ++II)
Indices.push_back(cast<ConstantInt>(*II)->getSExtValue());
// GEPs with a single 0 index can be merged with direct loads
if (Indices.size() == 1 && Indices.front() == 0)
Indices.clear();
ArgIndices.insert(Indices);
LoadInst *OrigLoad;
if (LoadInst *L = dyn_cast<LoadInst>(User))
OrigLoad = L;
else
// Take any load, we will use it only to update Alias Analysis
OrigLoad = cast<LoadInst>(User->use_back());
OriginalLoads[Indices] = OrigLoad;
}
// Add a parameter to the function for each element passed in.
for (ScalarizeTable::iterator SI = ArgIndices.begin(),
E = ArgIndices.end(); SI != E; ++SI) {
// not allowed to dereference ->begin() if size() is 0
Params.push_back(GetElementPtrInst::getIndexedType(I->getType(),
SI->begin(),
SI->end()));
assert(Params.back());
}
if (ArgIndices.size() == 1 && ArgIndices.begin()->empty())
//.........这里部分代码省略.........
示例2: InsertProfilingInitCall
void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName,
GlobalValue *Array) {
const Type *ArgVTy =
PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty));
const PointerType *UIntPtr = PointerType::getUnqual(Type::Int32Ty);
Module &M = *MainFn->getParent();
Constant *InitFn = M.getOrInsertFunction(FnName, Type::Int32Ty, Type::Int32Ty,
ArgVTy, UIntPtr, Type::Int32Ty,
(Type *)0);
// This could force argc and argv into programs that wouldn't otherwise have
// them, but instead we just pass null values in.
std::vector<Value*> Args(4);
Args[0] = Constant::getNullValue(Type::Int32Ty);
Args[1] = Constant::getNullValue(ArgVTy);
// Skip over any allocas in the entry block.
BasicBlock *Entry = MainFn->begin();
BasicBlock::iterator InsertPos = Entry->begin();
while (isa<AllocaInst>(InsertPos)) ++InsertPos;
std::vector<Constant*> GEPIndices(2, Constant::getNullValue(Type::Int32Ty));
unsigned NumElements = 0;
if (Array) {
Args[2] = ConstantExpr::getGetElementPtr(Array, &GEPIndices[0],
GEPIndices.size());
NumElements =
cast<ArrayType>(Array->getType()->getElementType())->getNumElements();
} else {
// If this profiling instrumentation doesn't have a constant array, just
// pass null.
Args[2] = ConstantPointerNull::get(UIntPtr);
}
Args[3] = ConstantInt::get(Type::Int32Ty, NumElements);
Instruction *InitCall = CallInst::Create(InitFn, Args.begin(), Args.end(),
"newargc", InsertPos);
// If argc or argv are not available in main, just pass null values in.
Function::arg_iterator AI;
switch (MainFn->arg_size()) {
default:
case 2:
AI = MainFn->arg_begin(); ++AI;
if (AI->getType() != ArgVTy) {
Instruction::CastOps opcode = CastInst::getCastOpcode(AI, false, ArgVTy,
false);
InitCall->setOperand(2,
CastInst::create(opcode, AI, ArgVTy, "argv.cast", InitCall));
} else {
InitCall->setOperand(2, AI);
}
/* FALL THROUGH */
case 1:
AI = MainFn->arg_begin();
// If the program looked at argc, have it look at the return value of the
// init call instead.
if (AI->getType() != Type::Int32Ty) {
Instruction::CastOps opcode;
if (!AI->use_empty()) {
opcode = CastInst::getCastOpcode(InitCall, true, AI->getType(), true);
AI->replaceAllUsesWith(
CastInst::create(opcode, InitCall, AI->getType(), "", InsertPos));
}
opcode = CastInst::getCastOpcode(AI, true, Type::Int32Ty, true);
InitCall->setOperand(1,
CastInst::create(opcode, AI, Type::Int32Ty, "argc.cast", InitCall));
} else {
AI->replaceAllUsesWith(InitCall);
InitCall->setOperand(1, AI);
}
case 0: break;
}
}
示例3: PropagateConstantsIntoArguments
/// PropagateConstantsIntoArguments - Look at all uses of the specified
/// function. If all uses are direct call sites, and all pass a particular
/// constant in for an argument, propagate that constant in as the argument.
///
bool IPCP::PropagateConstantsIntoArguments(Function &F) {
if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit.
// For each argument, keep track of its constant value and whether it is a
// constant or not. The bool is driven to true when found to be non-constant.
SmallVector<std::pair<Constant*, bool>, 16> ArgumentConstants;
ArgumentConstants.resize(F.arg_size());
unsigned NumNonconstant = 0;
for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
User *U = *UI;
// Ignore blockaddress uses.
if (isa<BlockAddress>(U)) continue;
// Used by a non-instruction, or not the callee of a function, do not
// transform.
if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
return false;
CallSite CS(cast<Instruction>(U));
if (!CS.isCallee(UI))
return false;
// Check out all of the potentially constant arguments. Note that we don't
// inspect varargs here.
CallSite::arg_iterator AI = CS.arg_begin();
Function::arg_iterator Arg = F.arg_begin();
for (unsigned i = 0, e = ArgumentConstants.size(); i != e;
++i, ++AI, ++Arg) {
// If this argument is known non-constant, ignore it.
if (ArgumentConstants[i].second)
continue;
Constant *C = dyn_cast<Constant>(*AI);
if (C && ArgumentConstants[i].first == 0) {
ArgumentConstants[i].first = C; // First constant seen.
} else if (C && ArgumentConstants[i].first == C) {
// Still the constant value we think it is.
} else if (*AI == &*Arg) {
// Ignore recursive calls passing argument down.
} else {
// Argument became non-constant. If all arguments are non-constant now,
// give up on this function.
if (++NumNonconstant == ArgumentConstants.size())
return false;
ArgumentConstants[i].second = true;
}
}
}
// If we got to this point, there is a constant argument!
assert(NumNonconstant != ArgumentConstants.size());
bool MadeChange = false;
Function::arg_iterator AI = F.arg_begin();
for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI) {
// Do we have a constant argument?
if (ArgumentConstants[i].second || AI->use_empty() ||
(AI->hasByValAttr() && !F.onlyReadsMemory()))
continue;
Value *V = ArgumentConstants[i].first;
if (V == 0) V = UndefValue::get(AI->getType());
AI->replaceAllUsesWith(V);
++NumArgumentsProped;
MadeChange = true;
}
return MadeChange;
}
示例4: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// Clone functions that take GEPs as arguments
//
// 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 GEPExprArgs::runOnModule(Module& M) {
bool changed;
do {
changed = false;
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;) {
CallInst *CI = dyn_cast<CallInst>(I++);
if(!CI)
continue;
if(CI->hasByValArgument())
continue;
// if the GEP calls a function, that is externally defined,
// or might be changed, ignore this call site.
Function *F = CI->getCalledFunction();
if (!F || (F->isDeclaration() || F->mayBeOverridden()))
continue;
if(F->hasStructRetAttr())
continue;
if(F->isVarArg())
continue;
// find the argument we must replace
Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
unsigned argNum = 1;
for(; argNum < CI->getNumOperands();argNum++, ++ai) {
if(ai->use_empty())
continue;
if (isa<GEPOperator>(CI->getOperand(argNum)))
break;
}
// if no argument was a GEP operator to be changed
if(ai == ae)
continue;
GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum));
if(!GEP->hasAllConstantIndices())
continue;
// Construct the new Type
// Appends the struct Type at the beginning
std::vector<Type*>TP;
TP.push_back(GEP->getPointerOperand()->getType());
for(unsigned c = 1; c < CI->getNumOperands();c++) {
TP.push_back(CI->getOperand(c)->getType());
}
//return type is same as that of original instruction
FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
Function *NewF;
numSimplified++;
if(numSimplified > 800)
return true;
NewF = Function::Create(NewFTy,
GlobalValue::InternalLinkage,
F->getName().str() + ".TEST",
&M);
Function::arg_iterator NI = NewF->arg_begin();
NI->setName("GEParg");
++NI;
ValueToValueMapTy ValueMap;
for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
ValueMap[II] = NI;
NI->setName(II->getName());
NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1));
}
NewF->setAttributes(NewF->getAttributes().addAttr(
0, F->getAttributes().getRetAttributes()));
// Perform the cloning.
SmallVector<ReturnInst*,100> Returns;
CloneFunctionInto(NewF, F, ValueMap, false, Returns);
std::vector<Value*> fargs;
for(Function::arg_iterator ai = NewF->arg_begin(),
ae= NewF->arg_end(); ai != ae; ++ai) {
fargs.push_back(ai);
}
//.........这里部分代码省略.........
示例5: getValueType
/// LowerArguments - V8 uses a very simple ABI, where all values are passed in
/// either one or two GPRs, including FP values. TODO: we should pass FP values
/// in FP registers for fastcc functions.
void
SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &ArgValues,
DebugLoc dl) {
MachineFunction &MF = DAG.getMachineFunction();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
static const unsigned ArgRegs[] = {
SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
};
const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6;
unsigned ArgOffset = 68;
SDValue Root = DAG.getRoot();
std::vector<SDValue> OutChains;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
MVT ObjectVT = getValueType(I->getType());
switch (ObjectVT.getSimpleVT()) {
default: assert(0 && "Unhandled argument type!");
case MVT::i1:
case MVT::i8:
case MVT::i16:
case MVT::i32:
if (I->use_empty()) { // Argument is dead.
if (CurArgReg < ArgRegEnd) ++CurArgReg;
ArgValues.push_back(DAG.getUNDEF(ObjectVT));
} else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
if (ObjectVT != MVT::i32) {
unsigned AssertOp = ISD::AssertSext;
Arg = DAG.getNode(AssertOp, dl, MVT::i32, Arg,
DAG.getValueType(ObjectVT));
Arg = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Arg);
}
ArgValues.push_back(Arg);
} else {
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
SDValue Load;
if (ObjectVT == MVT::i32) {
Load = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0);
} else {
ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
// Sparc is big endian, so add an offset based on the ObjectVT.
unsigned Offset = 4-std::max(1U, ObjectVT.getSizeInBits()/8);
FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr,
DAG.getConstant(Offset, MVT::i32));
Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Root, FIPtr,
NULL, 0, ObjectVT);
Load = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Load);
}
ArgValues.push_back(Load);
}
ArgOffset += 4;
break;
case MVT::f32:
if (I->use_empty()) { // Argument is dead.
if (CurArgReg < ArgRegEnd) ++CurArgReg;
ArgValues.push_back(DAG.getUNDEF(ObjectVT));
} else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
// FP value is passed in an integer register.
unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32);
Arg = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Arg);
ArgValues.push_back(Arg);
} else {
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
SDValue Load = DAG.getLoad(MVT::f32, dl, Root, FIPtr, NULL, 0);
ArgValues.push_back(Load);
}
ArgOffset += 4;
break;
case MVT::i64:
case MVT::f64:
if (I->use_empty()) { // Argument is dead.
if (CurArgReg < ArgRegEnd) ++CurArgReg;
if (CurArgReg < ArgRegEnd) ++CurArgReg;
ArgValues.push_back(DAG.getUNDEF(ObjectVT));
} else {
SDValue HiVal;
if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
MF.getRegInfo().addLiveIn(*CurArgReg++, VRegHi);
HiVal = DAG.getCopyFromReg(Root, dl, VRegHi, MVT::i32);
} else {
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
//.........这里部分代码省略.........
示例6: runOnModule
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass.
// Clone functions that take LoadInsts as arguments
//
// 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 LoadArgs::runOnModule(Module& M) {
std::map<std::pair<Function*, const Type * > , Function* > fnCache;
bool changed;
do {
changed = false;
for (Module::iterator Func = M.begin(); Func != M.end(); ++Func) {
for (Function::iterator B = Func->begin(), FE = Func->end(); B != FE; ++B) {
for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
CallInst *CI = dyn_cast<CallInst>(I++);
if(!CI)
continue;
if(CI->hasByValArgument())
continue;
// if the CallInst calls a function, that is externally defined,
// or might be changed, ignore this call site.
Function *F = CI->getCalledFunction();
if (!F || (F->isDeclaration() || F->mayBeOverridden()))
continue;
if(F->hasStructRetAttr())
continue;
if(F->isVarArg())
continue;
// find the argument we must replace
Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
unsigned argNum = 0;
for(; argNum < CI->getNumArgOperands();argNum++, ++ai) {
// do not care about dead arguments
if(ai->use_empty())
continue;
if(F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::SExt) ||
F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::ZExt))
continue;
if (isa<LoadInst>(CI->getArgOperand(argNum)))
break;
}
// if no argument was a GEP operator to be changed
if(ai == ae)
continue;
LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(argNum));
Instruction * InsertPt = &(Func->getEntryBlock().front());
AllocaInst *NewVal = new AllocaInst(LI->getType(), "",InsertPt);
StoreInst *Copy = new StoreInst(LI, NewVal);
Copy->insertAfter(LI);
/*if(LI->getParent() != CI->getParent())
continue;
// Also check that there is no store after the load.
// TODO: Check if the load/store do not alias.
BasicBlock::iterator bii = LI->getParent()->begin();
Instruction *BII = bii;
while(BII != LI) {
++bii;
BII = bii;
}
while(BII != CI) {
if(isa<StoreInst>(BII))
break;
++bii;
BII = bii;
}
if(isa<StoreInst>(bii)){
continue;
}*/
// Construct the new Type
// Appends the struct Type at the beginning
std::vector<Type*>TP;
for(unsigned c = 0; c < CI->getNumArgOperands();c++) {
if(c == argNum)
TP.push_back(LI->getPointerOperand()->getType());
TP.push_back(CI->getArgOperand(c)->getType());
}
//return type is same as that of original instruction
FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
numSimplified++;
//if(numSimplified > 1000)
//return true;
//.........这里部分代码省略.........
示例7: CS
/// DoPromotion - This method actually performs the promotion of the specified
/// arguments, and returns the new function. At this point, we know that it's
/// safe to do so.
static Function *
doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
SmallPtrSetImpl<Argument *> &ByValArgsToTransform,
Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>>
ReplaceCallSite) {
// Start by computing a new prototype for the function, which is the same as
// the old function, but has modified arguments.
FunctionType *FTy = F->getFunctionType();
std::vector<Type *> Params;
using ScalarizeTable = std::set<std::pair<Type *, IndicesVector>>;
// ScalarizedElements - If we are promoting a pointer that has elements
// accessed out of it, keep track of which elements are accessed so that we
// can add one argument for each.
//
// Arguments that are directly loaded will have a zero element value here, to
// handle cases where there are both a direct load and GEP accesses.
std::map<Argument *, ScalarizeTable> ScalarizedElements;
// OriginalLoads - Keep track of a representative load instruction from the
// original function so that we can tell the alias analysis implementation
// what the new GEP/Load instructions we are inserting look like.
// We need to keep the original loads for each argument and the elements
// of the argument that are accessed.
std::map<std::pair<Argument *, IndicesVector>, LoadInst *> OriginalLoads;
// Attribute - Keep track of the parameter attributes for the arguments
// that we are *not* promoting. For the ones that we do promote, the parameter
// attributes are lost
SmallVector<AttributeSet, 8> ArgAttrVec;
AttributeList PAL = F->getAttributes();
// First, determine the new argument list
unsigned ArgNo = 0;
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
++I, ++ArgNo) {
if (ByValArgsToTransform.count(&*I)) {
// Simple byval argument? Just add all the struct element types.
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
StructType *STy = cast<StructType>(AgTy);
Params.insert(Params.end(), STy->element_begin(), STy->element_end());
ArgAttrVec.insert(ArgAttrVec.end(), STy->getNumElements(),
AttributeSet());
++NumByValArgsPromoted;
} else if (!ArgsToPromote.count(&*I)) {
// Unchanged argument
Params.push_back(I->getType());
ArgAttrVec.push_back(PAL.getParamAttributes(ArgNo));
} else if (I->use_empty()) {
// Dead argument (which are always marked as promotable)
++NumArgumentsDead;
// There may be remaining metadata uses of the argument for things like
// llvm.dbg.value. Replace them with undef.
I->replaceAllUsesWith(UndefValue::get(I->getType()));
} else {
// Okay, this is being promoted. This means that the only uses are loads
// or GEPs which are only used by loads
// In this table, we will track which indices are loaded from the argument
// (where direct loads are tracked as no indices).
ScalarizeTable &ArgIndices = ScalarizedElements[&*I];
for (User *U : I->users()) {
Instruction *UI = cast<Instruction>(U);
Type *SrcTy;
if (LoadInst *L = dyn_cast<LoadInst>(UI))
SrcTy = L->getType();
else
SrcTy = cast<GetElementPtrInst>(UI)->getSourceElementType();
IndicesVector Indices;
Indices.reserve(UI->getNumOperands() - 1);
// Since loads will only have a single operand, and GEPs only a single
// non-index operand, this will record direct loads without any indices,
// and gep+loads with the GEP indices.
for (User::op_iterator II = UI->op_begin() + 1, IE = UI->op_end();
II != IE; ++II)
Indices.push_back(cast<ConstantInt>(*II)->getSExtValue());
// GEPs with a single 0 index can be merged with direct loads
if (Indices.size() == 1 && Indices.front() == 0)
Indices.clear();
ArgIndices.insert(std::make_pair(SrcTy, Indices));
LoadInst *OrigLoad;
if (LoadInst *L = dyn_cast<LoadInst>(UI))
OrigLoad = L;
else
// Take any load, we will use it only to update Alias Analysis
OrigLoad = cast<LoadInst>(UI->user_back());
OriginalLoads[std::make_pair(&*I, Indices)] = OrigLoad;
}
// Add a parameter to the function for each element passed in.
for (const auto &ArgIndex : ArgIndices) {
// not allowed to dereference ->begin() if size() is 0
Params.push_back(GetElementPtrInst::getIndexedType(
cast<PointerType>(I->getType()->getScalarType())->getElementType(),
ArgIndex.second));
//.........这里部分代码省略.........