diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 72 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp | 29 | ||||
-rw-r--r-- | clang/lib/CodeGen/Targets/AMDGPU.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/Targets/SPIR.cpp | 2 |
7 files changed, 107 insertions, 31 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6020684..ecfbcb5 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -430,12 +430,6 @@ static bool initTargetOptions(const CompilerInstance &CI, Options.NoInfsFPMath = LangOpts.NoHonorInfs; Options.NoNaNsFPMath = LangOpts.NoHonorNaNs; Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; - Options.UnsafeFPMath = LangOpts.AllowFPReassoc && LangOpts.AllowRecip && - LangOpts.NoSignedZero && LangOpts.ApproxFunc && - (LangOpts.getDefaultFPContractMode() == - LangOptions::FPModeKind::FPM_Fast || - LangOpts.getDefaultFPContractMode() == - LangOptions::FPModeKind::FPM_FastHonorPragmas); Options.BBAddrMap = CodeGenOpts.BBAddrMap; Options.BBSections = diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 741fa44..465f3f4 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5937,8 +5937,24 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, CI->getCalledFunction()->getName().starts_with("_Z4sqrt")) { SetSqrtFPAccuracy(CI); } - if (callOrInvoke) + if (callOrInvoke) { *callOrInvoke = CI; + if (CGM.getCodeGenOpts().CallGraphSection) { + QualType CST; + if (TargetDecl && TargetDecl->getFunctionType()) + CST = QualType(TargetDecl->getFunctionType(), 0); + else if (const auto *FPT = + Callee.getAbstractInfo().getCalleeFunctionProtoType()) + CST = QualType(FPT, 0); + else + llvm_unreachable( + "Cannot find the callee type to generate callee_type metadata."); + + // Set type identifier metadata of indirect calls for call graph section. + if (!CST.isNull()) + CGM.createCalleeTypeMetadataForIcall(CST, *callOrInvoke); + } + } // If this is within a function that has the guard(nocf) attribute and is an // indirect call, add the "guard_nocf" attribute to this call to indicate that diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1085f45..3746bc04 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1325,22 +1325,29 @@ void CodeGenModule::Release() { "tag-stack-memory-buildattr", 1); if (T.isARM() || T.isThumb() || T.isAArch64()) { + // Previously 1 is used and meant for the backed to derive the function + // attribute form it. 2 now means function attributes already set for all + // functions in this module, so no need to propagate those from the module + // flag. Value is only used in case of LTO module merge because the backend + // will see all required function attribute set already. Value is used + // before modules got merged. Any posive value means the feature is active + // and required binary markings need to be emit accordingly. if (LangOpts.BranchTargetEnforcement) getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement", - 1); + 2); if (LangOpts.BranchProtectionPAuthLR) getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", - 1); + 2); if (LangOpts.GuardedControlStack) - getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1); + getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 2); if (LangOpts.hasSignReturnAddress()) - getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1); + getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 2); if (LangOpts.isSignReturnAddressScopeAll()) getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all", - 1); + 2); if (!LangOpts.isSignReturnAddressWithAKey()) getModule().addModuleFlag(llvm::Module::Min, - "sign-return-address-with-bkey", 1); + "sign-return-address-with-bkey", 2); if (LangOpts.PointerAuthELFGOT) getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1); @@ -2863,6 +2870,11 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, } } + if (CodeGenOpts.CallGraphSection) { + if (auto *FD = dyn_cast<FunctionDecl>(D)) + createIndirectFunctionTypeMD(FD, F); + } + // Emit type metadata on member functions for member function pointer checks. // These are only ever necessary on definitions; we're guaranteed that the // definition will be present in the LTO unit as a result of LTO visibility. @@ -3066,6 +3078,26 @@ static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) { GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); } +static bool hasExistingGeneralizedTypeMD(llvm::Function *F) { + llvm::MDNode *MD = F->getMetadata(llvm::LLVMContext::MD_type); + return MD && MD->hasGeneralizedMDString(); +} + +void CodeGenModule::createIndirectFunctionTypeMD(const FunctionDecl *FD, + llvm::Function *F) { + // Return if generalized type metadata is already attached. + if (hasExistingGeneralizedTypeMD(F)) + return; + + // All functions which are not internal linkage could be indirect targets. + // Address taken functions with internal linkage could be indirect targets. + if (!F->hasLocalLinkage() || + F->getFunction().hasAddressTaken(nullptr, /*IgnoreCallbackUses=*/true, + /*IgnoreAssumeLikeCalls=*/true, + /*IgnoreLLVMUsed=*/false)) + F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType())); +} + void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Function *F) { // Only if we are checking indirect calls. @@ -3081,10 +3113,12 @@ void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD, /*GeneralizePointers=*/false); llvm::Metadata *MD = CreateMetadataIdentifierForType(FnType); F->addTypeMetadata(0, MD); - - QualType GenPtrFnType = GeneralizeFunctionType(getContext(), FD->getType(), - /*GeneralizePointers=*/true); - F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(GenPtrFnType)); + // Add the generalized identifier if not added already. + if (!hasExistingGeneralizedTypeMD(F)) { + QualType GenPtrFnType = GeneralizeFunctionType(getContext(), FD->getType(), + /*GeneralizePointers=*/true); + F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(GenPtrFnType)); + } // Emit a hash-based bit set entry for cross-DSO calls. if (CodeGenOpts.SanitizeCfiCrossDso) @@ -3092,6 +3126,21 @@ void CodeGenModule::createFunctionTypeMetadataForIcall(const FunctionDecl *FD, F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId)); } +void CodeGenModule::createCalleeTypeMetadataForIcall(const QualType &QT, + llvm::CallBase *CB) { + // Only if needed for call graph section and only for indirect calls. + if (!CodeGenOpts.CallGraphSection || !CB->isIndirectCall()) + return; + + llvm::Metadata *TypeIdMD = CreateMetadataIdentifierGeneralized(QT); + llvm::MDTuple *TypeTuple = llvm::MDTuple::get( + getLLVMContext(), {llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + llvm::Type::getInt64Ty(getLLVMContext()), 0)), + TypeIdMD}); + llvm::MDTuple *MDN = llvm::MDNode::get(getLLVMContext(), {TypeTuple}); + CB->setMetadata(llvm::LLVMContext::MD_callee_type, MDN); +} + void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) { llvm::LLVMContext &Ctx = F->getContext(); llvm::MDBuilder MDB(Ctx); @@ -3227,6 +3276,9 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, !CodeGenOpts.SanitizeCfiCanonicalJumpTables) createFunctionTypeMetadataForIcall(FD, F); + if (CodeGenOpts.CallGraphSection) + createIndirectFunctionTypeMD(FD, F); + if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) setKCFIType(FD, F); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 3971b29..a253bcd 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1644,6 +1644,13 @@ public: void createFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Function *F); + /// Create and attach type metadata if the function is a potential indirect + /// call target to support call graph section. + void createIndirectFunctionTypeMD(const FunctionDecl *FD, llvm::Function *F); + + /// Create and attach type metadata to the given call. + void createCalleeTypeMetadataForIcall(const QualType &QT, llvm::CallBase *CB); + /// Set type metadata to the given function. void setKCFIType(const FunctionDecl *FD, llvm::Function *F); diff --git a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp index 5049a0a..f49a5af 100644 --- a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp @@ -12,6 +12,7 @@ #include "CGBuiltin.h" #include "CodeGenFunction.h" +#include "clang/Basic/SyncScope.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/Analysis/ValueTracking.h" @@ -313,33 +314,33 @@ void CodeGenFunction::ProcessOrderScopeAMDGCN(Value *Order, Value *Scope, } // Older builtins had an enum argument for the memory scope. + const char *SSN = nullptr; int scope = cast<llvm::ConstantInt>(Scope)->getZExtValue(); switch (scope) { - case 0: // __MEMORY_SCOPE_SYSTEM + case AtomicScopeGenericModel::System: // __MEMORY_SCOPE_SYSTEM SSID = llvm::SyncScope::System; break; - case 1: // __MEMORY_SCOPE_DEVICE - if (getTarget().getTriple().isSPIRV()) - SSID = getLLVMContext().getOrInsertSyncScopeID("device"); - else - SSID = getLLVMContext().getOrInsertSyncScopeID("agent"); + case AtomicScopeGenericModel::Device: // __MEMORY_SCOPE_DEVICE + SSN = getTarget().getTriple().isSPIRV() ? "device" : "agent"; break; - case 2: // __MEMORY_SCOPE_WRKGRP - SSID = getLLVMContext().getOrInsertSyncScopeID("workgroup"); + case AtomicScopeGenericModel::Workgroup: // __MEMORY_SCOPE_WRKGRP + SSN = "workgroup"; break; - case 3: // __MEMORY_SCOPE_WVFRNT - if (getTarget().getTriple().isSPIRV()) - SSID = getLLVMContext().getOrInsertSyncScopeID("subgroup"); - else - SSID = getLLVMContext().getOrInsertSyncScopeID("wavefront"); + case AtomicScopeGenericModel::Cluster: // __MEMORY_SCOPE_CLUSTR + SSN = getTarget().getTriple().isSPIRV() ? "workgroup" : "cluster"; + break; + case AtomicScopeGenericModel::Wavefront: // __MEMORY_SCOPE_WVFRNT + SSN = getTarget().getTriple().isSPIRV() ? "subgroup" : "wavefront"; break; - case 4: // __MEMORY_SCOPE_SINGLE + case AtomicScopeGenericModel::Single: // __MEMORY_SCOPE_SINGLE SSID = llvm::SyncScope::SingleThread; break; default: SSID = llvm::SyncScope::System; break; } + if (SSN) + SSID = getLLVMContext().getOrInsertSyncScopeID(SSN); } llvm::Value *CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments, diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp index 16d5919..0bc4b4b7 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -508,6 +508,10 @@ AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts, case SyncScope::WavefrontScope: Name = "wavefront"; break; + case SyncScope::HIPCluster: + case SyncScope::ClusterScope: + Name = "cluster"; + break; case SyncScope::HIPWorkgroup: case SyncScope::OpenCLWorkGroup: case SyncScope::WorkgroupScope: diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 3f6d4e0..80e096e 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -93,6 +93,8 @@ inline StringRef mapClangSyncScopeToLLVM(SyncScope Scope) { case SyncScope::OpenCLSubGroup: case SyncScope::WavefrontScope: return "subgroup"; + case SyncScope::HIPCluster: + case SyncScope::ClusterScope: case SyncScope::HIPWorkgroup: case SyncScope::OpenCLWorkGroup: case SyncScope::WorkgroupScope: |