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


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

本文整理汇总了C++中StructType::getElementType方法的典型用法代码示例。如果您正苦于以下问题:C++ StructType::getElementType方法的具体用法?C++ StructType::getElementType怎么用?C++ StructType::getElementType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在StructType的用法示例。


在下文中一共展示了StructType::getElementType方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: 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

示例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: 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

示例5: 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

示例6: cmpType

/// cmpType - compares two types,
/// defines total ordering among the types set.
/// See method declaration comments for more details.
int FunctionComparator::cmpType(Type *TyL, Type *TyR) const {

  PointerType *PTyL = dyn_cast<PointerType>(TyL);
  PointerType *PTyR = dyn_cast<PointerType>(TyR);

  if (DL) {
    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.
  case Type::IntegerTyID:
  case Type::VectorTyID:
    // TyL == TyR would have returned true earlier.
    return cmpNumbers((uint64_t)TyL, (uint64_t)TyR);

  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:
    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 = cmpType(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 = cmpType(FTyL->getReturnType(), FTyR->getReturnType()))
      return Res;

    for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
      if (int Res = cmpType(FTyL->getParamType(i), FTyR->getParamType(i)))
        return Res;
    }
    return 0;
  }

  case Type::ArrayTyID: {
    ArrayType *ATyL = cast<ArrayType>(TyL);
    ArrayType *ATyR = cast<ArrayType>(TyR);
    if (ATyL->getNumElements() != ATyR->getNumElements())
      return cmpNumbers(ATyL->getNumElements(), ATyR->getNumElements());
    return cmpType(ATyL->getElementType(), ATyR->getElementType());
  }
  }
}
开发者ID:compnerd,项目名称:llvm,代码行数:88,代码来源:MergeFunctions.cpp

示例7: RemoveDeadStuffFromFunction

// RemoveDeadStuffFromFunction - Remove any arguments and return values from F
// that are not in LiveValues. Transform the function and all of the callees of
// the function to not have these arguments and return values.
//
bool DAE::RemoveDeadStuffFromFunction(Function *F) {
  // Don't modify fully live functions
  if (LiveFunctions.count(F))
    return false;

  // Start by computing a new prototype for the function, which is the same as
  // the old function, but has fewer arguments and a different return type.
  FunctionType *FTy = F->getFunctionType();
  std::vector<Type*> Params;

  // Set up to build a new list of parameter attributes.
  SmallVector<AttributeWithIndex, 8> AttributesVec;
  const AttributeSet &PAL = F->getAttributes();

  // Find out the new return value.
  Type *RetTy = FTy->getReturnType();
  Type *NRetTy = NULL;
  unsigned RetCount = NumRetVals(F);

  // -1 means unused, other numbers are the new index
  SmallVector<int, 5> NewRetIdxs(RetCount, -1);
  std::vector<Type*> RetTypes;
  if (RetTy->isVoidTy()) {
    NRetTy = RetTy;
  } else {
    StructType *STy = dyn_cast<StructType>(RetTy);
    if (STy)
      // Look at each of the original return values individually.
      for (unsigned i = 0; i != RetCount; ++i) {
        RetOrArg Ret = CreateRet(F, i);
        if (LiveValues.erase(Ret)) {
          RetTypes.push_back(STy->getElementType(i));
          NewRetIdxs[i] = RetTypes.size() - 1;
        } else {
          ++NumRetValsEliminated;
          DEBUG(dbgs() << "DAE - Removing return value " << i << " from "
                << F->getName() << "\n");
        }
      }
    else
      // We used to return a single value.
      if (LiveValues.erase(CreateRet(F, 0))) {
        RetTypes.push_back(RetTy);
        NewRetIdxs[0] = 0;
      } else {
        DEBUG(dbgs() << "DAE - Removing return value from " << F->getName()
              << "\n");
        ++NumRetValsEliminated;
      }
    if (RetTypes.size() > 1)
      // More than one return type? Return a struct with them. Also, if we used
      // to return a struct and didn't change the number of return values,
      // return a struct again. This prevents changing {something} into
      // something and {} into void.
      // Make the new struct packed if we used to return a packed struct
      // already.
      NRetTy = StructType::get(STy->getContext(), RetTypes, STy->isPacked());
    else if (RetTypes.size() == 1)
      // One return type? Just a simple value then, but only if we didn't use to
      // return a struct with that simple value before.
      NRetTy = RetTypes.front();
    else if (RetTypes.size() == 0)
      // No return types? Make it void, but only if we didn't use to return {}.
      NRetTy = Type::getVoidTy(F->getContext());
  }

  assert(NRetTy && "No new return type found?");

  // The existing function return attributes.
  AttributeSet RAttrs = PAL.getRetAttributes();

  // Remove any incompatible attributes, but only if we removed all return
  // values. Otherwise, ensure that we don't have any conflicting attributes
  // here. Currently, this should not be possible, but special handling might be
  // required when new return value attributes are added.
  if (NRetTy->isVoidTy())
    RAttrs =
      AttributeSet::get(NRetTy->getContext(), AttributeSet::ReturnIndex,
                        AttrBuilder(RAttrs, AttributeSet::ReturnIndex).
                    removeAttributes(AttributeFuncs::typeIncompatible(NRetTy)));
  else
    assert(!AttrBuilder(RAttrs, AttributeSet::ReturnIndex).
             hasAttributes(AttributeFuncs::typeIncompatible(NRetTy)) &&
           "Return attributes no longer compatible?");

  if (RAttrs.hasAttributes(AttributeSet::ReturnIndex))
    AttributesVec.push_back(AttributeWithIndex::get(NRetTy->getContext(),
                                                    AttributeSet::ReturnIndex,
                                                    RAttrs));

  // Remember which arguments are still alive.
  SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
  // Construct the new parameter list from non-dead arguments. Also construct
  // a new set of parameter attributes to correspond. Skip the first parameter
  // attribute, since that belongs to the return value.
  unsigned i = 0;
//.........这里部分代码省略.........
开发者ID:deadly-platypus,项目名称:llvm,代码行数:101,代码来源:DeadArgumentElimination.cpp

示例8: 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

示例9: 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,代码来源:

示例10: buildBitSetsFromGlobalVariables

/// Given a disjoint set of bitsets and globals, layout the globals, build the
/// bit sets and lower the llvm.bitset.test calls.
void LowerBitSets::buildBitSetsFromGlobalVariables(
    ArrayRef<Metadata *> BitSets, ArrayRef<GlobalVariable *> Globals) {
  // Build a new global with the combined contents of the referenced globals.
  // This global is a struct whose even-indexed elements contain the original
  // contents of the referenced globals and whose odd-indexed elements contain
  // any padding required to align the next element to the next power of 2.
  std::vector<Constant *> GlobalInits;
  const DataLayout &DL = M->getDataLayout();
  for (GlobalVariable *G : Globals) {
    GlobalInits.push_back(G->getInitializer());
    uint64_t InitSize = DL.getTypeAllocSize(G->getValueType());

    // Compute the amount of padding required.
    uint64_t Padding = NextPowerOf2(InitSize - 1) - InitSize;

    // Cap at 128 was found experimentally to have a good data/instruction
    // overhead tradeoff.
    if (Padding > 128)
      Padding = RoundUpToAlignment(InitSize, 128) - InitSize;

    GlobalInits.push_back(
        ConstantAggregateZero::get(ArrayType::get(Int8Ty, Padding)));
  }
  if (!GlobalInits.empty())
    GlobalInits.pop_back();
  Constant *NewInit = ConstantStruct::getAnon(M->getContext(), GlobalInits);
  auto *CombinedGlobal =
      new GlobalVariable(*M, NewInit->getType(), /*isConstant=*/true,
                         GlobalValue::PrivateLinkage, NewInit);

  StructType *NewTy = cast<StructType>(NewInit->getType());
  const StructLayout *CombinedGlobalLayout = DL.getStructLayout(NewTy);

  // Compute the offsets of the original globals within the new global.
  DenseMap<GlobalObject *, uint64_t> GlobalLayout;
  for (unsigned I = 0; I != Globals.size(); ++I)
    // Multiply by 2 to account for padding elements.
    GlobalLayout[Globals[I]] = CombinedGlobalLayout->getElementOffset(I * 2);

  lowerBitSetCalls(BitSets, CombinedGlobal, GlobalLayout);

  // Build aliases pointing to offsets into the combined global for each
  // global from which we built the combined global, and replace references
  // to the original globals with references to the aliases.
  for (unsigned I = 0; I != Globals.size(); ++I) {
    // Multiply by 2 to account for padding elements.
    Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0),
                                      ConstantInt::get(Int32Ty, I * 2)};
    Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr(
        NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs);
    if (LinkerSubsectionsViaSymbols) {
      Globals[I]->replaceAllUsesWith(CombinedGlobalElemPtr);
    } else {
      assert(Globals[I]->getType()->getAddressSpace() == 0);
      GlobalAlias *GAlias = GlobalAlias::create(NewTy->getElementType(I * 2), 0,
                                                Globals[I]->getLinkage(), "",
                                                CombinedGlobalElemPtr, M);
      GAlias->setVisibility(Globals[I]->getVisibility());
      GAlias->takeName(Globals[I]);
      Globals[I]->replaceAllUsesWith(GAlias);
    }
    Globals[I]->eraseFromParent();
  }
}
开发者ID:IanLee1521,项目名称:ares,代码行数:66,代码来源:LowerBitSets.cpp

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