diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp | 252 | 
1 files changed, 202 insertions, 50 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp index 664b51078424..3c582688e91e 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp @@ -65,25 +65,9 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)      : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),        Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),                CGBuilderInserterTy(this)), -      CurFn(nullptr), ReturnValue(Address::invalid()), -      CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize), -      IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false), -      SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr), -      BlockPointer(nullptr), LambdaThisCaptureField(nullptr), -      NormalCleanupDest(nullptr), NextCleanupDestIndex(1), -      FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr), -      EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()), -      DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr), -      PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr), -      CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0), -      NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr), -      CXXABIThisValue(nullptr), CXXThisValue(nullptr), -      CXXStructorImplicitParamDecl(nullptr), -      CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr), -      CurLexicalScope(nullptr), TerminateLandingPad(nullptr), -      TerminateHandler(nullptr), TrapBB(nullptr), -      ShouldEmitLifetimeMarkers( -          shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) { +      SanOpts(CGM.getLangOpts().Sanitize), DebugInfo(CGM.getModuleDebugInfo()), +      PGO(cgm), ShouldEmitLifetimeMarkers(shouldEmitLifetimeMarkers( +                    CGM.getCodeGenOpts(), CGM.getLangOpts())) {    if (!suppressNewContext)      CGM.getCXXABI().getMangleContext().startNewFunction(); @@ -439,11 +423,17 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {    // if compiled with no optimizations. We do it for coroutine as the lifetime    // of CleanupDestSlot alloca make correct coroutine frame building very    // difficult. -  if (NormalCleanupDest && isCoroutine()) { +  if (NormalCleanupDest.isValid() && isCoroutine()) {      llvm::DominatorTree DT(*CurFn); -    llvm::PromoteMemToReg(NormalCleanupDest, DT); -    NormalCleanupDest = nullptr; +    llvm::PromoteMemToReg( +        cast<llvm::AllocaInst>(NormalCleanupDest.getPointer()), DT); +    NormalCleanupDest = Address::invalid();    } + +  // Add the required-vector-width attribute. +  if (LargestVectorWidth != 0) +    CurFn->addFnAttr("min-legal-vector-width", +                     llvm::utostr(LargestVectorWidth));  }  /// ShouldInstrumentFunction - Return true if the current function should be @@ -465,9 +455,19 @@ bool CodeGenFunction::ShouldXRayInstrumentFunction() const {  }  /// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to -/// the __xray_customevent(...) builin calls, when doing XRay instrumentation. +/// the __xray_customevent(...) builtin calls, when doing XRay instrumentation.  bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const { -  return CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents; +  return CGM.getCodeGenOpts().XRayInstrumentFunctions && +         (CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents || +          CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask == +              XRayInstrKind::Custom); +} + +bool CodeGenFunction::AlwaysEmitXRayTypedEvents() const { +  return CGM.getCodeGenOpts().XRayInstrumentFunctions && +         (CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents || +          CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask == +              XRayInstrKind::Typed);  }  llvm::Constant * @@ -845,14 +845,24 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,    if (D) {      // Apply the no_sanitize* attributes to SanOpts. -    for (auto Attr : D->specific_attrs<NoSanitizeAttr>()) -      SanOpts.Mask &= ~Attr->getMask(); +    for (auto Attr : D->specific_attrs<NoSanitizeAttr>()) { +      SanitizerMask mask = Attr->getMask(); +      SanOpts.Mask &= ~mask; +      if (mask & SanitizerKind::Address) +        SanOpts.set(SanitizerKind::KernelAddress, false); +      if (mask & SanitizerKind::KernelAddress) +        SanOpts.set(SanitizerKind::Address, false); +      if (mask & SanitizerKind::HWAddress) +        SanOpts.set(SanitizerKind::KernelHWAddress, false); +      if (mask & SanitizerKind::KernelHWAddress) +        SanOpts.set(SanitizerKind::HWAddress, false); +    }    }    // Apply sanitizer attributes to the function.    if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))      Fn->addFnAttr(llvm::Attribute::SanitizeAddress); -  if (SanOpts.hasOneOf(SanitizerKind::HWAddress)) +  if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress))      Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);    if (SanOpts.has(SanitizerKind::Thread))      Fn->addFnAttr(llvm::Attribute::SanitizeThread); @@ -860,6 +870,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,      Fn->addFnAttr(llvm::Attribute::SanitizeMemory);    if (SanOpts.has(SanitizerKind::SafeStack))      Fn->addFnAttr(llvm::Attribute::SafeStack); +  if (SanOpts.has(SanitizerKind::ShadowCallStack)) +    Fn->addFnAttr(llvm::Attribute::ShadowCallStack); + +  // Apply fuzzing attribute to the function. +  if (SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink)) +    Fn->addFnAttr(llvm::Attribute::OptForFuzzing);    // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,    // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time. @@ -887,7 +903,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,    }    // Apply xray attributes to the function (as a string, for now) -  if (D && ShouldXRayInstrumentFunction()) { +  bool InstrumentXray = ShouldXRayInstrumentFunction() && +                        CGM.getCodeGenOpts().XRayInstrumentationBundle.has( +                            XRayInstrKind::Function); +  if (D && InstrumentXray) {      if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {        if (XRayAttr->alwaysXRayInstrument())          Fn->addFnAttr("function-instrument", "xray-always"); @@ -924,8 +943,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,    if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {      if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {        if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) { +        // Remove any (C++17) exception specifications, to allow calling e.g. a +        // noexcept function through a non-noexcept pointer. +        auto ProtoTy = +          getContext().getFunctionTypeWithExceptionSpec(FD->getType(), +                                                        EST_None);          llvm::Constant *FTRTTIConst = -            CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true); +            CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true);          llvm::Constant *FTRTTIConstEncoded =              EncodeAddrForUseInPrologue(Fn, FTRTTIConst);          llvm::Constant *PrologueStructElems[] = {PrologueSig, @@ -990,7 +1014,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,        ArgTypes.push_back(VD->getType());      QualType FnType = getContext().getFunctionType(          RetTy, ArgTypes, FunctionProtoType::ExtProtoInfo(CC)); -    DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, Builder); +    DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, CurFuncIsThunk, +                          Builder);    }    if (ShouldInstrumentFunction()) { @@ -1009,10 +1034,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,    // The attribute "counting-function" is set to mcount function name which is    // architecture dependent.    if (CGM.getCodeGenOpts().InstrumentForProfiling) { -    if (CGM.getCodeGenOpts().CallFEntry) -      Fn->addFnAttr("fentry-call", "true"); -    else { -      if (!CurFuncDecl || !CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) { +    // Calls to fentry/mcount should not be generated if function has +    // the no_instrument_function attribute. +    if (!CurFuncDecl || !CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) { +      if (CGM.getCodeGenOpts().CallFEntry) +        Fn->addFnAttr("fentry-call", "true"); +      else {          Fn->addFnAttr("instrument-function-entry-inlined",                        getTarget().getMCountName());        } @@ -1058,6 +1085,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,    EmitStartEHSpec(CurCodeDecl);    PrologueCleanupDepth = EHStack.stable_begin(); + +  // Emit OpenMP specific initialization of the device functions. +  if (getLangOpts().OpenMP && CurCodeDecl) +    CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl); +    EmitFunctionProlog(*CurFnInfo, CurFn, Args);    if (D && isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) { @@ -1111,8 +1143,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,        // may have a static invoker function, which may call this operator with        // a null 'this' pointer.        if (isLambdaCallOperator(MD) && -          cast<CXXRecordDecl>(MD->getParent())->getLambdaCaptureDefault() == -              LCD_None) +          MD->getParent()->getLambdaCaptureDefault() == LCD_None)          SkippedChecks.set(SanitizerKind::Null, true);        EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall @@ -1144,6 +1175,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,    // Emit a location at the end of the prologue.    if (CGDebugInfo *DI = getDebugInfo())      DI->EmitLocation(Builder, StartLoc); + +  // TODO: Do we need to handle this in two places like we do with +  // target-features/target-cpu? +  if (CurFuncDecl) +    if (const auto *VecWidth = CurFuncDecl->getAttr<MinVectorWidthAttr>()) +      LargestVectorWidth = VecWidth->getVectorWidth();  }  void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args, @@ -1751,12 +1788,9 @@ CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) {      if (const VariableArrayType *vlaType =            dyn_cast_or_null<VariableArrayType>(                                            getContext().getAsArrayType(Ty))) { -      QualType eltType; -      llvm::Value *numElts; -      std::tie(numElts, eltType) = getVLASize(vlaType); - -      SizeVal = numElts; -      CharUnits eltSize = getContext().getTypeSizeInChars(eltType); +      auto VlaSize = getVLASize(vlaType); +      SizeVal = VlaSize.NumElts; +      CharUnits eltSize = getContext().getTypeSizeInChars(VlaSize.Type);        if (!eltSize.isOne())          SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(eltSize));        vla = vlaType; @@ -1839,7 +1873,7 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,    // this is the size of the VLA in bytes, not its size in elements.    llvm::Value *numVLAElements = nullptr;    if (isa<VariableArrayType>(arrayType)) { -    numVLAElements = getVLASize(cast<VariableArrayType>(arrayType)).first; +    numVLAElements = getVLASize(cast<VariableArrayType>(arrayType)).NumElts;      // Walk into all VLAs.  This doesn't require changes to addr,      // which has type T* where T is the first non-VLA element type. @@ -1920,14 +1954,13 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,    return numElements;  } -std::pair<llvm::Value*, QualType> -CodeGenFunction::getVLASize(QualType type) { +CodeGenFunction::VlaSizePair CodeGenFunction::getVLASize(QualType type) {    const VariableArrayType *vla = getContext().getAsVariableArrayType(type);    assert(vla && "type was not a variable array type!");    return getVLASize(vla);  } -std::pair<llvm::Value*, QualType> +CodeGenFunction::VlaSizePair  CodeGenFunction::getVLASize(const VariableArrayType *type) {    // The number of elements so far; always size_t.    llvm::Value *numElements = nullptr; @@ -1948,7 +1981,22 @@ CodeGenFunction::getVLASize(const VariableArrayType *type) {      }    } while ((type = getContext().getAsVariableArrayType(elementType))); -  return std::pair<llvm::Value*,QualType>(numElements, elementType); +  return { numElements, elementType }; +} + +CodeGenFunction::VlaSizePair +CodeGenFunction::getVLAElements1D(QualType type) { +  const VariableArrayType *vla = getContext().getAsVariableArrayType(type); +  assert(vla && "type was not a variable array type!"); +  return getVLAElements1D(vla); +} + +CodeGenFunction::VlaSizePair +CodeGenFunction::getVLAElements1D(const VariableArrayType *Vla) { +  llvm::Value *VlaSize = VLASizeMap[Vla->getSizeExpr()]; +  assert(VlaSize && "no size for VLA!"); +  assert(VlaSize->getType() == SizeTy); +  return { VlaSize, Vla->getElementType() };  }  void CodeGenFunction::EmitVariablyModifiedType(QualType type) { @@ -2231,7 +2279,7 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures,    return std::all_of(        ReqFeatures.begin(), ReqFeatures.end(), [&](StringRef Feature) {          SmallVector<StringRef, 1> OrFeatures; -        Feature.split(OrFeatures, "|"); +        Feature.split(OrFeatures, '|');          return std::any_of(OrFeatures.begin(), OrFeatures.end(),                             [&](StringRef Feature) {                               if (!CallerFeatureMap.lookup(Feature)) { @@ -2269,17 +2317,28 @@ void CodeGenFunction::checkTargetFeatures(const CallExpr *E,      // Return if the builtin doesn't have any required features.      if (!FeatureList || StringRef(FeatureList) == "")        return; -    StringRef(FeatureList).split(ReqFeatures, ","); +    StringRef(FeatureList).split(ReqFeatures, ',');      if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature))        CGM.getDiags().Report(E->getLocStart(), diag::err_builtin_needs_feature)            << TargetDecl->getDeclName()            << CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID); -  } else if (TargetDecl->hasAttr<TargetAttr>()) { +  } else if (TargetDecl->hasAttr<TargetAttr>() || +             TargetDecl->hasAttr<CPUSpecificAttr>()) {      // Get the required features for the callee. + +    const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>(); +    TargetAttr::ParsedTargetAttr ParsedAttr = CGM.filterFunctionTargetAttrs(TD); +      SmallVector<StringRef, 1> ReqFeatures;      llvm::StringMap<bool> CalleeFeatureMap;      CGM.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl); + +    for (const auto &F : ParsedAttr.Features) { +      if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1))) +        ReqFeatures.push_back(StringRef(F).substr(1)); +    } +      for (const auto &F : CalleeFeatureMap) {        // Only positive features are "required".        if (F.getValue()) @@ -2300,6 +2359,99 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {    CGM.getSanStats().create(IRB, SSK);  } +llvm::Value *CodeGenFunction::FormResolverCondition( +    const TargetMultiVersionResolverOption &RO) { +  llvm::Value *TrueCondition = nullptr; +  if (!RO.ParsedAttribute.Architecture.empty()) +    TrueCondition = EmitX86CpuIs(RO.ParsedAttribute.Architecture); + +  if (!RO.ParsedAttribute.Features.empty()) { +    SmallVector<StringRef, 8> FeatureList; +    llvm::for_each(RO.ParsedAttribute.Features, +                   [&FeatureList](const std::string &Feature) { +                     FeatureList.push_back(StringRef{Feature}.substr(1)); +                   }); +    llvm::Value *FeatureCmp = EmitX86CpuSupports(FeatureList); +    TrueCondition = TrueCondition ? Builder.CreateAnd(TrueCondition, FeatureCmp) +                                  : FeatureCmp; +  } +  return TrueCondition; +} + +void CodeGenFunction::EmitTargetMultiVersionResolver( +    llvm::Function *Resolver, +    ArrayRef<TargetMultiVersionResolverOption> Options) { +  assert((getContext().getTargetInfo().getTriple().getArch() == +              llvm::Triple::x86 || +          getContext().getTargetInfo().getTriple().getArch() == +              llvm::Triple::x86_64) && +         "Only implemented for x86 targets"); + +  // Main function's basic block. +  llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver); +  Builder.SetInsertPoint(CurBlock); +  EmitX86CpuInit(); + +  llvm::Function *DefaultFunc = nullptr; +  for (const TargetMultiVersionResolverOption &RO : Options) { +    Builder.SetInsertPoint(CurBlock); +    llvm::Value *TrueCondition = FormResolverCondition(RO); + +    if (!TrueCondition) { +      DefaultFunc = RO.Function; +    } else { +      llvm::BasicBlock *RetBlock = createBasicBlock("ro_ret", Resolver); +      llvm::IRBuilder<> RetBuilder(RetBlock); +      RetBuilder.CreateRet(RO.Function); +      CurBlock = createBasicBlock("ro_else", Resolver); +      Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock); +    } +  } + +  assert(DefaultFunc && "No default version?"); +  // Emit return from the 'else-ist' block. +  Builder.SetInsertPoint(CurBlock); +  Builder.CreateRet(DefaultFunc); +} + +void CodeGenFunction::EmitCPUDispatchMultiVersionResolver( +    llvm::Function *Resolver, +    ArrayRef<CPUDispatchMultiVersionResolverOption> Options) { +  assert((getContext().getTargetInfo().getTriple().getArch() == +              llvm::Triple::x86 || +          getContext().getTargetInfo().getTriple().getArch() == +              llvm::Triple::x86_64) && +         "Only implemented for x86 targets"); + +  // Main function's basic block. +  llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver); +  Builder.SetInsertPoint(CurBlock); +  EmitX86CpuInit(); + +  for (const CPUDispatchMultiVersionResolverOption &RO : Options) { +    Builder.SetInsertPoint(CurBlock); + +    // "generic" case should catch-all. +    if (RO.FeatureMask == 0) { +      Builder.CreateRet(RO.Function); +      return; +    } +    llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver); +    llvm::IRBuilder<> RetBuilder(RetBlock); +    RetBuilder.CreateRet(RO.Function); +    CurBlock = createBasicBlock("resolver_else", Resolver); +    llvm::Value *TrueCondition = EmitX86CpuSupports(RO.FeatureMask); +    Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock); +  } + +  Builder.SetInsertPoint(CurBlock); +  llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); +  TrapCall->setDoesNotReturn(); +  TrapCall->setDoesNotThrow(); +  Builder.CreateUnreachable(); +  Builder.ClearInsertionPoint(); +} +  llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) {    if (CGDebugInfo *DI = getDebugInfo())      return DI->SourceLocToDebugLoc(Location);  | 
