Skip to content

Commit 5836c35

Browse files
committedOct 15, 2019
[Clang][OpenMP Offload] Move offload registration code to the wrapper
The final list of OpenMP offload targets becomes known only at the link time and since offload registration code depends on the targets list it makes sense to delay offload registration code generation to the link time instead of adding it to the host part of every fat object. This patch moves offload registration code generation from clang to the offload wrapper tool. This is the last part of the OpenMP linker script elimination patch https://reviews.llvm.org/D64943 Differential Revision: https://reviews.llvm.org/D68746 llvm-svn: 374937
1 parent 215a8d9 commit 5836c35

38 files changed

+524
-1140
lines changed
 

‎clang/lib/CodeGen/CGOpenMPRuntime.cpp

+3-168
Original file line numberDiff line numberDiff line change
@@ -4006,157 +4006,6 @@ void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
40064006
Action(E.getKey(), E.getValue());
40074007
}
40084008

4009-
llvm::Function *
4010-
CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() {
4011-
// If we don't have entries or if we are emitting code for the device, we
4012-
// don't need to do anything.
4013-
if (CGM.getLangOpts().OpenMPIsDevice || OffloadEntriesInfoManager.empty())
4014-
return nullptr;
4015-
4016-
llvm::Module &M = CGM.getModule();
4017-
ASTContext &C = CGM.getContext();
4018-
4019-
// Get list of devices we care about
4020-
const std::vector<llvm::Triple> &Devices = CGM.getLangOpts().OMPTargetTriples;
4021-
4022-
// We should be creating an offloading descriptor only if there are devices
4023-
// specified.
4024-
assert(!Devices.empty() && "No OpenMP offloading devices??");
4025-
4026-
// Create the external variables that will point to the begin and end of the
4027-
// host entries section. These will be defined by the linker.
4028-
llvm::Type *OffloadEntryTy =
4029-
CGM.getTypes().ConvertTypeForMem(getTgtOffloadEntryQTy());
4030-
auto *HostEntriesBegin = new llvm::GlobalVariable(
4031-
M, OffloadEntryTy, /*isConstant=*/true,
4032-
llvm::GlobalValue::ExternalLinkage, /*Initializer=*/nullptr,
4033-
"__start_omp_offloading_entries");
4034-
HostEntriesBegin->setVisibility(llvm::GlobalValue::HiddenVisibility);
4035-
auto *HostEntriesEnd = new llvm::GlobalVariable(
4036-
M, OffloadEntryTy, /*isConstant=*/true,
4037-
llvm::GlobalValue::ExternalLinkage,
4038-
/*Initializer=*/nullptr, "__stop_omp_offloading_entries");
4039-
HostEntriesEnd->setVisibility(llvm::GlobalValue::HiddenVisibility);
4040-
4041-
// Create all device images
4042-
auto *DeviceImageTy = cast<llvm::StructType>(
4043-
CGM.getTypes().ConvertTypeForMem(getTgtDeviceImageQTy()));
4044-
ConstantInitBuilder DeviceImagesBuilder(CGM);
4045-
ConstantArrayBuilder DeviceImagesEntries =
4046-
DeviceImagesBuilder.beginArray(DeviceImageTy);
4047-
4048-
for (const llvm::Triple &Device : Devices) {
4049-
StringRef T = Device.getTriple();
4050-
std::string BeginName = getName({"omp_offloading", "img_start", ""});
4051-
auto *ImgBegin = new llvm::GlobalVariable(
4052-
M, CGM.Int8Ty, /*isConstant=*/true,
4053-
llvm::GlobalValue::ExternalWeakLinkage,
4054-
/*Initializer=*/nullptr, Twine(BeginName).concat(T));
4055-
std::string EndName = getName({"omp_offloading", "img_end", ""});
4056-
auto *ImgEnd = new llvm::GlobalVariable(
4057-
M, CGM.Int8Ty, /*isConstant=*/true,
4058-
llvm::GlobalValue::ExternalWeakLinkage,
4059-
/*Initializer=*/nullptr, Twine(EndName).concat(T));
4060-
4061-
llvm::Constant *Data[] = {ImgBegin, ImgEnd, HostEntriesBegin,
4062-
HostEntriesEnd};
4063-
createConstantGlobalStructAndAddToParent(CGM, getTgtDeviceImageQTy(), Data,
4064-
DeviceImagesEntries);
4065-
}
4066-
4067-
// Create device images global array.
4068-
std::string ImagesName = getName({"omp_offloading", "device_images"});
4069-
llvm::GlobalVariable *DeviceImages =
4070-
DeviceImagesEntries.finishAndCreateGlobal(ImagesName,
4071-
CGM.getPointerAlign(),
4072-
/*isConstant=*/true);
4073-
DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4074-
4075-
// This is a Zero array to be used in the creation of the constant expressions
4076-
llvm::Constant *Index[] = {llvm::Constant::getNullValue(CGM.Int32Ty),
4077-
llvm::Constant::getNullValue(CGM.Int32Ty)};
4078-
4079-
// Create the target region descriptor.
4080-
llvm::Constant *Data[] = {
4081-
llvm::ConstantInt::get(CGM.Int32Ty, Devices.size()),
4082-
llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
4083-
DeviceImages, Index),
4084-
HostEntriesBegin, HostEntriesEnd};
4085-
std::string Descriptor = getName({"omp_offloading", "descriptor"});
4086-
llvm::GlobalVariable *Desc = createGlobalStruct(
4087-
CGM, getTgtBinaryDescriptorQTy(), /*IsConstant=*/true, Data, Descriptor);
4088-
4089-
// Emit code to register or unregister the descriptor at execution
4090-
// startup or closing, respectively.
4091-
4092-
llvm::Function *UnRegFn;
4093-
{
4094-
FunctionArgList Args;
4095-
ImplicitParamDecl DummyPtr(C, C.VoidPtrTy, ImplicitParamDecl::Other);
4096-
Args.push_back(&DummyPtr);
4097-
4098-
CodeGenFunction CGF(CGM);
4099-
// Disable debug info for global (de-)initializer because they are not part
4100-
// of some particular construct.
4101-
CGF.disableDebugInfo();
4102-
const auto &FI =
4103-
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
4104-
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
4105-
std::string UnregName = getName({"omp_offloading", "descriptor_unreg"});
4106-
UnRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, UnregName, FI);
4107-
CGF.StartFunction(GlobalDecl(), C.VoidTy, UnRegFn, FI, Args);
4108-
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_unregister_lib),
4109-
Desc);
4110-
CGF.FinishFunction();
4111-
}
4112-
llvm::Function *RegFn;
4113-
{
4114-
CodeGenFunction CGF(CGM);
4115-
// Disable debug info for global (de-)initializer because they are not part
4116-
// of some particular construct.
4117-
CGF.disableDebugInfo();
4118-
const auto &FI = CGM.getTypes().arrangeNullaryFunction();
4119-
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
4120-
4121-
// Encode offload target triples into the registration function name. It
4122-
// will serve as a comdat key for the registration/unregistration code for
4123-
// this particular combination of offloading targets.
4124-
SmallVector<StringRef, 4U> RegFnNameParts(Devices.size() + 2U);
4125-
RegFnNameParts[0] = "omp_offloading";
4126-
RegFnNameParts[1] = "descriptor_reg";
4127-
llvm::transform(Devices, std::next(RegFnNameParts.begin(), 2),
4128-
[](const llvm::Triple &T) -> const std::string& {
4129-
return T.getTriple();
4130-
});
4131-
llvm::sort(std::next(RegFnNameParts.begin(), 2), RegFnNameParts.end());
4132-
std::string Descriptor = getName(RegFnNameParts);
4133-
RegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, Descriptor, FI);
4134-
CGF.StartFunction(GlobalDecl(), C.VoidTy, RegFn, FI, FunctionArgList());
4135-
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_lib), Desc);
4136-
// Create a variable to drive the registration and unregistration of the
4137-
// descriptor, so we can reuse the logic that emits Ctors and Dtors.
4138-
ImplicitParamDecl RegUnregVar(C, C.getTranslationUnitDecl(),
4139-
SourceLocation(), nullptr, C.CharTy,
4140-
ImplicitParamDecl::Other);
4141-
CGM.getCXXABI().registerGlobalDtor(CGF, RegUnregVar, UnRegFn, Desc);
4142-
CGF.FinishFunction();
4143-
}
4144-
if (CGM.supportsCOMDAT()) {
4145-
// It is sufficient to call registration function only once, so create a
4146-
// COMDAT group for registration/unregistration functions and associated
4147-
// data. That would reduce startup time and code size. Registration
4148-
// function serves as a COMDAT group key.
4149-
llvm::Comdat *ComdatKey = M.getOrInsertComdat(RegFn->getName());
4150-
RegFn->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4151-
RegFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
4152-
RegFn->setComdat(ComdatKey);
4153-
UnRegFn->setComdat(ComdatKey);
4154-
DeviceImages->setComdat(ComdatKey);
4155-
Desc->setComdat(ComdatKey);
4156-
}
4157-
return RegFn;
4158-
}
4159-
41604009
void CGOpenMPRuntime::createOffloadEntry(
41614010
llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
41624011
llvm::GlobalValue::LinkageTypes Linkage) {
@@ -4197,8 +4046,9 @@ void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
41974046
// Right now we only generate metadata for function that contain target
41984047
// regions.
41994048

4200-
// If we do not have entries, we don't need to do anything.
4201-
if (OffloadEntriesInfoManager.empty())
4049+
// If we are in simd mode or there are no entries, we don't need to do
4050+
// anything.
4051+
if (CGM.getLangOpts().OpenMPSimd || OffloadEntriesInfoManager.empty())
42024052
return;
42034053

42044054
llvm::Module &M = CGM.getModule();
@@ -10031,17 +9881,6 @@ llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() {
100319881
return RequiresRegFn;
100329882
}
100339883

10034-
llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
10035-
// If we have offloading in the current module, we need to emit the entries
10036-
// now and register the offloading descriptor.
10037-
createOffloadEntriesAndInfoMetadata();
10038-
10039-
// Create and register the offloading binary descriptors. This is the main
10040-
// entity that captures all the information about offloading in the current
10041-
// compilation unit.
10042-
return createOffloadingBinaryDescriptorRegistration();
10043-
}
10044-
100459884
void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
100469885
const OMPExecutableDirective &D,
100479886
SourceLocation Loc,
@@ -11534,10 +11373,6 @@ bool CGOpenMPSIMDRuntime::emitTargetGlobal(GlobalDecl GD) {
1153411373
return false;
1153511374
}
1153611375

11537-
llvm::Function *CGOpenMPSIMDRuntime::emitRegistrationFunction() {
11538-
return nullptr;
11539-
}
11540-
1154111376
void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
1154211377
const OMPExecutableDirective &D,
1154311378
SourceLocation Loc,

‎clang/lib/CodeGen/CGOpenMPRuntime.h

+3-17
Original file line numberDiff line numberDiff line change
@@ -672,14 +672,6 @@ class CGOpenMPRuntime {
672672
/// Device routines are specific to the
673673
bool HasEmittedDeclareTargetRegion = false;
674674

675-
/// Creates and registers offloading binary descriptor for the current
676-
/// compilation unit. The function that does the registration is returned.
677-
llvm::Function *createOffloadingBinaryDescriptorRegistration();
678-
679-
/// Creates all the offload entries in the current compilation unit
680-
/// along with the associated metadata.
681-
void createOffloadEntriesAndInfoMetadata();
682-
683675
/// Loads all the offload entries information from the host IR
684676
/// metadata.
685677
void loadOffloadInfoMetadata();
@@ -1492,10 +1484,9 @@ class CGOpenMPRuntime {
14921484
/// requires directives was used in the current module.
14931485
llvm::Function *emitRequiresDirectiveRegFun();
14941486

1495-
/// Creates the offloading descriptor in the event any target region
1496-
/// was emitted in the current module and return the function that registers
1497-
/// it.
1498-
virtual llvm::Function *emitRegistrationFunction();
1487+
/// Creates all the offload entries in the current compilation unit
1488+
/// along with the associated metadata.
1489+
void createOffloadEntriesAndInfoMetadata();
14991490

15001491
/// Emits code for teams call of the \a OutlinedFn with
15011492
/// variables captured in a record which address is stored in \a
@@ -2167,11 +2158,6 @@ class CGOpenMPSIMDRuntime final : public CGOpenMPRuntime {
21672158
/// \param GD Global to scan.
21682159
bool emitTargetGlobal(GlobalDecl GD) override;
21692160

2170-
/// Creates the offloading descriptor in the event any target region
2171-
/// was emitted in the current module and return the function that registers
2172-
/// it.
2173-
llvm::Function *emitRegistrationFunction() override;
2174-
21752161
/// Emits code for teams call of the \a OutlinedFn with
21762162
/// variables captured in a record which address is stored in \a
21772163
/// CapturedStruct.

‎clang/lib/CodeGen/CodeGenModule.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,7 @@ void CodeGenModule::Release() {
414414
OpenMPRuntime->emitRequiresDirectiveRegFun()) {
415415
AddGlobalCtor(OpenMPRequiresDirectiveRegFun, 0);
416416
}
417-
if (llvm::Function *OpenMPRegistrationFunction =
418-
OpenMPRuntime->emitRegistrationFunction()) {
419-
auto ComdatKey = OpenMPRegistrationFunction->hasComdat() ?
420-
OpenMPRegistrationFunction : nullptr;
421-
AddGlobalCtor(OpenMPRegistrationFunction, 0, ComdatKey);
422-
}
417+
OpenMPRuntime->createOffloadEntriesAndInfoMetadata();
423418
OpenMPRuntime->clear();
424419
}
425420
if (PGOReader) {

‎clang/lib/Driver/ToolChains/Clang.cpp

+3-27
Original file line numberDiff line numberDiff line change
@@ -6418,30 +6418,6 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
64186418
CmdArgs.push_back("-target");
64196419
CmdArgs.push_back(Args.MakeArgString(Triple.getTriple()));
64206420

6421-
assert(JA.getInputs().size() == Inputs.size() &&
6422-
"Not have inputs for all dependence actions??");
6423-
6424-
// Add offload targets. It is a comma-separated list of offload target
6425-
// triples.
6426-
SmallString<128> Targets;
6427-
Targets += "-offload-targets=";
6428-
for (unsigned I = 0; I < Inputs.size(); ++I) {
6429-
if (I)
6430-
Targets += ',';
6431-
6432-
// Get input's Offload Kind and ToolChain.
6433-
const auto *OA = cast<OffloadAction>(JA.getInputs()[I]);
6434-
assert(OA->hasSingleDeviceDependence(/*DoNotConsiderHostActions=*/true) &&
6435-
"Expected one device dependence!");
6436-
const ToolChain *DeviceTC = nullptr;
6437-
OA->doOnEachDependence([&DeviceTC](Action *, const ToolChain *TC,
6438-
const char *) { DeviceTC = TC; });
6439-
6440-
// And add it to the offload targets.
6441-
Targets += DeviceTC->getTriple().normalize();
6442-
}
6443-
CmdArgs.push_back(Args.MakeArgString(Targets));
6444-
64456421
// Add the output file name.
64466422
assert(Output.isFilename() && "Invalid output.");
64476423
CmdArgs.push_back("-o");
@@ -6454,7 +6430,7 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
64546430
}
64556431

64566432
C.addCommand(std::make_unique<Command>(
6457-
JA, *this,
6458-
Args.MakeArgString(getToolChain().GetProgramPath(getShortName())),
6459-
CmdArgs, Inputs));
6433+
JA, *this,
6434+
Args.MakeArgString(getToolChain().GetProgramPath(getShortName())),
6435+
CmdArgs, Inputs));
64606436
}

‎clang/test/Driver/clang-offload-wrapper.c

+31-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
// RUN: clang-offload-wrapper --help | FileCheck %s --check-prefix CHECK-HELP
77
// CHECK-HELP: {{.*}}OVERVIEW: A tool to create a wrapper bitcode for offload target binaries. Takes offload
88
// CHECK-HELP: {{.*}}target binaries as input and produces bitcode file containing target binaries packaged
9-
// CHECK-HELP: {{.*}}as data.
9+
// CHECK-HELP: {{.*}}as data and initialization code which registers target binaries in offload runtime.
1010
// CHECK-HELP: {{.*}}USAGE: clang-offload-wrapper [options] <input files>
1111
// CHECK-HELP: {{.*}} -o=<filename> - Output filename
12-
// CHECK-HELP: {{.*}} --offload-targets=<triples> - Comma-separated list of device target triples
1312
// CHECK-HELP: {{.*}} --target=<triple> - Target triple for the output module
1413

1514
//
@@ -20,10 +19,37 @@
2019
//
2120
// Check bitcode produced by the wrapper tool.
2221
//
23-
// RUN: clang-offload-wrapper -target=x86_64-pc-linux-gnu -offload-targets=powerpc64le-ibm-linux-gnu -o %t.wrapper.bc %t.tgt
22+
// RUN: clang-offload-wrapper -target=x86_64-pc-linux-gnu -o %t.wrapper.bc %t.tgt
2423
// RUN: llvm-dis %t.wrapper.bc -o - | FileCheck %s --check-prefix CHECK-IR
2524

2625
// CHECK-IR: target triple = "x86_64-pc-linux-gnu"
2726

28-
// CHECK-IR: @.omp_offloading.img_start.powerpc64le-ibm-linux-gnu = hidden unnamed_addr constant [{{[0-9]+}} x i8] c"Content of device file{{.+}}", section ".omp_offloading.powerpc64le-ibm-linux-gnu"
29-
// CHECK-IR: @.omp_offloading.img_end.powerpc64le-ibm-linux-gnu = hidden unnamed_addr constant [0 x i8] zeroinitializer, section ".omp_offloading.powerpc64le-ibm-linux-gnu"
27+
// CHECK-IR-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
28+
// CHECK-IR-DAG: [[IMAGETY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
29+
// CHECK-IR-DAG: [[DESCTY:%.+]] = type { i32, [[IMAGETY]]*, [[ENTTY]]*, [[ENTTY]]* }
30+
31+
// CHECK-IR: [[ENTBEGIN:@.+]] = external hidden constant [[ENTTY]]
32+
// CHECK-IR: [[ENTEND:@.+]] = external hidden constant [[ENTTY]]
33+
34+
// CHECK-IR: [[DUMMY:@.+]] = hidden constant [0 x %__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries"
35+
36+
// CHECK-IR: [[BIN:@.+]] = internal unnamed_addr constant [[BINTY:\[[0-9]+ x i8\]]] c"Content of device file{{.+}}"
37+
38+
// CHECK-IR: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[IMAGETY]]] [{{.+}} { i8* getelementptr inbounds ([[BINTY]], [[BINTY]]* [[BIN]], i64 0, i64 0), i8* getelementptr inbounds ([[BINTY]], [[BINTY]]* [[BIN]], i64 1, i64 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }]
39+
40+
// CHECK-IR: [[DESC:@.+]] = internal constant [[DESCTY]] { i32 1, [[IMAGETY]]* getelementptr inbounds ([1 x [[IMAGETY]]], [1 x [[IMAGETY]]]* [[IMAGES]], i64 0, i64 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }
41+
42+
// CHECK-IR: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[REGFN:@.+]], i8* null }]
43+
// CHECK-IR: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* [[UNREGFN:@.+]], i8* null }]
44+
45+
// CHECK-IR: define internal void [[REGFN]]()
46+
// CHECK-IR: call void @__tgt_register_lib([[DESCTY]]* [[DESC]])
47+
// CHECK-IR: ret void
48+
49+
// CHECK-IR: declare void @__tgt_register_lib([[DESCTY]]*)
50+
51+
// CHECK-IR: define internal void [[UNREGFN]]()
52+
// CHECK-IR: call void @__tgt_unregister_lib([[DESCTY]]* [[DESC]])
53+
// CHECK-IR: ret void
54+
55+
// CHECK-IR: declare void @__tgt_unregister_lib([[DESCTY]]*)

‎clang/test/OpenMP/openmp_offload_registration.cpp

+1-31
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,9 @@ void foo() {
88
}
99

1010
// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
11-
// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
12-
// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
13-
14-
// Comdat key for the offload registration code. Should have sorted offload
15-
// target triples encoded into the name.
16-
// CHECK-DAG: $[[REGFN:\.omp_offloading\..+\.powerpc64le-ibm-linux-gnu\.x86_64-pc-linux-gnu+]] = comdat any
17-
18-
// Check if offloading descriptor is created.
19-
// CHECK: [[ENTBEGIN:@.+]] = external hidden constant [[ENTTY]]
20-
// CHECK: [[ENTEND:@.+]] = external hidden constant [[ENTTY]]
21-
// CHECK: [[DEV1BEGIN:@.+]] = extern_weak constant i8
22-
// CHECK: [[DEV1END:@.+]] = extern_weak constant i8
23-
// CHECK: [[DEV2BEGIN:@.+]] = extern_weak constant i8
24-
// CHECK: [[DEV2END:@.+]] = extern_weak constant i8
25-
// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [2 x [[DEVTY]]] [{{.+}} { i8* [[DEV1BEGIN]], i8* [[DEV1END]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, {{.+}} { i8* [[DEV2BEGIN]], i8* [[DEV2END]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
26-
// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 2, [[DEVTY]]* getelementptr inbounds ([2 x [[DEVTY]]], [2 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
2711

2812
// Check target registration is registered as a Ctor.
29-
// CHECK: appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @.omp_offloading.requires_reg, i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @[[REGFN]], i8* bitcast (void ()* @[[REGFN]] to i8*) }]
13+
// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @.omp_offloading.requires_reg, i8* null }]
3014

3115
// Check presence of foo() and the outlined target region
3216
// CHECK: define void [[FOO:@.+]]()
@@ -37,17 +21,3 @@ void foo() {
3721
// CHECK: define internal void @.omp_offloading.requires_reg()
3822
// CHECK: call void @__tgt_register_requires(i64 1)
3923
// CHECK: ret void
40-
41-
// CHECK: define internal void @[[UNREGFN:.+]](i8* %0)
42-
// CHECK-SAME: comdat($[[REGFN]]) {
43-
// CHECK: call i32 @__tgt_unregister_lib([[DSCTY]]* [[DESC]])
44-
// CHECK: ret void
45-
// CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*)
46-
47-
// CHECK: define linkonce hidden void @[[REGFN]]()
48-
// CHECK-SAME: comdat {
49-
// CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]])
50-
// CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*),
51-
// CHECK: ret void
52-
// CHECK: declare i32 @__tgt_register_lib([[DSCTY]]*)
53-

0 commit comments

Comments
 (0)
Please sign in to comment.