本文整理汇总了C++中StructType::getNumElements方法的典型用法代码示例。如果您正苦于以下问题:C++ StructType::getNumElements方法的具体用法?C++ StructType::getNumElements怎么用?C++ StructType::getNumElements使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类StructType
的用法示例。
在下文中一共展示了StructType::getNumElements方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: appendToGlobalArray
static void appendToGlobalArray(const char *Array,
Module &M, Function *F, int Priority) {
IRBuilder<> IRB(M.getContext());
FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
// Get the current set of static global constructors and add the new ctor
// to the list.
SmallVector<Constant *, 16> CurrentCtors;
StructType *EltTy;
if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
// If there is a global_ctors array, use the existing struct type, which can
// have 2 or 3 fields.
ArrayType *ATy = cast<ArrayType>(GVCtor->getType()->getElementType());
EltTy = cast<StructType>(ATy->getElementType());
if (Constant *Init = GVCtor->getInitializer()) {
unsigned n = Init->getNumOperands();
CurrentCtors.reserve(n + 1);
for (unsigned i = 0; i != n; ++i)
CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
}
GVCtor->eraseFromParent();
} else {
// Use a simple two-field struct if there isn't one already.
EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
nullptr);
}
// Build a 2 or 3 field global_ctor entry. We don't take a comdat key.
Constant *CSVals[3];
CSVals[0] = IRB.getInt32(Priority);
CSVals[1] = F;
// FIXME: Drop support for the two element form in LLVM 4.0.
if (EltTy->getNumElements() >= 3)
CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
Constant *RuntimeCtorInit =
ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
CurrentCtors.push_back(RuntimeCtorInit);
// Create a new initializer.
ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size());
Constant *NewInit = ConstantArray::get(AT, CurrentCtors);
// Create the new global variable and replace all uses of
// the old global variable with the new one.
(void)new GlobalVariable(M, NewInit->getType(), false,
GlobalValue::AppendingLinkage, NewInit, Array);
}
示例2: switch
Value *AArch64TTIImpl::getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) {
switch (Inst->getIntrinsicID()) {
default:
return nullptr;
case Intrinsic::aarch64_neon_st2:
case Intrinsic::aarch64_neon_st3:
case Intrinsic::aarch64_neon_st4: {
// Create a struct type
StructType *ST = dyn_cast<StructType>(ExpectedType);
if (!ST)
return nullptr;
unsigned NumElts = Inst->getNumArgOperands() - 1;
if (ST->getNumElements() != NumElts)
return nullptr;
for (unsigned i = 0, e = NumElts; i != e; ++i) {
if (Inst->getArgOperand(i)->getType() != ST->getElementType(i))
return nullptr;
}
Value *Res = UndefValue::get(ExpectedType);
IRBuilder<> Builder(Inst);
for (unsigned i = 0, e = NumElts; i != e; ++i) {
Value *L = Inst->getArgOperand(i);
Res = Builder.CreateInsertValue(Res, L, i);
}
return Res;
}
case Intrinsic::aarch64_neon_ld2:
case Intrinsic::aarch64_neon_ld3:
case Intrinsic::aarch64_neon_ld4:
if (Inst->getType() == ExpectedType)
return Inst;
return nullptr;
}
}
示例3: isDenselyPacked
/// \brief Checks if a type could have padding bytes.
bool ArgPromotion::isDenselyPacked(Type *type) {
// There is no size information, so be conservative.
if (!type->isSized())
return false;
// If the alloc size is not equal to the storage size, then there are padding
// bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
if (!DL || DL->getTypeSizeInBits(type) != DL->getTypeAllocSizeInBits(type))
return false;
if (!isa<CompositeType>(type))
return true;
// For homogenous sequential types, check for padding within members.
if (SequentialType *seqTy = dyn_cast<SequentialType>(type))
return isa<PointerType>(seqTy) || isDenselyPacked(seqTy->getElementType());
// Check for padding within and between elements of a struct.
StructType *StructTy = cast<StructType>(type);
const StructLayout *Layout = DL->getStructLayout(StructTy);
uint64_t StartPos = 0;
for (unsigned i = 0, E = StructTy->getNumElements(); i < E; ++i) {
Type *ElTy = StructTy->getElementType(i);
if (!isDenselyPacked(ElTy))
return false;
if (StartPos != Layout->getElementOffsetInBits(i))
return false;
StartPos += DL->getTypeAllocSizeInBits(ElTy);
}
return true;
}
示例4: SplitUpPHINode
static void SplitUpPHINode(PHINode *Phi) {
StructType *STy = cast<StructType>(Phi->getType());
Value *NewStruct = UndefValue::get(STy);
Instruction *NewStructInsertPt = Phi->getParent()->getFirstInsertionPt();
// Create a separate PHINode for each struct field.
for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
PHINode *NewPhi = PHINode::Create(
STy->getElementType(Index), Phi->getNumIncomingValues(),
Phi->getName() + ".index", Phi);
CopyDebug(NewPhi, Phi);
for (unsigned PhiIndex = 0; PhiIndex < Phi->getNumIncomingValues();
++PhiIndex) {
BasicBlock *IncomingBB = Phi->getIncomingBlock(PhiIndex);
Value *EV = CopyDebug(
ExtractValueInst::Create(
Phi->getIncomingValue(PhiIndex), EVIndexes,
Phi->getName() + ".extract", IncomingBB->getTerminator()), Phi);
NewPhi->addIncoming(EV, IncomingBB);
}
// Reconstruct the original struct value.
NewStruct = CopyDebug(
InsertValueInst::Create(NewStruct, NewPhi, EVIndexes,
Phi->getName() + ".insert", NewStructInsertPt),
Phi);
}
Phi->replaceAllUsesWith(NewStruct);
Phi->eraseFromParent();
}
示例5: SplitUpStore
static bool SplitUpStore(StoreInst *Store, const DataLayout *DL) {
StructType *STy = cast<StructType>(Store->getValueOperand()->getType());
bool NeedsAnotherPass = false;
// Create a separate store instruction for each struct field.
for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
SmallVector<Value *, 2> Indexes;
Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0)));
Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index)));
Value *GEP =
CopyDebug(GetElementPtrInst::Create(STy,
Store->getPointerOperand(), Indexes,
Store->getPointerOperand()->getName() + ".index", Store),
Store);
NeedsAnotherPass =
NeedsAnotherPass || DoAnotherPass(GEP->getType()->getContainedType(0));
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
Value *Field = ExtractValueInst::Create(Store->getValueOperand(), EVIndexes,
"", Store);
StoreInst *NewStore = new StoreInst(Field, GEP, Store);
ProcessLoadOrStoreAttrs(NewStore, Store, STy, Index, DL);
}
Store->eraseFromParent();
return NeedsAnotherPass;
}
示例6: SplitUpLoad
static void SplitUpLoad(LoadInst *Load) {
StructType *STy = cast<StructType>(Load->getType());
Value *NewStruct = UndefValue::get(STy);
// Create a separate load instruction for each struct field.
for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
SmallVector<Value *, 2> Indexes;
Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, 0)));
Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, Index)));
Value *GEP = CopyDebug(
GetElementPtrInst::Create(Load->getPointerOperand(), Indexes,
Load->getName() + ".index", Load), Load);
LoadInst *NewLoad = new LoadInst(GEP, Load->getName() + ".field", Load);
ProcessLoadOrStoreAttrs(NewLoad, Load);
// Reconstruct the struct value.
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
NewStruct = CopyDebug(
InsertValueInst::Create(NewStruct, NewLoad, EVIndexes,
Load->getName() + ".insert", Load), Load);
}
Load->replaceAllUsesWith(NewStruct);
Load->eraseFromParent();
}
示例7: areTypesEquivalent
bool AllocaMerging::areTypesEquivalent(const cheerp::TypeSupport& types, cheerp::PointerAnalyzer& PA, Type* a, Type* b)
{
//TODO: Integer types may be equivalent as well
if(a==b)
return true;
else if(a->isPointerTy() && b->isPointerTy())
return true;
else if(a->isFloatingPointTy() && b->isFloatingPointTy())
return true;
else if(a->isArrayTy() && b->isArrayTy())
{
return cast<ArrayType>(a)->getNumElements()==cast<ArrayType>(b)->getNumElements() &&
areTypesEquivalent(types, PA, a->getArrayElementType(), b->getArrayElementType());
}
else if(a->isStructTy() && b->isStructTy())
{
// TODO: Byte layout structs with the same size are equivalent
if(cast<StructType>(a)->hasByteLayout() ||
cast<StructType>(b)->hasByteLayout())
return false;
StructType* stA = cast<StructType>(a);
StructType* stB = cast<StructType>(b);
if(stA->getNumElements() != stB->getNumElements())
return false;
for(uint32_t i=0;i<stA->getNumElements();i++)
{
Type* elementA = stA->getElementType(i);
Type* elementB = stB->getElementType(i);
// The types needs to have consistent wrapper arrays
if(types.useWrapperArrayForMember(PA, stA, i) ^ types.useWrapperArrayForMember(PA, stB, i))
return false;
if(!areTypesEquivalent(types, PA, elementA, elementB))
return false;
}
return true;
}
else
return false;
}
示例8: 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;
}
示例9: Verify
/// Verify - Verify that the specified constraint string is reasonable for the
/// specified function type, and otherwise validate the constraint string.
bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) {
if (Ty->isVarArg()) return false;
ConstraintInfoVector Constraints = ParseConstraints(ConstStr);
// Error parsing constraints.
if (Constraints.empty() && !ConstStr.empty()) return false;
unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
unsigned NumIndirect = 0;
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
switch (Constraints[i].Type) {
case InlineAsm::isOutput:
if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
return false; // outputs before inputs and clobbers.
if (!Constraints[i].isIndirect) {
++NumOutputs;
break;
}
++NumIndirect;
// FALLTHROUGH for Indirect Outputs.
case InlineAsm::isInput:
if (NumClobbers) return false; // inputs before clobbers.
++NumInputs;
break;
case InlineAsm::isClobber:
++NumClobbers;
break;
}
}
switch (NumOutputs) {
case 0:
if (!Ty->getReturnType()->isVoidTy()) return false;
break;
case 1:
if (Ty->getReturnType()->isStructTy()) return false;
break;
default:
StructType *STy = dyn_cast<StructType>(Ty->getReturnType());
if (!STy || STy->getNumElements() != NumOutputs)
return false;
break;
}
if (Ty->getNumParams() != NumInputs) return false;
return true;
}
示例10: SplitUpStore
static void SplitUpStore(StoreInst *Store) {
StructType *STy = cast<StructType>(Store->getValueOperand()->getType());
// Create a separate store instruction for each struct field.
for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
SmallVector<Value *, 2> Indexes;
Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0)));
Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index)));
Value *GEP = CopyDebug(GetElementPtrInst::Create(
Store->getPointerOperand(), Indexes,
Store->getPointerOperand()->getName() + ".index",
Store), Store);
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
Value *Field = ExtractValueInst::Create(Store->getValueOperand(),
EVIndexes, "", Store);
StoreInst *NewStore = new StoreInst(Field, GEP, Store);
ProcessLoadOrStoreAttrs(NewStore, Store);
}
Store->eraseFromParent();
}
示例11: linkDefinedTypeBodies
/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest
/// module from a type definition in the source module.
void TypeMapTy::linkDefinedTypeBodies() {
SmallVector<Type*, 16> Elements;
SmallString<16> TmpName;
// Note that processing entries in this loop (calling 'get') can add new
// entries to the SrcDefinitionsToResolve vector.
while (!SrcDefinitionsToResolve.empty()) {
StructType *SrcSTy = SrcDefinitionsToResolve.pop_back_val();
StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
// TypeMap is a many-to-one mapping, if there were multiple types that
// provide a body for DstSTy then previous iterations of this loop may have
// already handled it. Just ignore this case.
if (!DstSTy->isOpaque()) continue;
assert(!SrcSTy->isOpaque() && "Not resolving a definition?");
// Map the body of the source type over to a new body for the dest type.
Elements.resize(SrcSTy->getNumElements());
for (unsigned i = 0, e = Elements.size(); i != e; ++i)
Elements[i] = getImpl(SrcSTy->getElementType(i));
DstSTy->setBody(Elements, SrcSTy->isPacked());
// If DstSTy has no name or has a longer name than STy, then viciously steal
// STy's name.
if (!SrcSTy->hasName()) continue;
StringRef SrcName = SrcSTy->getName();
if (!DstSTy->hasName() || DstSTy->getName().size() > SrcName.size()) {
TmpName.insert(TmpName.end(), SrcName.begin(), SrcName.end());
SrcSTy->setName("");
DstSTy->setName(TmpName.str());
TmpName.clear();
}
}
DstResolvedOpaqueTypes.clear();
}
示例12: SplitUpSelect
static bool SplitUpSelect(SelectInst *Select) {
StructType *STy = cast<StructType>(Select->getType());
Value *NewStruct = UndefValue::get(STy);
bool NeedsAnotherPass = false;
// Create a separate SelectInst for each struct field.
for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) {
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
Value *TrueVal = CopyDebug(
ExtractValueInst::Create(Select->getTrueValue(), EVIndexes,
Select->getName() + ".extract", Select),
Select);
Value *FalseVal = CopyDebug(
ExtractValueInst::Create(Select->getFalseValue(), EVIndexes,
Select->getName() + ".extract", Select),
Select);
Value *NewSelect =
CopyDebug(SelectInst::Create(Select->getCondition(), TrueVal, FalseVal,
Select->getName() + ".index", Select),
Select);
NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass(NewSelect);
// Reconstruct the original struct value.
NewStruct = CopyDebug(
InsertValueInst::Create(NewStruct, NewSelect, EVIndexes,
Select->getName() + ".insert", Select),
Select);
}
Select->replaceAllUsesWith(NewStruct);
Select->eraseFromParent();
return NeedsAnotherPass;
}
示例13: B
/// 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,
SmallPtrSetImpl<Argument*> &ArgsToPromote,
SmallPtrSetImpl<Argument*> &ByValArgsToTransform) {
// 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;
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.
// 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> AttributesVec;
const AttributeSet &PAL = F->getAttributes();
// Add any return attributes.
if (PAL.hasAttributes(AttributeSet::ReturnIndex))
AttributesVec.push_back(AttributeSet::get(F->getContext(),
PAL.getRetAttributes()));
// 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.
Type *AgTy = cast<PointerType>(I->getType())->getElementType();
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());
AttributeSet attrs = PAL.getParamAttributes(ArgIndex);
if (attrs.hasAttributes(ArgIndex)) {
AttrBuilder B(attrs, ArgIndex);
AttributesVec.
push_back(AttributeSet::get(F->getContext(), Params.size(), B));
}
} 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 (User *U : I->users()) {
Instruction *UI = cast<Instruction>(U);
assert(isa<LoadInst>(UI) || isa<GetElementPtrInst>(UI));
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(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 (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));
//.........这里部分代码省略.........
示例14: PropagateConstantReturn
// Check to see if this function returns one or more constants. If so, replace
// all callers that use those return values with the constant value. This will
// leave in the actual return values and instructions, but deadargelim will
// clean that up.
//
// Additionally if a function always returns one of its arguments directly,
// callers will be updated to use the value they pass in directly instead of
// using the return value.
bool IPCP::PropagateConstantReturn(Function &F) {
if (F.getReturnType()->isVoidTy())
return false; // No return value.
// If this function could be overridden later in the link stage, we can't
// propagate information about its results into callers.
if (F.mayBeOverridden())
return false;
// Check to see if this function returns a constant.
SmallVector<Value *,4> RetVals;
StructType *STy = dyn_cast<StructType>(F.getReturnType());
if (STy)
for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i)
RetVals.push_back(UndefValue::get(STy->getElementType(i)));
else
RetVals.push_back(UndefValue::get(F.getReturnType()));
unsigned NumNonConstant = 0;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
// Already found conflicting return values?
Value *RV = RetVals[i];
if (!RV)
continue;
// Find the returned value
Value *V;
if (!STy)
V = RI->getOperand(0);
else
V = FindInsertedValue(RI->getOperand(0), i);
if (V) {
// Ignore undefs, we can change them into anything
if (isa<UndefValue>(V))
continue;
// Try to see if all the rets return the same constant or argument.
if (isa<Constant>(V) || isa<Argument>(V)) {
if (isa<UndefValue>(RV)) {
// No value found yet? Try the current one.
RetVals[i] = V;
continue;
}
// Returning the same value? Good.
if (RV == V)
continue;
}
}
// Different or no known return value? Don't propagate this return
// value.
RetVals[i] = 0;
// All values non constant? Stop looking.
if (++NumNonConstant == RetVals.size())
return false;
}
}
// If we got here, the function returns at least one constant value. Loop
// over all users, replacing any uses of the return value with the returned
// constant.
bool MadeChange = false;
for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
CallSite CS(*UI);
Instruction* Call = CS.getInstruction();
// Not a call instruction or a call instruction that's not calling F
// directly?
if (!Call || !CS.isCallee(UI))
continue;
// Call result not used?
if (Call->use_empty())
continue;
MadeChange = true;
if (STy == 0) {
Value* New = RetVals[0];
if (Argument *A = dyn_cast<Argument>(New))
// Was an argument returned? Then find the corresponding argument in
// the call instruction and use that.
New = CS.getArgument(A->getArgNo());
Call->replaceAllUsesWith(New);
continue;
}
for (Value::use_iterator I = Call->use_begin(), E = Call->use_end();
I != E;) {
Instruction *Ins = cast<Instruction>(*I);
//.........这里部分代码省略.........
示例15: cmpTypes
/// cmpType - compares two types,
/// defines total ordering among the types set.
/// See method declaration comments for more details.
int FunctionComparator::cmpTypes(Type *TyL, Type *TyR) const {
PointerType *PTyL = dyn_cast<PointerType>(TyL);
PointerType *PTyR = dyn_cast<PointerType>(TyR);
const DataLayout &DL = FnL->getParent()->getDataLayout();
if (PTyL && PTyL->getAddressSpace() == 0)
TyL = DL.getIntPtrType(TyL);
if (PTyR && PTyR->getAddressSpace() == 0)
TyR = DL.getIntPtrType(TyR);
if (TyL == TyR)
return 0;
if (int Res = cmpNumbers(TyL->getTypeID(), TyR->getTypeID()))
return Res;
switch (TyL->getTypeID()) {
default:
llvm_unreachable("Unknown type!");
// Fall through in Release mode.
LLVM_FALLTHROUGH;
case Type::IntegerTyID:
return cmpNumbers(cast<IntegerType>(TyL)->getBitWidth(),
cast<IntegerType>(TyR)->getBitWidth());
// TyL == TyR would have returned true earlier, because types are uniqued.
case Type::VoidTyID:
case Type::FloatTyID:
case Type::DoubleTyID:
case Type::X86_FP80TyID:
case Type::FP128TyID:
case Type::PPC_FP128TyID:
case Type::LabelTyID:
case Type::MetadataTyID:
case Type::TokenTyID:
return 0;
case Type::PointerTyID: {
assert(PTyL && PTyR && "Both types must be pointers here.");
return cmpNumbers(PTyL->getAddressSpace(), PTyR->getAddressSpace());
}
case Type::StructTyID: {
StructType *STyL = cast<StructType>(TyL);
StructType *STyR = cast<StructType>(TyR);
if (STyL->getNumElements() != STyR->getNumElements())
return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
if (STyL->isPacked() != STyR->isPacked())
return cmpNumbers(STyL->isPacked(), STyR->isPacked());
for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) {
if (int Res = cmpTypes(STyL->getElementType(i), STyR->getElementType(i)))
return Res;
}
return 0;
}
case Type::FunctionTyID: {
FunctionType *FTyL = cast<FunctionType>(TyL);
FunctionType *FTyR = cast<FunctionType>(TyR);
if (FTyL->getNumParams() != FTyR->getNumParams())
return cmpNumbers(FTyL->getNumParams(), FTyR->getNumParams());
if (FTyL->isVarArg() != FTyR->isVarArg())
return cmpNumbers(FTyL->isVarArg(), FTyR->isVarArg());
if (int Res = cmpTypes(FTyL->getReturnType(), FTyR->getReturnType()))
return Res;
for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
if (int Res = cmpTypes(FTyL->getParamType(i), FTyR->getParamType(i)))
return Res;
}
return 0;
}
case Type::ArrayTyID:
case Type::VectorTyID: {
auto *STyL = cast<SequentialType>(TyL);
auto *STyR = cast<SequentialType>(TyR);
if (STyL->getNumElements() != STyR->getNumElements())
return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());
return cmpTypes(STyL->getElementType(), STyR->getElementType());
}
}
}