Skip to content

Commit e811c53

Browse files
authored
[SYCL][NativeCPU] Build libclc target-independently. (#17408)
This change creates a Clang NativeCPU target to be used for creating LLVM IR for NativeCPU, builds libclc with this target, and does the initial processing of NativeCPU device code with this target. This allows the libclc to be independent of the concrete host target, allowing libclc to be re-used across different host targets, and across different ABIs for the same host target.
1 parent e8d1e30 commit e811c53

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+315
-534
lines changed

clang/lib/Basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ add_clang_library(clangBasic
108108
Targets/MSP430.cpp
109109
Targets/Mips.cpp
110110
Targets/NVPTX.cpp
111+
Targets/NativeCPU.cpp
111112
Targets/OSTargets.cpp
112113
Targets/PNaCl.cpp
113114
Targets/PPC.cpp

clang/lib/Basic/TargetInfo.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -546,41 +546,6 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
546546

547547
if (Opts.FakeAddressSpaceMap)
548548
AddrSpaceMap = &FakeAddrSpaceMap;
549-
550-
if ((Opts.SYCLIsDevice || Opts.OpenCL) && Opts.SYCLIsNativeCPU) {
551-
// For SYCL Native CPU we use the NVPTXAddrSpaceMap because
552-
// we need builtins to be mangled with AS information.
553-
// This is also enabled in OpenCL mode so that mangling
554-
// matches when building libclc.
555-
556-
static const unsigned SYCLNativeCPUASMap[] = {
557-
0, // Default
558-
1, // opencl_global
559-
3, // opencl_local
560-
4, // opencl_constant
561-
0, // opencl_private
562-
0, // opencl_generic
563-
1, // opencl_global_device
564-
1, // opencl_global_host
565-
1, // cuda_device
566-
4, // cuda_constant
567-
3, // cuda_shared
568-
1, // sycl_global
569-
1, // sycl_global_device
570-
1, // sycl_global_host
571-
3, // sycl_local
572-
0, // sycl_private
573-
0, // ptr32_sptr
574-
0, // ptr32_uptr
575-
0, // ptr64
576-
0, // hlsl_groupshared
577-
0, // hlsl_constant
578-
20, // wasm_funcref
579-
};
580-
581-
AddrSpaceMap = &SYCLNativeCPUASMap;
582-
UseAddrSpaceMapMangling = true;
583-
}
584549
}
585550

586551
bool TargetInfo::initFeatureMap(

clang/lib/Basic/Targets.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "Targets/MSP430.h"
2929
#include "Targets/Mips.h"
3030
#include "Targets/NVPTX.h"
31+
#include "Targets/NativeCPU.h"
3132
#include "Targets/OSTargets.h"
3233
#include "Targets/PNaCl.h"
3334
#include "Targets/PPC.h"
@@ -117,6 +118,13 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
117118
default:
118119
return nullptr;
119120

121+
case llvm::Triple::UnknownArch:
122+
// native_cpu is only known to Clang, not to LLVM.
123+
if (Triple.str() == "native_cpu")
124+
return std::make_unique<NativeCPUTargetInfo>(Triple, Opts);
125+
126+
return nullptr;
127+
120128
case llvm::Triple::arc:
121129
return std::make_unique<ARCTargetInfo>(Triple, Opts);
122130

clang/lib/Basic/Targets/NativeCPU.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===--- NativeCPU.cpp - Implement NativeCPU target feature support -------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements NativeCPU TargetInfo objects.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "NativeCPU.h"
14+
#include <llvm/TargetParser/Host.h>
15+
16+
using namespace clang;
17+
using namespace clang::targets;
18+
19+
static const LangASMap NativeCPUASMap = {
20+
0, // Default
21+
1, // opencl_global
22+
3, // opencl_local
23+
4, // opencl_constant
24+
0, // opencl_private
25+
0, // opencl_generic
26+
1, // opencl_global_device
27+
1, // opencl_global_host
28+
1, // cuda_device
29+
4, // cuda_constant
30+
3, // cuda_shared
31+
1, // sycl_global
32+
1, // sycl_global_device
33+
1, // sycl_global_host
34+
3, // sycl_local
35+
0, // sycl_private
36+
0, // ptr32_sptr
37+
0, // ptr32_uptr
38+
0, // ptr64
39+
0, // hlsl_groupshared
40+
0, // hlsl_constant
41+
20, // wasm_funcref
42+
};
43+
44+
NativeCPUTargetInfo::NativeCPUTargetInfo(const llvm::Triple &,
45+
const TargetOptions &Opts)
46+
: TargetInfo(llvm::Triple()) {
47+
AddrSpaceMap = &NativeCPUASMap;
48+
UseAddrSpaceMapMangling = true;
49+
HasLegalHalfType = true;
50+
HasFloat16 = true;
51+
resetDataLayout("e");
52+
53+
llvm::Triple HostTriple([&] {
54+
// Take the default target triple if no other host triple is specified so
55+
// that system headers work.
56+
if (Opts.HostTriple.empty())
57+
return llvm::sys::getDefaultTargetTriple();
58+
59+
return Opts.HostTriple;
60+
}());
61+
if (HostTriple.getArch() != llvm::Triple::UnknownArch) {
62+
HostTarget = AllocateTarget(HostTriple, Opts);
63+
64+
// Copy properties from host target.
65+
BoolWidth = HostTarget->getBoolWidth();
66+
BoolAlign = HostTarget->getBoolAlign();
67+
IntWidth = HostTarget->getIntWidth();
68+
IntAlign = HostTarget->getIntAlign();
69+
HalfWidth = HostTarget->getHalfWidth();
70+
HalfAlign = HostTarget->getHalfAlign();
71+
FloatWidth = HostTarget->getFloatWidth();
72+
FloatAlign = HostTarget->getFloatAlign();
73+
DoubleWidth = HostTarget->getDoubleWidth();
74+
DoubleAlign = HostTarget->getDoubleAlign();
75+
LongWidth = HostTarget->getLongWidth();
76+
LongAlign = HostTarget->getLongAlign();
77+
LongLongWidth = HostTarget->getLongLongWidth();
78+
LongLongAlign = HostTarget->getLongLongAlign();
79+
PointerWidth = HostTarget->getPointerWidth(LangAS::Default);
80+
PointerAlign = HostTarget->getPointerAlign(LangAS::Default);
81+
MinGlobalAlign = HostTarget->getMinGlobalAlign(/*TypeSize=*/0,
82+
/*HasNonWeakDef=*/true);
83+
NewAlign = HostTarget->getNewAlign();
84+
DefaultAlignForAttributeAligned =
85+
HostTarget->getDefaultAlignForAttributeAligned();
86+
SizeType = HostTarget->getSizeType();
87+
PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default);
88+
IntMaxType = HostTarget->getIntMaxType();
89+
WCharType = HostTarget->getWCharType();
90+
WIntType = HostTarget->getWIntType();
91+
Char16Type = HostTarget->getChar16Type();
92+
Char32Type = HostTarget->getChar32Type();
93+
Int64Type = HostTarget->getInt64Type();
94+
SigAtomicType = HostTarget->getSigAtomicType();
95+
ProcessIDType = HostTarget->getProcessIDType();
96+
97+
UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
98+
UseZeroLengthBitfieldAlignment =
99+
HostTarget->useZeroLengthBitfieldAlignment();
100+
UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
101+
ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
102+
103+
// This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
104+
// we need those macros to be identical on host and device, because (among
105+
// other things) they affect which standard library classes are defined,
106+
// and we need all classes to be defined on both the host and device.
107+
MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
108+
}
109+
}

clang/lib/Basic/Targets/NativeCPU.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//===--- NativeCPU.h - Declare NativeCPU target feature support -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares NativeCPU TargetInfo objects.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_NATIVECPU_H
14+
#define LLVM_CLANG_LIB_BASIC_TARGETS_NATIVECPU_H
15+
16+
#include "Targets.h"
17+
18+
namespace clang {
19+
namespace targets {
20+
21+
class LLVM_LIBRARY_VISIBILITY NativeCPUTargetInfo final : public TargetInfo {
22+
std::unique_ptr<TargetInfo> HostTarget;
23+
24+
public:
25+
NativeCPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
26+
27+
void getTargetDefines(const LangOptions &Opts,
28+
MacroBuilder &Builder) const override {
29+
DefineStd(Builder, "NativeCPU", Opts);
30+
}
31+
32+
SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {
33+
return {};
34+
}
35+
36+
BuiltinVaListKind getBuiltinVaListKind() const override {
37+
if (HostTarget)
38+
return HostTarget->getBuiltinVaListKind();
39+
40+
return TargetInfo::VoidPtrBuiltinVaList;
41+
}
42+
43+
bool validateAsmConstraint(const char *&Name,
44+
TargetInfo::ConstraintInfo &info) const override {
45+
return true;
46+
}
47+
48+
std::string_view getClobbers() const override { return ""; }
49+
50+
void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
51+
52+
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
53+
if (HostTarget)
54+
return HostTarget->checkCallingConvention(CC);
55+
56+
return TargetInfo::checkCallingConvention(CC);
57+
}
58+
59+
protected:
60+
ArrayRef<const char *> getGCCRegNames() const override { return {}; }
61+
62+
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
63+
return {};
64+
}
65+
66+
bool hasBitIntType() const override { return true; }
67+
};
68+
69+
} // namespace targets
70+
} // namespace clang
71+
72+
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_NATIVECPU_H

clang/lib/Driver/Compilation.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "clang/Driver/Compilation.h"
10+
#include "ToolChains/SYCL.h"
1011
#include "clang/Basic/LLVM.h"
1112
#include "clang/Driver/Action.h"
1213
#include "clang/Driver/Driver.h"
@@ -127,7 +128,8 @@ Compilation::getArgsForToolChain(const ToolChain *TC, StringRef BoundArch,
127128
if (DeviceOffloadKind == Action::OFK_OpenMP ||
128129
DeviceOffloadKind == Action::OFK_SYCL) {
129130
const ToolChain *HostTC = getSingleOffloadToolChain<Action::OFK_Host>();
130-
bool SameTripleAsHost = (TC->getTriple() == HostTC->getTriple());
131+
bool SameTripleAsHost = (TC->getTriple() == HostTC->getTriple()) ||
132+
isSYCLNativeCPU(TC->getTriple());
131133
OffloadArgs = TC->TranslateOffloadTargetArgs(
132134
*TranslatedArgs, SameTripleAsHost, AllocatedArgs, DeviceOffloadKind);
133135
}

clang/lib/Driver/Driver.cpp

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,10 @@ static bool isValidSYCLTriple(llvm::Triple T) {
968968
!T.hasEnvironment())
969969
return true;
970970

971+
// 'native_cpu' is valid for Native CPU.
972+
if (isSYCLNativeCPU(T))
973+
return true;
974+
971975
// Check for invalid SYCL device triple values.
972976
// Non-SPIR/SPIRV arch.
973977
if (!T.isSPIROrSPIRV())
@@ -1392,12 +1396,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
13921396
}
13931397
Arch = Device->data();
13941398
UserTargetName = "amdgcn-amd-amdhsa";
1395-
} else if (Val == "native_cpu") {
1396-
const ToolChain *HostTC =
1397-
C.getSingleOffloadToolChain<Action::OFK_Host>();
1398-
llvm::Triple HostTriple = HostTC->getTriple();
1399-
SYCLTriples.insert(HostTriple.normalize());
1400-
continue;
14011399
}
14021400

14031401
llvm::Triple DeviceTriple(getSYCLDeviceTriple(UserTargetName));
@@ -5667,9 +5665,7 @@ class OffloadingActionBuilder final {
56675665
auto IsAMDGCN = TargetTriple.isAMDGCN();
56685666
auto IsSPIR = TargetTriple.isSPIROrSPIRV();
56695667
bool IsSpirvAOT = TargetTriple.isSPIRAOT();
5670-
const bool IsSYCLNativeCPU =
5671-
TC->getAuxTriple() &&
5672-
driver::isSYCLNativeCPU(TargetTriple, *TC->getAuxTriple());
5668+
bool IsSYCLNativeCPU = isSYCLNativeCPU(TargetTriple);
56735669
for (const auto &Input : ListIndex) {
56745670
if (TargetTriple.getSubArch() == llvm::Triple::SPIRSubArch_fpga &&
56755671
types::isFPGA(Input->getType())) {
@@ -6733,12 +6729,6 @@ class OffloadingActionBuilder final {
67336729
C.getDriver().getSYCLDeviceTriple("amdgcn-amd-amdhsa"),
67346730
ValidDevice->data());
67356731
UserTargetName = "amdgcn-amd-amdhsa";
6736-
} else if (Val == "native_cpu") {
6737-
const ToolChain *HostTC =
6738-
C.getSingleOffloadToolChain<Action::OFK_Host>();
6739-
llvm::Triple TT = HostTC->getTriple();
6740-
SYCLTripleList.push_back(TT);
6741-
continue;
67426732
}
67436733

67446734
llvm::Triple TT(
@@ -7277,10 +7267,6 @@ class OffloadingActionBuilder final {
72777267
/// Offload deps output is then forwarded to active device action builders so
72787268
/// they can add it to the device linker inputs.
72797269
void addDeviceLinkDependenciesFromHost(ActionList &LinkerInputs) {
7280-
if (isSYCLNativeCPU(C.getArgs())) {
7281-
// SYCL Native CPU doesn't need deps from clang-offload-deps.
7282-
return;
7283-
}
72847270
// Link image for reading dependencies from it.
72857271
auto *LA = C.MakeAction<LinkJobAction>(LinkerInputs,
72867272
types::TY_Host_Dependencies_Image);
@@ -9684,9 +9670,7 @@ InputInfoList Driver::BuildJobsForActionNoCache(
96849670
Action::OffloadKind DependentOffloadKind;
96859671
if (UI.DependentOffloadKind == Action::OFK_SYCL &&
96869672
TargetDeviceOffloadKind == Action::OFK_None &&
9687-
!(isSYCLNativeCPU(Args) &&
9688-
isSYCLNativeCPU(C.getDefaultToolChain().getTriple(),
9689-
TC->getTriple()) &&
9673+
!(isSYCLNativeCPU(C.getDefaultToolChain().getTriple()) &&
96909674
UA->getDependentActionsInfo().size() > 1))
96919675
DependentOffloadKind = Action::OFK_Host;
96929676
else
@@ -10581,9 +10565,9 @@ const ToolChain &Driver::getOffloadToolChain(
1058110565
*HostTC, Args, Kind);
1058210566
break;
1058310567
default:
10584-
if (Kind == Action::OFK_SYCL && isSYCLNativeCPU(Args))
10585-
TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target,
10586-
*HostTC, Args);
10568+
if (Kind == Action::OFK_SYCL && isSYCLNativeCPU(Target))
10569+
TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target, *HostTC,
10570+
Args);
1058710571
break;
1058810572
}
1058910573
}

clang/lib/Driver/OffloadBundler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ bool OffloadTargetInfo::isOffloadKindCompatible(
177177
}
178178

179179
bool OffloadTargetInfo::isTripleValid() const {
180-
return !Triple.str().empty() && Triple.getArch() != Triple::UnknownArch;
180+
return !Triple.str().empty() && (Triple.getArch() != Triple::UnknownArch ||
181+
Triple.str() == "native_cpu---");
181182
}
182183

183184
bool OffloadTargetInfo::operator==(const OffloadTargetInfo &Target) const {

0 commit comments

Comments
 (0)