Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ clang/include/clang/AST/ASTContext.h @@ -45,6 +45,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/TinyPtrVector.h" +#include "llvm/Frontend/OpenMP/OMPContext.h" #include "llvm/Support/TypeSize.h" namespace llvm { @@ -454,6 +455,10 @@ static constexpr unsigned GeneralTypesLog2InitSize = 9; static constexpr unsigned FunctionProtoTypesLog2InitSize = 12; + /// A lazily initialized llvm::TargetMachine objects. They are used + /// to define the default OpenMP SIMD alignment which is target specific + llvm::TargetMachineCache OpenMPTargets; + ASTContext &this_() { return *this; } public: @@ -2269,7 +2274,7 @@ TypeInfo getTypeInfo(QualType T) const { return getTypeInfo(T.getTypePtr()); } /// Get default simd alignment of the specified complete type in bits. - unsigned getOpenMPDefaultSimdAlign(QualType T) const; + unsigned getOpenMPDefaultSimdAlign(QualType T); /// Return the size of the specified (complete) type \p T, in bits. uint64_t getTypeSize(QualType T) const { return getTypeInfo(T).Width; } Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -226,7 +226,6 @@ bool HasStrictFP; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; - unsigned short SimdDefaultAlign; std::string DataLayoutString; const char *UserLabelPrefix; const char *MCountName; @@ -795,10 +794,6 @@ /// Return the maximum vector alignment supported for the given target. unsigned getMaxVectorAlign() const { return MaxVectorAlign; } - /// Return default simd alignment for the given target. Generally, this - /// value is type-specific, but this alignment can be used for most of the - /// types for the given target. - unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; } unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; } Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -2496,9 +2496,12 @@ return UnadjustedAlign; } -unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const { - unsigned SimdAlign = getTargetInfo().getSimdDefaultAlign(); - return SimdAlign; +unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) { + const std::vector &TargetFeatures = + Target->getTargetOpts().Features; + + return OpenMPTargets.GetVectorTypeAlignment( + Target->getTriple().str(), Target->getTargetOpts().CPU, TargetFeatures); } /// toCharUnitsFromBits - Convert a size in bits to a size in characters. Index: clang/lib/Basic/TargetInfo.cpp =================================================================== --- clang/lib/Basic/TargetInfo.cpp +++ clang/lib/Basic/TargetInfo.cpp @@ -95,7 +95,6 @@ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; MaxVectorAlign = 0; MaxTLSAlign = 0; - SimdDefaultAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; Index: clang/lib/Basic/Targets/PPC.h =================================================================== --- clang/lib/Basic/Targets/PPC.h +++ clang/lib/Basic/Targets/PPC.h @@ -88,7 +88,6 @@ PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { SuitableAlign = 128; - SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); HasStrictFP = true; Index: clang/lib/Basic/Targets/WebAssembly.h =================================================================== --- clang/lib/Basic/Targets/WebAssembly.h +++ clang/lib/Basic/Targets/WebAssembly.h @@ -50,7 +50,6 @@ SuitableAlign = 128; LargeArrayMinWidth = 128; LargeArrayAlign = 128; - SimdDefaultAlign = 128; SigAtomicType = SignedLong; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); Index: clang/lib/Basic/Targets/X86.cpp =================================================================== --- clang/lib/Basic/Targets/X86.cpp +++ clang/lib/Basic/Targets/X86.cpp @@ -399,9 +399,6 @@ return false; } - SimdDefaultAlign = - hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; - // FIXME: We should allow long double type on 32-bits to match with GCC. // This requires backend to be able to lower f80 without x87 first. if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended()) Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -499,8 +499,6 @@ auto target_info = TargetInfo::CreateTargetInfo( m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts); if (log) { - LLDB_LOGF(log, "Using SIMD alignment: %d", - target_info->getSimdDefaultAlign()); LLDB_LOGF(log, "Target datalayout string: '%s'", target_info->getDataLayoutString()); LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str()); Index: llvm/include/llvm/Frontend/OpenMP/OMPContext.h =================================================================== --- llvm/include/llvm/Frontend/OpenMP/OMPContext.h +++ llvm/include/llvm/Frontend/OpenMP/OMPContext.h @@ -19,10 +19,13 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" namespace llvm { +class Type; class Triple; +class TargetMachine; namespace omp { /// OpenMP Context related IDs and helpers @@ -206,5 +209,29 @@ } }; +/// The class which stores TargetMachine items. TargetMachine items store +/// information about maximal simd alignment for given target. Target data +/// is required to determine vector type alignment. +class TargetMachineCache { + StringMap Targets; + +public: + ~TargetMachineCache(); + + /// Get the alignment value for given target and type of aligned value + /// + /// \param Triple String which describes target triple + /// \param CPU String which describes target CPU + /// \param Features String which describes extra CPU features + /// \param AlignedValueTy Type of the value which needs to be aligned. + /// If it is nullptr then the alignment is calculated + /// on the basis of target CPU properties. + uint64_t + GetVectorTypeAlignment(const std::string &TargetTriple, + const std::string &CPU, + const std::vector &TargetFeatures, + Type *AlignedValueTy = nullptr); +}; + } // end namespace llvm #endif // LLVM_FRONTEND_OPENMP_OMPCONTEXT_H Index: llvm/include/llvm/Target/TargetMachine.h =================================================================== --- llvm/include/llvm/Target/TargetMachine.h +++ llvm/include/llvm/Target/TargetMachine.h @@ -106,6 +106,9 @@ std::unique_ptr MII; std::unique_ptr STI; + /// OpenMP Target Specific information + unsigned OpenMPSimdMaxAlignment = 0; + unsigned RequireStructuredCFG : 1; unsigned O0WantsFastISel : 1; @@ -195,6 +198,9 @@ return DL.getPointerSize(DL.getAllocaAddrSpace()); } + /// Return maximal allowed SIMD alignment + unsigned getMaximalSimdAlignment() const { return OpenMPSimdMaxAlignment; } + /// Reset the target options based on the function's attributes. // FIXME: Remove TargetOptions that affect per-function code generation // from TargetMachine. Index: llvm/lib/Frontend/OpenMP/OMPContext.cpp =================================================================== --- llvm/lib/Frontend/OpenMP/OMPContext.cpp +++ llvm/lib/Frontend/OpenMP/OMPContext.cpp @@ -16,8 +16,12 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/Type.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" +#include #define DEBUG_TYPE "openmp-ir-builder" @@ -546,3 +550,56 @@ S.pop_back(); return S; } + +TargetMachineCache::~TargetMachineCache() { + for (auto &TargetItem : Targets) { + delete TargetItem.getValue(); + } +} + +uint64_t TargetMachineCache::GetVectorTypeAlignment( + const std::string &Triple, const std::string &CPU, + const std::vector &TargetFeatures, Type *AlignedValueTy) { + + uint64_t MaxSimdAlignment; + std::string TargetFeaturesString = std::accumulate( + TargetFeatures.cbegin(), TargetFeatures.cend(), std::string(), + [](const std::string &s1, const std::string &s2) { + return s1.empty() ? s2 : s1 + "," + s2; + }); + std::string Key = Triple + CPU + TargetFeaturesString; + + if (!Targets.count(Key)) { + TargetOptions Options; + const Target *TheTarget; + std::string Error; + TheTarget = TargetRegistry::lookupTarget(Triple, Error); + if (!TheTarget) + return 0; + + Targets[Key] = TheTarget->createTargetMachine( + Triple, CPU, TargetFeaturesString, Options, /*RelocModel=*/std::nullopt, + /*CodeModel=*/std::nullopt, CodeGenOpt::Default); + } + + const auto &TargetsIter = Targets.find(Key); + if (!TargetsIter->getValue()) + return 0; + + // Get maximal SIMD alignment specified for given target + MaxSimdAlignment = TargetsIter->getValue()->getMaximalSimdAlignment(); + + // If aligned value type is not specified, then return maximal target + // alignment for given target. + if (!AlignedValueTy) + return MaxSimdAlignment; + + const DataLayout &DL = TargetsIter->getValue()->createDataLayout(); + Align PrefAlign = DL.getPrefTypeAlign(AlignedValueTy); + + // If preferred alignment is bigger than maximal, return the maximal value + if (PrefAlign.value() > MaxSimdAlignment) + return MaxSimdAlignment; + + return PrefAlign.value(); +} Index: llvm/lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCTargetMachine.cpp +++ llvm/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -331,6 +331,7 @@ TLOF(createTLOF(getTargetTriple())), TargetABI(computeTargetABI(TT, Options)), Endianness(isLittleEndianTriple(TT) ? Endian::LITTLE : Endian::BIG) { + OpenMPSimdMaxAlignment = 128; initAsmInfo(); } Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -138,6 +138,7 @@ this->Options.FunctionSections = true; this->Options.DataSections = true; this->Options.UniqueSectionNames = true; + OpenMPSimdMaxAlignment = 128; initAsmInfo(); Index: llvm/lib/Target/X86/X86TargetMachine.cpp =================================================================== --- llvm/lib/Target/X86/X86TargetMachine.cpp +++ llvm/lib/Target/X86/X86TargetMachine.cpp @@ -243,6 +243,13 @@ setSupportsDebugEntryValues(true); initAsmInfo(); + + if (FS.contains("+avx512f")) + OpenMPSimdMaxAlignment = 512; + else if (FS.contains("+avx")) + OpenMPSimdMaxAlignment = 256; + else + OpenMPSimdMaxAlignment = 128; } X86TargetMachine::~X86TargetMachine() = default;