diff options
-rw-r--r-- | clang/include/clang/AST/ASTContext.h | 10 | ||||
-rw-r--r-- | clang/include/clang/Basic/LangOptions.def | 1 | ||||
-rw-r--r-- | clang/include/clang/Basic/LangOptions.h | 2 | ||||
-rw-r--r-- | clang/include/clang/Basic/TargetInfo.h | 10 | ||||
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 14 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Basic/TargetInfo.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 22 | ||||
-rw-r--r-- | clang/test/CodeGenOpenCL/address-spaces-mangling.cl | 30 | ||||
-rw-r--r-- | clang/test/CodeGenOpenCL/local.cl | 4 |
12 files changed, 123 insertions, 9 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 107b5f1fc08..f1ccee2e372 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -393,6 +393,10 @@ private: /// \brief The logical -> physical address space map. const LangAS::Map *AddrSpaceMap; + /// \brief Address space map mangling must be used with language specific + /// address spaces (e.g. OpenCL/CUDA) + bool AddrSpaceMapMangling; + friend class ASTDeclReader; friend class ASTReader; friend class ASTWriter; @@ -1920,6 +1924,12 @@ public: return (*AddrSpaceMap)[AS - LangAS::Offset]; } + bool addressSpaceMapManglingFor(unsigned AS) const { + return AddrSpaceMapMangling || + AS < LangAS::Offset || + AS >= LangAS::Offset + LangAS::Count; + } + private: // Helper for integer ordering unsigned getIntegerRank(const Type *T) const; diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a2e94ffc78d..55db34ce304 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -142,6 +142,7 @@ LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility") LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") LANGOPT(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") +ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") LANGOPT(MRTD , 1, 0, "-mrtd calling convention") BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 21ca7eb201c..45320542ab7 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -66,6 +66,8 @@ public: SOB_Trapping // -ftrapv }; + enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; + public: clang::ObjCRuntime ObjCRuntime; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index ee3a28db2ee..bda6af374a2 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -202,6 +202,10 @@ protected: /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; + /// \brief Specify if mangling based on address space map should be used or + /// not for language specific address spaces + bool UseAddrSpaceMapMangling; + public: IntType getSizeType() const { return SizeType; } IntType getIntMaxType() const { return IntMaxType; } @@ -431,6 +435,12 @@ public: return ComplexLongDoubleUsesFP2Ret; } + /// \brief Specify if mangling based on address space map should be used or + /// not for language specific address spaces + bool useAddressSpaceMapMangling() const { + return UseAddrSpaceMapMangling; + } + ///===---- Other target property query methods --------------------------===// /// \brief Appends the target-specific \#define values for this diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index b74f4453e65..d91001f8c78 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -460,6 +460,8 @@ def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">, HelpText<"Ignore bit-field types when aligning structures">; def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">, HelpText<"Use a fake address space map; OpenCL testing purposes only">; +def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"<yes|no|target>">, + HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">; def funknown_anytype : Flag<["-"], "funknown-anytype">, HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">; def fdebugger_support : Flag<["-"], "fdebugger-support">, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4ab987d844f..0783f291610 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -695,6 +695,19 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T, } } +static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, + const LangOptions &LangOpts) { + switch (LangOpts.getAddressSpaceMapMangling()) { + default: return false; + case LangOptions::ASMM_Target: + return TI.useAddressSpaceMapMangling(); + case LangOptions::ASMM_On: + return true; + case LangOptions::ASMM_Off: + return false; + } +} + ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t, IdentifierTable &idents, SelectorTable &sels, @@ -900,6 +913,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { ABI.reset(createCXXABI(Target)); AddrSpaceMap = getAddressSpaceMap(Target, LangOpts); + AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts); // C99 6.2.5p19. InitBuiltinType(VoidTy, BuiltinType::Void); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 38a6223f788..91e8244b017 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1755,15 +1755,33 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { Out << 'K'; if (Quals.hasAddressSpace()) { - // Extension: + // Address space extension: // - // <type> ::= U <address-space-number> - // - // where <address-space-number> is a source name consisting of 'AS' - // followed by the address space <number>. + // <type> ::= U <target-addrspace> + // <type> ::= U <OpenCL-addrspace> + // <type> ::= U <CUDA-addrspace> + SmallString<64> ASString; - ASString = "AS" + llvm::utostr_32( - Context.getASTContext().getTargetAddressSpace(Quals.getAddressSpace())); + unsigned AS = Quals.getAddressSpace(); + bool IsLangAS = (LangAS::Offset <= AS) && (AS < LangAS::Last); + + if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { + // <target-addrspace> ::= "AS" <address-space-number> + unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS); + ASString = "AS" + llvm::utostr_32(TargetAS); + } else { + switch (AS) { + default: llvm_unreachable("Not a language specific address space"); + // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" ] + case LangAS::opencl_global: ASString = "CLglobal"; break; + case LangAS::opencl_local: ASString = "CLlocal"; break; + case LangAS::opencl_constant: ASString = "CLconstant"; break; + // <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ] + case LangAS::cuda_device: ASString = "CUdevice"; break; + case LangAS::cuda_constant: ASString = "CUconstant"; break; + case LangAS::cuda_shared: ASString = "CUshared"; break; + } + } Out << 'U' << ASString.size() << ASString; } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 3feaf9e572c..e993055cc88 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -88,6 +88,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // Default to an empty address space map. AddrSpaceMap = &DefaultAddrSpaceMap; + UseAddrSpaceMapMangling = false; // Default to an unknown platform name. PlatformName = "unknown"; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 00431c2a0d6..b1cbc23f814 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -1266,6 +1266,7 @@ namespace { TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &NVPTXAddrSpaceMap; + UseAddrSpaceMapMangling = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; @@ -1424,6 +1425,7 @@ public: : TargetInfo(Triple), GPU(GK_R600) { DescriptionString = DescriptionStringR600; AddrSpaceMap = &R600AddrSpaceMap; + UseAddrSpaceMapMangling = true; } virtual const char * getClobbers() const { @@ -4577,6 +4579,7 @@ namespace { "f32:32:32-f64:32:32-v64:32:32-" "v128:32:32-a0:0:32-n32"; AddrSpaceMap = &TCEOpenCLAddrSpaceMap; + UseAddrSpaceMapMangling = true; } virtual void getTargetDefines(const LangOptions &Opts, @@ -5139,6 +5142,7 @@ namespace { TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &SPIRAddrSpaceMap; + UseAddrSpaceMapMangling = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 669ea5de3ef..1c3dd7da7c5 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1329,6 +1329,28 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack); Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name); + if (Arg *A = Args.getLastArg(OPT_faddress_space_map_mangling_EQ)) { + switch (llvm::StringSwitch<unsigned>(A->getValue()) + .Case("target", LangOptions::ASMM_Target) + .Case("no", LangOptions::ASMM_Off) + .Case("yes", LangOptions::ASMM_On) + .Default(255)) { + default: + Diags.Report(diag::err_drv_invalid_value) + << "-faddress-space-map-mangling=" << A->getValue(); + break; + case LangOptions::ASMM_Target: + Opts.setAddressSpaceMapMangling(LangOptions::ASMM_Target); + break; + case LangOptions::ASMM_On: + Opts.setAddressSpaceMapMangling(LangOptions::ASMM_On); + break; + case LangOptions::ASMM_Off: + Opts.setAddressSpaceMapMangling(LangOptions::ASMM_Off); + break; + } + } + // Check if -fopenmp is specified. Opts.OpenMP = Args.hasArg(OPT_fopenmp); diff --git a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl new file mode 100644 index 00000000000..3c7a5183636 --- /dev/null +++ b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s +// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s + +// We can't name this f as private is equivalent to default +// no specifier given address space so we get multiple definition +// warnings, but we do want it for comparison purposes. +__attribute__((overloadable)) +void ff(int *arg) { } +// ASMANG: @_Z2ffPi +// NOASMANG: @_Z2ffPi + +__attribute__((overloadable)) +void f(private int *arg) { } +// ASMANG: @_Z1fPi +// NOASMANG: @_Z1fPi + +__attribute__((overloadable)) +void f(global int *arg) { } +// ASMANG: @_Z1fPU3AS1i +// NOASMANG: @_Z1fPU8CLglobali + +__attribute__((overloadable)) +void f(local int *arg) { } +// ASMANG: @_Z1fPU3AS2i +// NOASMANG: @_Z1fPU7CLlocali + +__attribute__((overloadable)) +void f(constant int *arg) { } +// ASMANG: @_Z1fPU3AS3i +// NOASMANG: @_Z1fPU10CLconstanti diff --git a/clang/test/CodeGenOpenCL/local.cl b/clang/test/CodeGenOpenCL/local.cl index 852fa438f50..b5c67d9af9c 100644 --- a/clang/test/CodeGenOpenCL/local.cl +++ b/clang/test/CodeGenOpenCL/local.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -emit-llvm -o - | FileCheck %s __kernel void foo(void) { // CHECK: @foo.i = internal addrspace(2) @@ -6,7 +6,7 @@ __kernel void foo(void) { ++i; } -// CHECK-LABEL: define void @_Z3barPU3AS2i +// CHECK-LABEL: define void @_Z3barPU7CLlocali __kernel void __attribute__((__overloadable__)) bar(local int *x) { *x = 5; } |