Esempio n. 1
0
// maybeUpdateRTTILinkage - Will update the linkage of the RTTI data structures
// from available_externally to the correct linkage if necessary. An example of
// this is:
//
//   struct A {
//     virtual void f();
//   };
//
//   const std::type_info &g() {
//     return typeid(A);
//   }
//
//   void A::f() { }
//
// When we're generating the typeid(A) expression, we do not yet know that
// A's key function is defined in this translation unit, so we will give the
// typeinfo and typename structures available_externally linkage. When A::f
// forces the vtable to be generated, we need to change the linkage of the
// typeinfo and typename structs, otherwise we'll end up with undefined
// externals when linking.
static void 
maybeUpdateRTTILinkage(CodeGenModule &CGM, llvm::GlobalVariable *GV,
                       QualType Ty) {
  // We're only interested in globals with available_externally linkage.
  if (!GV->hasAvailableExternallyLinkage())
    return;

  // Get the real linkage for the type.
  llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty);

  // If variable is supposed to have available_externally linkage, we don't
  // need to do anything.
  if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
    return;

  // Update the typeinfo linkage.
  GV->setLinkage(Linkage);

  // Get the typename global.
  SmallString<256> OutName;
  llvm::raw_svector_ostream Out(OutName);
  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
  Out.flush();
  StringRef Name = OutName.str();

  llvm::GlobalVariable *TypeNameGV = CGM.getModule().getNamedGlobal(Name);

  assert(TypeNameGV->hasAvailableExternallyLinkage() &&
         "Type name has different linkage from type info!");

  // And update its linkage.
  TypeNameGV->setLinkage(Linkage);
}
Esempio n. 2
0
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info,
                    llvm::SmallVectorImpl<llvm::Type*> &elementTypes) {
  ASTContext &C = CGM.getContext();

  // The header is basically a 'struct { void *; int; int; void *; void *; }'.
  CharUnits ptrSize, ptrAlign, intSize, intAlign;
  llvm::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.UInt32Ty);
  llvm::tie(intSize, intAlign) = C.getTypeInfoInChars(C.Int32Ty);

  // Are there crazy embedded platforms where this isn't true?
  assert(intSize <= ptrSize && "layout assumptions horribly violated");

  CharUnits headerSize = ptrSize;
  if (2 * intSize < ptrAlign) headerSize += ptrSize;
  else headerSize += 2 * intSize;
  headerSize += 2 * ptrSize;

  info.BlockAlign = ptrAlign;
  info.BlockSize = headerSize;

  assert(elementTypes.empty());
  llvm::Type *i8p = CGM.getTypes().ConvertType(C.UInt32Ty);
  llvm::Type *intTy = CGM.getTypes().ConvertType(C.Int32Ty);
  elementTypes.push_back(i8p);
  elementTypes.push_back(intTy);
  elementTypes.push_back(intTy);
  elementTypes.push_back(i8p);
  elementTypes.push_back(CGM.getBlockDescriptorType());

  assert(elementTypes.size() == BlockHeaderSize);
}
static bool CheckElementalArguments(CodeGenModule &CGM, const FunctionDecl *FD,
                                    llvm::Function *Fn, bool &HasThis) {
  // Check the return type.
  QualType RetTy = FD->getReturnType();
  if (RetTy->isAggregateType()) {
    CGM.Error(FD->getLocation(), "the return type for this elemental "
                                 "function is not supported yet");
    return false;
  }

  // Check each parameter type.
  for (unsigned I = 0, E = FD->param_size(); I < E; ++I) {
    const ParmVarDecl *VD = FD->getParamDecl(I);
    QualType Ty = VD->getType();
    assert(!Ty->isIncompleteType() && "incomplete type");
    if (Ty->isAggregateType()) {
      CGM.Error(VD->getLocation(), "the parameter type for this elemental "
                                   "function is not supported yet");
      return false;
    }
  }

  HasThis = isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance();

  // At this point, no passing struct arguments by value.
  unsigned NumArgs = FD->param_size();
  unsigned NumLLVMArgs = Fn->arg_size();

  // There is a single implicit 'this' parameter.
  if (HasThis && (NumArgs + 1 == NumLLVMArgs))
    return true;

  return NumArgs == NumLLVMArgs;
}
Esempio n. 4
0
CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
  : CGM(CGM), ItaniumVTContext(CGM.getContext()) {
  if (CGM.getTarget().getCXXABI().isMicrosoft()) {
    // FIXME: Eventually, we should only have one of V*TContexts available.
    // Today we use both in the Microsoft ABI as MicrosoftVFTableContext
    // is not completely supported in CodeGen yet.
    MicrosoftVTContext.reset(new MicrosoftVTableContext(CGM.getContext()));
  }
}
Esempio n. 5
0
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) : CGCUDARuntime(CGM) {
  CodeGen::CodeGenTypes &Types = CGM.getTypes();
  ASTContext &Ctx = CGM.getContext();

  IntTy = Types.ConvertType(Ctx.IntTy);
  SizeTy = Types.ConvertType(Ctx.getSizeType());

  CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy));
  VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy));
}
Esempio n. 6
0
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
    : CGCUDARuntime(CGM), Context(CGM.getLLVMContext()),
      TheModule(CGM.getModule()) {
  CodeGen::CodeGenTypes &Types = CGM.getTypes();
  ASTContext &Ctx = CGM.getContext();

  IntTy = CGM.IntTy;
  SizeTy = CGM.SizeTy;
  VoidTy = CGM.VoidTy;

  CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy));
  VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy));
  VoidPtrPtrTy = VoidPtrTy->getPointerTo();
}
Esempio n. 7
0
/// Given that we're currently at the end of the translation unit, and
/// we've emitted a reference to the v-table for this class, should
/// we define that v-table?
static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
                                                   const CXXRecordDecl *RD) {
  // If we're building with optimization, we always emit v-tables
  // since that allows for virtual function calls to be devirtualized.
  // If the v-table is defined strongly elsewhere, this definition
  // will be emitted available_externally.
  //
  // However, we don't want to do this in -fapple-kext mode, because
  // kext mode does not permit devirtualization.
  if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOpts().AppleKext)
    return true;

  return !CGM.getVTables().isVTableExternal(RD);
}
Esempio n. 8
0
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
                               llvm::Function *ThunkFn, bool ForVTable,
                               GlobalDecl GD) {
  CGM.setFunctionLinkage(GD, ThunkFn);
  CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
                                  !Thunk.Return.isEmpty());

  // Set the right visibility.
  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
  setThunkVisibility(CGM, MD, Thunk, ThunkFn);

  if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
    ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
}
Esempio n. 9
0
static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM,
                                 const OMPAlignedClause &Clause) {
  unsigned ClauseAlignment = 0;
  if (auto AlignmentExpr = Clause.getAlignment()) {
    auto AlignmentCI =
        cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
    ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue());
  }
  for (auto E : Clause.varlists()) {
    unsigned Alignment = ClauseAlignment;
    if (Alignment == 0) {
      // OpenMP [2.8.1, Description]
      // If no optional parameter is specified, implementation-defined default
      // alignments for SIMD instructions on the target platforms are assumed.
      Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment(
          E->getType());
    }
    assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) &&
           "alignment is not power of 2");
    if (Alignment != 0) {
      llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
      CGF.EmitAlignmentAssumption(PtrValue, Alignment);
    }
  }
}
Esempio n. 10
0
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
                               const ThunkInfo &Thunk, llvm::Function *Fn) {
  CGM.setGlobalVisibility(Fn, MD);

  if (!CGM.getCodeGenOpts().HiddenWeakVTables)
    return;

  // If the thunk has weak/linkonce linkage, but the function must be
  // emitted in every translation unit that references it, then we can
  // emit its thunks with hidden visibility, since its thunks must be
  // emitted when the function is.

  // This follows CodeGenModule::setTypeVisibility; see the comments
  // there for explanation.

  if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage &&
       Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) ||
      Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
    return;

  if (MD->getExplicitVisibility())
    return;

  switch (MD->getTemplateSpecializationKind()) {
  case TSK_ExplicitInstantiationDefinition:
  case TSK_ExplicitInstantiationDeclaration:
    return;

  case TSK_Undeclared:
    break;

  case TSK_ExplicitSpecialization:
  case TSK_ImplicitInstantiation:
    if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables)
      return;
    break;
  }

  // If there's an explicit definition, and that definition is
  // out-of-line, then we can't assume that all users will have a
  // definition to emit.
  const FunctionDecl *Def = 0;
  if (MD->hasBody(Def) && Def->isOutOfLine())
    return;

  Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
}
Esempio n. 11
0
static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
                                  bool IsUnprototyped, bool ForVTable) {
  // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to
  // provide thunks for us.
  if (CGM.getTarget().getCXXABI().isMicrosoft())
    return true;

  // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide
  // definitions of the main method. Therefore, emitting thunks with the vtable
  // is purely an optimization. Emit the thunk if optimizations are enabled and
  // all of the parameter types are complete.
  if (ForVTable)
    return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped;

  // Always emit thunks along with the method definition.
  return true;
}
Esempio n. 12
0
/// Given that we're currently at the end of the translation unit, and
/// we've emitted a reference to the vtable for this class, should
/// we define that vtable?
static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
                                                   const CXXRecordDecl *RD) {
  // If vtable is internal then it has to be done.
  if (!CGM.getVTables().isVTableExternal(RD))
    return true;

  // If it's external then maybe we will need it as available_externally.
  return shouldEmitAvailableExternallyVTable(CGM, RD);
}
void VBTableInfo::EmitVBTableDefinition(
    CodeGenModule &CGM, const CXXRecordDecl *RD,
    llvm::GlobalVariable::LinkageTypes Linkage) const {
  assert(RD->getNumVBases() && ReusingBase->getNumVBases() &&
         "should only emit vbtables for classes with vbtables");

  const ASTRecordLayout &BaseLayout =
    CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase());
  const ASTRecordLayout &DerivedLayout =
    CGM.getContext().getASTRecordLayout(RD);

  SmallVector<llvm::Constant *, 4> Offsets;

  // The offset from ReusingBase's vbptr to itself always leads.
  CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
  Offsets.push_back(
      llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity()));

  // These are laid out in the same order as in Itanium, which is the same as
  // the order of the vbase iterator.
  for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(),
       E = ReusingBase->vbases_end(); I != E; ++I) {
    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
    CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
    assert(!Offset.isNegative());
    // Make it relative to the subobject vbptr.
    Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset;
    Offsets.push_back(llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity()));
  }

  assert(Offsets.size() ==
         cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
                               ->getElementType())->getNumElements());
  llvm::ArrayType *VBTableType =
    llvm::ArrayType::get(CGM.IntTy, Offsets.size());
  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
  GV->setInitializer(Init);

  // Set the correct linkage.
  GV->setLinkage(Linkage);

  // Set the right visibility.
  CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable);
}
CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)
  : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),
    TheDataLayout(cgm.getDataLayout()),
    Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
    CodeGenOpts(cgm.getCodeGenOpts()),
    TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) {
  SkippedLayout = false;
}
Esempio n. 15
0
CharUnits swiftcall::getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type) {
  // For Swift's purposes, this is always just the store size of the type
  // rounded up to a power of 2.
  auto size = (unsigned long long) getTypeStoreSize(CGM, type).getQuantity();
  if (!isPowerOf2(size)) {
    size = 1ULL << (llvm::findLastSet(size, llvm::ZB_Undefined) + 1);
  }
  assert(size >= CGM.getDataLayout().getABITypeAlignment(type));
  return CharUnits::fromQuantity(size);
}
Esempio n. 16
0
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
/// the given type exists somewhere else, and that we should not emit the type
/// information in this translation unit.  Assumes that it is not a
/// standard-library type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) {
  ASTContext &Context = CGM.getContext();

  // If RTTI is disabled, don't consider key functions.
  if (!Context.getLangOpts().RTTI) return false;

  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
    if (!RD->hasDefinition())
      return false;

    if (!RD->isDynamicClass())
      return false;

    return !CGM.getVTables().ShouldEmitVTableInThisTU(RD);
  }
  
  return false;
}
Esempio n. 17
0
/// getTypeInfoLinkage - Return the linkage that the type info and type info
/// name constants should have for the given type.
static llvm::GlobalVariable::LinkageTypes 
getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) {
  // Itanium C++ ABI 2.9.5p7:
  //   In addition, it and all of the intermediate abi::__pointer_type_info 
  //   structs in the chain down to the abi::__class_type_info for the
  //   incomplete class type must be prevented from resolving to the 
  //   corresponding type_info structs for the complete class type, possibly
  //   by making them local static objects. Finally, a dummy class RTTI is
  //   generated for the incomplete type that will not resolve to the final 
  //   complete class RTTI (because the latter need not exist), possibly by 
  //   making it a local static object.
  if (ContainsIncompleteClassType(Ty))
    return llvm::GlobalValue::InternalLinkage;
  
  switch (Ty->getLinkage()) {
  case NoLinkage:
  case VisibleNoLinkage:
  case InternalLinkage:
  case UniqueExternalLinkage:
    return llvm::GlobalValue::InternalLinkage;

  case ExternalLinkage:
    if (!CGM.getLangOpts().RTTI) {
      // RTTI is not enabled, which means that this type info struct is going
      // to be used for exception handling. Give it linkonce_odr linkage.
      return llvm::GlobalValue::LinkOnceODRLinkage;
    }

    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
      if (RD->hasAttr<WeakAttr>())
        return llvm::GlobalValue::WeakODRLinkage;
      if (RD->isDynamicClass())
        return CGM.getVTableLinkage(RD);
    }

    return llvm::GlobalValue::LinkOnceODRLinkage;
  }

  llvm_unreachable("Invalid linkage!");
}
Esempio n. 18
0
CodeGenTypes::CodeGenTypes(CodeGenModule &CGM)
  : Context(CGM.getContext()), Target(Context.getTargetInfo()),
    TheModule(CGM.getModule()), TheTargetData(CGM.getTargetData()),
    TheABIInfo(CGM.getTargetCodeGenInfo().getABIInfo()),
    TheCXXABI(CGM.getCXXABI()),
    CodeGenOpts(CGM.getCodeGenOpts()), CGM(CGM) {
  SkippedLayout = false;
}
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
  : BlockFunction(cgm, *this, Builder), CGM(cgm),
    Target(CGM.getContext().Target),
    Builder(cgm.getModule().getContext()),
    DebugInfo(0), IndirectBranch(0),
    SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
    CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
    ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0),
    UniqueAggrDestructorCount(0) {
  LLVMIntTy = ConvertType(getContext().IntTy);
  LLVMPointerWidth = Target.getPointerWidth(0);
  Exceptions = getContext().getLangOptions().Exceptions;
  CatchUndefined = getContext().getLangOptions().CatchUndefined;
}
Esempio n. 20
0
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
/// the given type exists somewhere else, and that we should not emit the type
/// information in this translation unit.  Assumes that it is not a
/// standard-library type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
                                            QualType Ty) {
  ASTContext &Context = CGM.getContext();

  // If RTTI is disabled, assume it might be disabled in the
  // translation unit that defines any potential key function, too.
  if (!Context.getLangOpts().RTTI) return false;

  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
    if (!RD->hasDefinition())
      return false;

    if (!RD->isDynamicClass())
      return false;

    // FIXME: this may need to be reconsidered if the key function
    // changes.
    return CGM.getVTables().isVTableExternal(RD);
  }
  
  return false;
}
Esempio n. 21
0
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
  : CodeGenTypeCache(cgm), CGM(cgm),
    Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()),
    AutoreleaseResult(false), BlockInfo(0), BlockPointer(0),
    NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1),
    ExceptionSlot(0),
    DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false),
    IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
    ClassThisDefn(0), ClassThisValue(0), ClassVTTDefn(0), ClassVTTValue(0),
    OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0),
    TrapBB(0) {

  CatchUndefined = false/*getContext().getLangOptions().CatchUndefined*/;
  CGM.getOOPABI().getMangleContext().startNewFunction();
}
Esempio n. 22
0
CGIdeasRuntime::CGIdeasRuntime(CodeGenModule& CGM)
: module_(CGM.getModule()){
  llvm::LLVMContext& C = module_.getContext();
 
  Int1Ty = llvm::IntegerType::getInt1Ty(C);
  Int8Ty = llvm::IntegerType::getInt8Ty(C);
  Int32Ty = llvm::IntegerType::getInt32Ty(C);
  Int64Ty = llvm::IntegerType::getInt64Ty(C);
  FloatTy = llvm::Type::getFloatTy(C);
  DoubleTy = llvm::Type::getDoubleTy(C);
  VoidTy = llvm::Type::getVoidTy(C);
  VoidPtrTy = PointerTy(Int8Ty);
  StringTy = PointerTy(Int8Ty);
  
  TypeVec params = {VoidPtrTy};
  QueueFuncTy = llvm::FunctionType::get(VoidTy, params, false);
}
Esempio n. 23
0
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
  : CodeGenTypeCache(cgm), CGM(cgm),
    Target(CGM.getContext().getTargetInfo()),
    Builder(cgm.getModule().getContext()),
    AutoreleaseResult(false), BlockInfo(0), BlockPointer(0),
    LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1),
    FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0),
    DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false),
    IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
    CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), CXXVTTDecl(0),
    CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0),
    TerminateHandler(0), TrapBB(0) {

  CatchUndefined = getContext().getLangOpts().CatchUndefined;
  if (!suppressNewContext)
    CGM.getCXXABI().getMangleContext().startNewFunction();
}
Esempio n. 24
0
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
    : CGCUDARuntime(CGM), Context(CGM.getLLVMContext()),
      TheModule(CGM.getModule()),
      RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode),
      DeviceMC(CGM.getContext().createMangleContext(
          CGM.getContext().getAuxTargetInfo())) {
  CodeGen::CodeGenTypes &Types = CGM.getTypes();
  ASTContext &Ctx = CGM.getContext();

  IntTy = CGM.IntTy;
  SizeTy = CGM.SizeTy;
  VoidTy = CGM.VoidTy;

  CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy));
  VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy));
  VoidPtrPtrTy = VoidPtrTy->getPointerTo();
}
Esempio n. 25
0
bool swiftcall::isLegalIntegerType(CodeGenModule &CGM,
                                   llvm::IntegerType *intTy) {
  auto size = intTy->getBitWidth();
  switch (size) {
  case 1:
  case 8:
  case 16:
  case 32:
  case 64:
    // Just assume that the above are always legal.
    return true;

  case 128:
    return CGM.getContext().getTargetInfo().hasInt128Type();

  default:
    return false;
  }
}
/// \brief Generates a properstep argument for each function parameter.
/// Returns true if this is a non-linear and non-uniform variable.
/// Otherwise returns false.
static bool handleParameter(CodeGenModule &CGM, CilkElementalGroup &G,
                            StringRef ParmName,
                            SmallVectorImpl<llvm::Metadata *> &StepArgs,
                            SmallVectorImpl<llvm::Metadata *> &AligArgs) {
  // Update the alignment args.
  unsigned Alignment;
  if (G.getAlignedAttr(ParmName, &Alignment)) {
    AligArgs.push_back(llvm::ConstantAsMetadata::get(
      llvm::ConstantInt::get(CGM.IntTy, Alignment)));
  }
  else {
    AligArgs.push_back(llvm::ConstantAsMetadata::get(
      llvm::UndefValue::get(CGM.IntTy)));
  }
  // Update the step args.
  std::pair<int,std::string> LinStep;
  if (G.getUniformAttr(ParmName)) {
    // If this is uniform, then use step 0 as placeholder.
    StepArgs.push_back(llvm::ConstantAsMetadata::get(
      llvm::ConstantInt::get(CGM.IntTy, 0)));
    return false;
  }
  else if (G.getLinearAttr(ParmName, &LinStep)) {
    if (LinStep.first != 0) {
      StepArgs.push_back(llvm::ConstantAsMetadata::get(
        llvm::ConstantInt::get(CGM.IntTy, LinStep.first)));
    }
    else {
      StepArgs.push_back(llvm::MDString::get(CGM.getLLVMContext(),
                                             LinStep.second));
    }
    return false;
  }
  // If this is non-linear and non-uniform, use undefined step as placeholder.
  StepArgs.push_back(llvm::ConstantAsMetadata::get(
    llvm::UndefValue::get(CGM.IntTy)));
  return true;
}
Esempio n. 27
0
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
  : BlockFunction(cgm, *this, Builder), CGM(cgm),
    Target(CGM.getContext().Target),
    Builder(cgm.getModule().getContext()),
    NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1),
    ExceptionSlot(0), DebugInfo(0), IndirectBranch(0),
    SwitchInsn(0), CaseRangeBlock(0),
    DidCallStackSave(false), UnreachableBlock(0),
    CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
    ConditionalBranchLevel(0), TerminateLandingPad(0), TerminateHandler(0),
    TrapBB(0) {
      
  // Get some frequently used types.
  LLVMPointerWidth = Target.getPointerWidth(0);
  llvm::LLVMContext &LLVMContext = CGM.getLLVMContext();
  IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth);
  Int32Ty  = llvm::Type::getInt32Ty(LLVMContext);
  Int64Ty  = llvm::Type::getInt64Ty(LLVMContext);
      
  Exceptions = getContext().getLangOptions().Exceptions;
  CatchUndefined = getContext().getLangOptions().CatchUndefined;
  CGM.getCXXABI().getMangleContext().startNewFunction();
}
Esempio n. 28
0
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
                               llvm::Function *ThunkFn, bool ForVTable,
                               GlobalDecl GD) {
  CGM.setFunctionLinkage(GD, ThunkFn);
  CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
                                  !Thunk.Return.isEmpty());

  // Set the right visibility.
  CGM.setGVProperties(ThunkFn, GD);

  if (!CGM.getCXXABI().exportThunk()) {
    ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
    ThunkFn->setDSOLocal(true);
  }

  if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
    ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
}
Esempio n. 29
0
static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
                                                const CXXRecordDecl *RD) {
  return CGM.getCodeGenOpts().OptimizationLevel > 0 &&
         CGM.getCXXABI().canSpeculativelyEmitVTable(RD);
}
Esempio n. 30
0
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
                               const ThunkInfo &Thunk, llvm::Function *Fn) {
  CGM.setGlobalVisibility(Fn, MD);
}