diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 65 | ||||
-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 |
6 files changed, 106 insertions, 19 deletions
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 c5eb14e..e490b1c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -83,6 +83,7 @@ static llvm::cl::opt<bool> LimitedCoverage( llvm::cl::desc("Emit limited coverage mapping information (experimental)")); static const char AnnotationSection[] = "llvm.metadata"; +static constexpr auto ErrnoTBAAMDName = "llvm.errno.tbaa"; static CGCXXABI *createCXXABI(CodeGenModule &CGM) { switch (CGM.getContext().getCXXABIKind()) { @@ -1583,6 +1584,17 @@ void CodeGenModule::Release() { } } } + + // Emit `!llvm.errno.tbaa`, a module-level metadata that specifies the TBAA + // for an int access. This allows LLVM to reason about what memory can be + // accessed by certain library calls that only touch errno. + if (TBAA) { + TBAAAccessInfo TBAAInfo = getTBAAAccessInfo(Context.IntTy); + if (llvm::MDNode *IntegerNode = getTBAAAccessTagInfo(TBAAInfo)) { + auto *ErrnoTBAAMD = TheModule.getOrInsertNamedMetadata(ErrnoTBAAMDName); + ErrnoTBAAMD->addOperand(IntegerNode); + } + } } void CodeGenModule::EmitOpenCLMetadata() { @@ -2851,6 +2863,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. @@ -3054,6 +3071,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. @@ -3069,10 +3106,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) @@ -3080,6 +3119,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); @@ -3215,6 +3269,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: |