aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp18
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp65
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h7
-rw-r--r--clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp29
-rw-r--r--clang/lib/CodeGen/Targets/AMDGPU.cpp4
-rw-r--r--clang/lib/CodeGen/Targets/SPIR.cpp2
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: