当前位置: 首页>>代码示例>>C++>>正文


C++ StructType::getNumElements方法代码示例

本文整理汇总了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);
}
开发者ID:hsorby,项目名称:opencor,代码行数:48,代码来源:ModuleUtils.cpp

示例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;
  }
}
开发者ID:RichardsonAlex,项目名称:llvm-1,代码行数:35,代码来源:AArch64TargetTransformInfo.cpp

示例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;
}
开发者ID:Drup,项目名称:llvm,代码行数:34,代码来源:ArgumentPromotion.cpp

示例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();
}
开发者ID:sriramnrn,项目名称:llvm-port,代码行数:34,代码来源:ExpandStructRegs.cpp

示例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;
}
开发者ID:leaningtech,项目名称:cheerp-llvm,代码行数:28,代码来源:ExpandStructRegs.cpp

示例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();
}
开发者ID:sriramnrn,项目名称:llvm-port,代码行数:25,代码来源:ExpandStructRegs.cpp

示例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;
}
开发者ID:IamSpid3r,项目名称:cheerp-llvm,代码行数:39,代码来源:AllocaMerging.cpp

示例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;
}
开发者ID:FreeBSDFoundation,项目名称:freebsd,代码行数:50,代码来源:EfficiencySanitizer.cpp

示例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;
}
开发者ID:2asoft,项目名称:freebsd,代码行数:51,代码来源:InlineAsm.cpp

示例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();
}
开发者ID:sriramnrn,项目名称:llvm-port,代码行数:20,代码来源:ExpandStructRegs.cpp

示例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();
}
开发者ID:groue,项目名称:llvm,代码行数:40,代码来源:LinkModules.cpp

示例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;
}
开发者ID:leaningtech,项目名称:cheerp-llvm,代码行数:36,代码来源:ExpandStructRegs.cpp

示例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));
//.........这里部分代码省略.........
开发者ID:Drup,项目名称:llvm,代码行数:101,代码来源:ArgumentPromotion.cpp

示例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);
//.........这里部分代码省略.........
开发者ID:,项目名称:,代码行数:101,代码来源:

示例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());
  }
  }
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:89,代码来源:FunctionComparator.cpp


注:本文中的StructType::getNumElements方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。