aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp185
1 files changed, 150 insertions, 35 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 5012bd822bd3..8cbe2a540744 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -16,6 +16,7 @@
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGDebugInfo.h"
+#include "CGHLSLRuntime.h"
#include "CGOpenMPRuntime.h"
#include "CodeGenModule.h"
#include "CodeGenPGO.h"
@@ -45,6 +46,7 @@
#include "llvm/Support/CRC.h"
#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
+#include <optional>
using namespace clang;
using namespace CodeGen;
@@ -172,10 +174,11 @@ void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) {
mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs());
mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs());
mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
- mergeFnAttrValue("unsafe-fp-math", FPFeatures.getAllowFPReassociate() &&
- FPFeatures.getAllowReciprocal() &&
- FPFeatures.getAllowApproxFunc() &&
- FPFeatures.getNoSignedZero());
+ mergeFnAttrValue(
+ "unsafe-fp-math",
+ FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
+ FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
+ FPFeatures.allowFPContractAcrossStatement());
}
CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
@@ -317,8 +320,10 @@ llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) {
if (!BB) return;
- if (!BB->use_empty())
- return CGF.CurFn->getBasicBlockList().push_back(BB);
+ if (!BB->use_empty()) {
+ CGF.CurFn->insert(CGF.CurFn->end(), BB);
+ return;
+ }
delete BB;
}
@@ -356,17 +361,18 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
bool HasOnlyLifetimeMarkers =
HasCleanups && EHStack.containsOnlyLifetimeMarkers(PrologueCleanupDepth);
bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
+
+ std::optional<ApplyDebugLocation> OAL;
if (HasCleanups) {
// Make sure the line table doesn't jump back into the body for
// the ret after it's been at EndLoc.
- Optional<ApplyDebugLocation> AL;
if (CGDebugInfo *DI = getDebugInfo()) {
if (OnlySimpleReturnStmts)
DI->EmitLocation(Builder, EndLoc);
else
// We may not have a valid end location. Try to apply it anyway, and
// fall back to an artificial location if needed.
- AL = ApplyDebugLocation::CreateDefaultArtificial(*this, EndLoc);
+ OAL = ApplyDebugLocation::CreateDefaultArtificial(*this, EndLoc);
}
PopCleanupBlocks(PrologueCleanupDepth);
@@ -477,13 +483,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
if (auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
LargestVectorWidth =
std::max((uint64_t)LargestVectorWidth,
- VT->getPrimitiveSizeInBits().getKnownMinSize());
+ VT->getPrimitiveSizeInBits().getKnownMinValue());
// Update vector width based on return type.
if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType()))
LargestVectorWidth =
std::max((uint64_t)LargestVectorWidth,
- VT->getPrimitiveSizeInBits().getKnownMinSize());
+ VT->getPrimitiveSizeInBits().getKnownMinValue());
if (CurFnInfo->getMaxVectorWidth() > LargestVectorWidth)
LargestVectorWidth = CurFnInfo->getMaxVectorWidth();
@@ -495,10 +501,12 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// 4. Width of vector arguments and return types for this function.
// 5. Width of vector aguments and return types for functions called by this
// function.
- CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth));
+ if (getContext().getTargetInfo().getTriple().isX86())
+ CurFn->addFnAttr("min-legal-vector-width",
+ llvm::utostr(LargestVectorWidth));
// Add vscale_range attribute if appropriate.
- Optional<std::pair<unsigned, unsigned>> VScaleRange =
+ std::optional<std::pair<unsigned, unsigned>> VScaleRange =
getContext().getTargetInfo().getVScaleRange(getLangOpts());
if (VScaleRange) {
CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
@@ -699,7 +707,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
CurCodeDecl = D;
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
if (FD && FD->usesSEHTry())
- CurSEHParent = FD;
+ CurSEHParent = GD;
CurFuncDecl = (D ? D->getNonClosureContext() : nullptr);
FnRetTy = RetTy;
CurFn = Fn;
@@ -724,7 +732,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
const bool SanitizeBounds = SanOpts.hasOneOf(SanitizerKind::Bounds);
bool NoSanitizeCoverage = false;
- for (auto Attr : D->specific_attrs<NoSanitizeAttr>()) {
+ for (auto *Attr : D->specific_attrs<NoSanitizeAttr>()) {
// Apply the no_sanitize* attributes to SanOpts.
SanitizerMask mask = Attr->getMask();
SanOpts.Mask &= ~mask;
@@ -842,8 +850,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups;
if (FuncGroups > 1) {
- auto FuncName = llvm::makeArrayRef<uint8_t>(
- CurFn->getName().bytes_begin(), CurFn->getName().bytes_end());
+ auto FuncName = llvm::ArrayRef<uint8_t>(CurFn->getName().bytes_begin(),
+ CurFn->getName().bytes_end());
auto Group = crc32(FuncName) % FuncGroups;
if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
!AlwaysXRayAttr)
@@ -851,9 +859,18 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
}
}
- if (CGM.getCodeGenOpts().getProfileInstr() != CodeGenOptions::ProfileNone)
- if (CGM.isFunctionBlockedFromProfileInstr(Fn, Loc))
+ if (CGM.getCodeGenOpts().getProfileInstr() != CodeGenOptions::ProfileNone) {
+ switch (CGM.isFunctionBlockedFromProfileInstr(Fn, Loc)) {
+ case ProfileList::Skip:
+ Fn->addFnAttr(llvm::Attribute::SkipProfile);
+ break;
+ case ProfileList::Forbid:
Fn->addFnAttr(llvm::Attribute::NoProfile);
+ break;
+ case ProfileList::Allow:
+ break;
+ }
+ }
unsigned Count, Offset;
if (const auto *Attr =
@@ -874,7 +891,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// backends as they don't need it -- instructions on these architectures are
// always atomically patchable at runtime.
if (CGM.getCodeGenOpts().HotPatch &&
- getContext().getTargetInfo().getTriple().isX86())
+ getContext().getTargetInfo().getTriple().isX86() &&
+ getContext().getTargetInfo().getTriple().getEnvironment() !=
+ llvm::Triple::CODE16)
Fn->addFnAttr("patchable-function", "prologue-short-redirect");
// Add no-jump-tables value.
@@ -941,7 +960,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// If we're checking nullability, we need to know whether we can check the
// return value. Initialize the flag to 'true' and refine it in EmitParmDecl.
if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
- auto Nullability = FnRetTy->getNullability(getContext());
+ auto Nullability = FnRetTy->getNullability();
if (Nullability && *Nullability == NullabilityKind::NonNull) {
if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>()))
@@ -1128,6 +1147,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (getLangOpts().OpenMP && CurCodeDecl)
CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl);
+ // Handle emitting HLSL entry functions.
+ if (D && D->hasAttr<HLSLShaderAttr>())
+ CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
+
EmitFunctionProlog(*CurFnInfo, CurFn, Args);
if (isa_and_nonnull<CXXMethodDecl>(D) &&
@@ -1450,7 +1473,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
llvm::Value *IsFalse = Builder.getFalse();
EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
SanitizerHandler::MissingReturn,
- EmitCheckSourceLocation(FD->getLocation()), None);
+ EmitCheckSourceLocation(FD->getLocation()), std::nullopt);
} else if (ShouldEmitUnreachable) {
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
EmitTrapCall(llvm::Intrinsic::trap);
@@ -2214,7 +2237,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::ConstantMatrix:
case Type::Record:
case Type::Enum:
- case Type::Elaborated:
case Type::Using:
case Type::TemplateSpecialization:
case Type::ObjCTypeParam:
@@ -2224,6 +2246,10 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::BitInt:
llvm_unreachable("type class is never variably-modified!");
+ case Type::Elaborated:
+ type = cast<ElaboratedType>(ty)->getNamedType();
+ break;
+
case Type::Adjusted:
type = cast<AdjustedType>(ty)->getAdjustedType();
break;
@@ -2426,8 +2452,6 @@ void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue,
SourceLocation AssumptionLoc,
llvm::Value *Alignment,
llvm::Value *OffsetValue) {
- if (auto *CE = dyn_cast<CastExpr>(E))
- E = CE->getSubExprAsWritten();
QualType Ty = E->getType();
SourceLocation Loc = E->getExprLoc();
@@ -2442,8 +2466,10 @@ llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Function *AnnotationFn,
const AnnotateAttr *Attr) {
SmallVector<llvm::Value *, 5> Args = {
AnnotatedVal,
- Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy),
- Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy),
+ Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr),
+ ConstGlobalsPtrTy),
+ Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location),
+ ConstGlobalsPtrTy),
CGM.EmitAnnotationLineNo(Location),
};
if (Attr)
@@ -2455,9 +2481,12 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) {
assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
// FIXME We create a new bitcast for every annotation because that's what
// llvm-gcc was doing.
+ unsigned AS = V->getType()->getPointerAddressSpace();
+ llvm::Type *I8PtrTy = Builder.getInt8PtrTy(AS);
for (const auto *I : D->specific_attrs<AnnotateAttr>())
- EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation),
- Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()),
+ EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation,
+ {I8PtrTy, CGM.ConstGlobalsPtrTy}),
+ Builder.CreateBitCast(V, I8PtrTy, V->getName()),
I->getAnnotation(), D->getLocation(), I);
}
@@ -2470,8 +2499,8 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
unsigned AS = PTy ? PTy->getAddressSpace() : 0;
llvm::PointerType *IntrinTy =
llvm::PointerType::getWithSamePointeeType(CGM.Int8PtrTy, AS);
- llvm::Function *F =
- CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, IntrinTy);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
+ {IntrinTy, CGM.ConstGlobalsPtrTy});
for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
// FIXME Always emit the cast inst so we can differentiate between
@@ -2594,8 +2623,30 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {
CGM.getSanStats().create(IRB, SSK);
}
-llvm::Value *
-CodeGenFunction::FormResolverCondition(const MultiVersionResolverOption &RO) {
+void CodeGenFunction::EmitKCFIOperandBundle(
+ const CGCallee &Callee, SmallVectorImpl<llvm::OperandBundleDef> &Bundles) {
+ const FunctionProtoType *FP =
+ Callee.getAbstractInfo().getCalleeFunctionProtoType();
+ if (FP)
+ Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar()));
+}
+
+llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
+ const MultiVersionResolverOption &RO) {
+ llvm::SmallVector<StringRef, 8> CondFeatures;
+ for (const StringRef &Feature : RO.Conditions.Features) {
+ // Form condition for features which are not yet enabled in target
+ if (!getContext().getTargetInfo().hasFeature(Feature))
+ CondFeatures.push_back(Feature);
+ }
+ if (!CondFeatures.empty()) {
+ return EmitAArch64CpuSupports(CondFeatures);
+ }
+ return nullptr;
+}
+
+llvm::Value *CodeGenFunction::FormX86ResolverCondition(
+ const MultiVersionResolverOption &RO) {
llvm::Value *Condition = nullptr;
if (!RO.Conditions.Architecture.empty())
@@ -2633,8 +2684,72 @@ static void CreateMultiVersionResolverReturn(CodeGenModule &CGM,
void CodeGenFunction::EmitMultiVersionResolver(
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
- assert(getContext().getTargetInfo().getTriple().isX86() &&
- "Only implemented for x86 targets");
+
+ llvm::Triple::ArchType ArchType =
+ getContext().getTargetInfo().getTriple().getArch();
+
+ switch (ArchType) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ EmitX86MultiVersionResolver(Resolver, Options);
+ return;
+ case llvm::Triple::aarch64:
+ EmitAArch64MultiVersionResolver(Resolver, Options);
+ return;
+
+ default:
+ assert(false && "Only implemented for x86 and AArch64 targets");
+ }
+}
+
+void CodeGenFunction::EmitAArch64MultiVersionResolver(
+ llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
+ assert(!Options.empty() && "No multiversion resolver options found");
+ assert(Options.back().Conditions.Features.size() == 0 &&
+ "Default case must be last");
+ bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
+ assert(SupportsIFunc &&
+ "Multiversion resolver requires target IFUNC support");
+ bool AArch64CpuInitialized = false;
+ llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
+
+ for (const MultiVersionResolverOption &RO : Options) {
+ Builder.SetInsertPoint(CurBlock);
+ llvm::Value *Condition = FormAArch64ResolverCondition(RO);
+
+ // The 'default' or 'all features enabled' case.
+ if (!Condition) {
+ CreateMultiVersionResolverReturn(CGM, Resolver, Builder, RO.Function,
+ SupportsIFunc);
+ return;
+ }
+
+ if (!AArch64CpuInitialized) {
+ Builder.SetInsertPoint(CurBlock, CurBlock->begin());
+ EmitAArch64CpuInit();
+ AArch64CpuInitialized = true;
+ Builder.SetInsertPoint(CurBlock);
+ }
+
+ llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
+ CGBuilderTy RetBuilder(*this, RetBlock);
+ CreateMultiVersionResolverReturn(CGM, Resolver, RetBuilder, RO.Function,
+ SupportsIFunc);
+ CurBlock = createBasicBlock("resolver_else", Resolver);
+ Builder.CreateCondBr(Condition, RetBlock, CurBlock);
+ }
+
+ // If no default, emit an unreachable.
+ Builder.SetInsertPoint(CurBlock);
+ llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
+ TrapCall->setDoesNotReturn();
+ TrapCall->setDoesNotThrow();
+ Builder.CreateUnreachable();
+ Builder.ClearInsertionPoint();
+}
+
+void CodeGenFunction::EmitX86MultiVersionResolver(
+ llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
@@ -2645,7 +2760,7 @@ void CodeGenFunction::EmitMultiVersionResolver(
for (const MultiVersionResolverOption &RO : Options) {
Builder.SetInsertPoint(CurBlock);
- llvm::Value *Condition = FormResolverCondition(RO);
+ llvm::Value *Condition = FormX86ResolverCondition(RO);
// The 'default' or 'generic' case.
if (!Condition) {