Skip to content

Commit 0b6c9c7

Browse files
Fixed code review comments:
1. Check call graph deps in all added tests. 2. Changed signature of makeResultFileName: replaced `bool IsEsimd` flag with `StringRef suffix`. 3. Added -split-esimd option to control SYCL-ESIMD splitting. 4. The new -split-esimd options is not compatible with -ir-output-only. 5. Added a test that checks that SYCL-ESIMD splitting doesn't happen when no '-split-esimd' option provided.
1 parent 016bcc5 commit 0b6c9c7

File tree

6 files changed

+154
-78
lines changed

6 files changed

+154
-78
lines changed

llvm/test/tools/sycl-post-link/sycl-esimd/basic-sycl-esimd-split.ll

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: sycl-post-link -split=auto -S %s -o %t.table
1+
; RUN: sycl-post-link -split-esimd -S %s -o %t.table
22
; RUN: FileCheck %s -input-file=%t.table
33
; RUN: FileCheck %s -input-file=%t_0.ll --check-prefixes CHECK-SYCL-IR
44
; RUN: FileCheck %s -input-file=%t_esimd_0.ll --check-prefixes CHECK-ESIMD-IR
@@ -17,14 +17,13 @@ entry:
1717
ret void
1818
}
1919

20-
define dso_local spir_kernel void @SYCL_kernel() #1 {
20+
define dso_local spir_kernel void @SYCL_kernel() #0 {
2121
entry:
2222
%call = tail call spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
2323
ret void
2424
}
2525

2626
attributes #0 = { "sycl-module-id"="a.cpp" }
27-
attributes #1 = { "sycl-module-id"="a.cpp" }
2827

2928
!llvm.module.flags = !{!0}
3029
!opencl.spir.version = !{!1}
@@ -39,6 +38,8 @@ attributes #1 = { "sycl-module-id"="a.cpp" }
3938
; CHECK: {{.*}}_0.ll|{{.*}}_0.prop
4039
; CHECK: {{.*}}_esimd_0.ll|{{.*}}_esimd_0.prop
4140

42-
; CHECK-SYCL-IR: define dso_local spir_kernel void @SYCL_kernel()
41+
; CHECK-SYCL-IR-DAG: define dso_local spir_kernel void @SYCL_kernel()
42+
; CHECK-SYCL-IR-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
4343

44-
; CHECK-ESIMD-IR: define dso_local spir_kernel void @ESIMD_kernel()
44+
; CHECK-ESIMD-IR-DAG: define dso_local spir_kernel void @ESIMD_kernel()
45+
; CHECK-ESIMD-IR-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
; RUN: sycl-post-link -split=source -S %s -o %t.table
2+
; RUN: FileCheck %s -input-file=%t.table
3+
; RUN: FileCheck %s -input-file=%t_0.ll --check-prefixes CHECK-IR-0
4+
; RUN: FileCheck %s -input-file=%t_1.ll --check-prefixes CHECK-IR-1
5+
6+
; This test checks that if no '-split-esimd' provided, ther is no
7+
; splitting of SYCL and ESIMD kernels into separate modules.
8+
; However, the rest of the splitting still happens according to
9+
; the '-split=' option.
10+
11+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
12+
target triple = "spir64-unknown-linux-sycldevice"
13+
14+
declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
15+
16+
define dso_local spir_kernel void @ESIMD_kernel() #0 !sycl_explicit_simd !3{
17+
entry:
18+
%call = tail call spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
19+
ret void
20+
}
21+
22+
define dso_local spir_kernel void @SYCL_kernel1() #0 {
23+
entry:
24+
%call = tail call spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
25+
ret void
26+
}
27+
28+
define dso_local spir_kernel void @SYCL_kernel2() #1 {
29+
entry:
30+
%call = tail call spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
31+
ret void
32+
}
33+
34+
attributes #0 = { "sycl-module-id"="a.cpp" }
35+
attributes #1 = { "sycl-module-id"="b.cpp" }
36+
37+
!llvm.module.flags = !{!0}
38+
!opencl.spir.version = !{!1}
39+
!spirv.Source = !{!2}
40+
41+
!0 = !{i32 1, !"wchar_size", i32 4}
42+
!1 = !{i32 1, i32 2}
43+
!2 = !{i32 0, i32 100000}
44+
!3 = !{}
45+
46+
; CHECK: [Code|Properties]
47+
; CHECK: {{.*}}_0.ll|{{.*}}_0.prop
48+
; CHECK: {{.*}}_1.ll|{{.*}}_1.prop
49+
50+
; CHECK-IR-0-DAG: define dso_local spir_kernel void @SYCL_kernel1()
51+
; CHECK-IR-0-DAG: define dso_local spir_kernel void @ESIMD_kernel()
52+
; CHECK-IR-0-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
53+
54+
; CHECK-IR-1-DAG: define dso_local spir_kernel void @SYCL_kernel2()
55+
; CHECK-IR-1-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()

llvm/test/tools/sycl-post-link/sycl-esimd/sycl-esimd-split-per-kernel.ll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: sycl-post-link -split=kernel -S %s -o %t.table
1+
; RUN: sycl-post-link -split-esimd -split=kernel -S %s -o %t.table
22
; RUN: FileCheck %s -input-file=%t.table
33
; RUN: FileCheck %s -input-file=%t_0.ll --check-prefixes CHECK-SYCL-IR-0
44
; RUN: FileCheck %s -input-file=%t_1.ll --check-prefixes CHECK-SYCL-IR-1
@@ -57,8 +57,14 @@ attributes #1 = { "sycl-module-id"="a.cpp" }
5757
; CHECK: {{.*}}_esimd_0.ll|{{.*}}_esimd_0.prop
5858
; CHECK: {{.*}}_esimd_1.ll|{{.*}}_esimd_1.prop
5959

60-
; CHECK-SYCL-IR-0: define dso_local spir_kernel void @SYCL_kernel1()
61-
; CHECK-SYCL-IR-1: define dso_local spir_kernel void @SYCL_kernel2()
60+
; CHECK-SYCL-IR-0-DAG: define dso_local spir_kernel void @SYCL_kernel1()
61+
; CHECK-SYCL-IR-0-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
6262

63-
; CHECK-ESIMD-IR-0: define dso_local spir_kernel void @ESIMD_kernel1()
64-
; CHECK-ESIMD-IR-1: define dso_local spir_kernel void @ESIMD_kernel2()
63+
; CHECK-SYCL-IR-1-DAG: define dso_local spir_kernel void @SYCL_kernel2()
64+
; CHECK-SYCL-IR-1-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
65+
66+
; CHECK-ESIMD-IR-0-DAG: define dso_local spir_kernel void @ESIMD_kernel1()
67+
; CHECK-ESIMD-IR-0-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
68+
69+
; CHECK-ESIMD-IR-1-DAG: define dso_local spir_kernel void @ESIMD_kernel2()
70+
; CHECK-ESIMD-IR-1-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()

llvm/test/tools/sycl-post-link/sycl-esimd/sycl-esimd-split-per-source.ll

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: sycl-post-link -split=source -S %s -o %t.table
1+
; RUN: sycl-post-link -split-esimd -split=source -S %s -o %t.table
22
; RUN: FileCheck %s -input-file=%t.table
33
; RUN: FileCheck %s -input-file=%t_0.ll --check-prefixes CHECK-SYCL-IR-0
44
; RUN: FileCheck %s -input-file=%t_1.ll --check-prefixes CHECK-SYCL-IR-1
@@ -71,10 +71,16 @@ attributes #1 = { "sycl-module-id"="b.cpp" }
7171
; CHECK: {{.*}}_esimd_0.ll|{{.*}}_esimd_0.prop
7272
; CHECK: {{.*}}_esimd_1.ll|{{.*}}_esimd_1.prop
7373

74-
; CHECK-SYCL-IR-0: define dso_local spir_kernel void @SYCL_kernel1()
75-
; CHECK-SYCL-IR-0: define dso_local spir_kernel void @SYCL_kernel2()
76-
; CHECK-SYCL-IR-1: define dso_local spir_kernel void @SYCL_kernel3()
74+
; CHECK-SYCL-IR-0-DAG: define dso_local spir_kernel void @SYCL_kernel1()
75+
; CHECK-SYCL-IR-0-DAG: define dso_local spir_kernel void @SYCL_kernel2()
76+
; CHECK-SYCL-IR-0-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
7777

78-
; CHECK-ESIMD-IR-0: define dso_local spir_kernel void @ESIMD_kernel1()
79-
; CHECK-ESIMD-IR-0: define dso_local spir_kernel void @ESIMD_kernel2()
80-
; CHECK-ESIMD-IR-1: define dso_local spir_kernel void @ESIMD_kernel3()
78+
; CHECK-SYCL-IR-1-DAG: define dso_local spir_kernel void @SYCL_kernel3()
79+
; CHECK-SYCL-IR-1-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
80+
81+
; CHECK-ESIMD-IR-0-DAG: define dso_local spir_kernel void @ESIMD_kernel1()
82+
; CHECK-ESIMD-IR-0-DAG: define dso_local spir_kernel void @ESIMD_kernel2()
83+
; CHECK-ESIMD-IR-0-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()
84+
85+
; CHECK-ESIMD-IR-1-DAG: define dso_local spir_kernel void @ESIMD_kernel3()
86+
; CHECK-ESIMD-IR-1-DAG: declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv()

llvm/test/tools/sycl-post-link/sycl-esimd/sycl-esimd-split-symbols.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: sycl-post-link -symbols -S %s -o %t.table
1+
; RUN: sycl-post-link -split-esimd -symbols -S %s -o %t.table
22
; RUN: FileCheck %s -input-file=%t.table
33
; RUN: FileCheck %s -input-file=%t_0.sym --check-prefixes CHECK-SYCL-SYM
44
; RUN: FileCheck %s -input-file=%t_esimd_0.sym --check-prefixes CHECK-ESIMD-SYM

llvm/tools/sycl-post-link/sycl-post-link.cpp

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ static cl::opt<bool> OutputAssembly{"S",
8888
cl::desc("Write output as LLVM assembly"),
8989
cl::Hidden, cl::cat(PostLinkCat)};
9090

91+
static cl::opt<bool> SplitEsimd{"split-esimd",
92+
cl::desc("Split SYCL and ESIMD kernels"),
93+
cl::cat(PostLinkCat)};
94+
9195
enum IRSplitMode {
9296
SPLIT_PER_TU, // one module per translation unit
9397
SPLIT_PER_KERNEL, // one module per kernel
@@ -446,18 +450,16 @@ splitModule(Module &M,
446450
}
447451
}
448452

449-
static std::string makeResultFileName(Twine Ext, int I, bool IsEsimd) {
453+
static std::string makeResultFileName(Twine Ext, int I, StringRef Suffix) {
450454
const StringRef Dir0 = OutputDir.getNumOccurrences() > 0
451455
? OutputDir
452456
: sys::path::parent_path(OutputFilename);
453457
const StringRef Sep = sys::path::get_separator();
454458
std::string Dir = Dir0.str();
455459
if (!Dir0.empty() && !Dir0.endswith(Sep))
456460
Dir += Sep.str();
457-
std::string RetStr = Dir + sys::path::stem(OutputFilename).str() + "_";
458-
if (IsEsimd)
459-
RetStr += "esimd_";
460-
return RetStr + std::to_string(I) + Ext.str();
461+
return Dir + sys::path::stem(OutputFilename).str() + "_" + Suffix.str() +
462+
std::to_string(I) + Ext.str();
461463
}
462464

463465
static void saveModule(Module &M, StringRef OutFilename) {
@@ -479,13 +481,13 @@ static void saveModule(Module &M, StringRef OutFilename) {
479481
// Saves file list if user specified corresponding filename.
480482
static string_vector
481483
saveResultModules(std::vector<std::unique_ptr<Module>> &ResModules,
482-
bool IsEsimd) {
484+
StringRef Suffix) {
483485
string_vector Res;
484486

485487
for (size_t I = 0; I < ResModules.size(); ++I) {
486488
std::error_code EC;
487489
StringRef FileExt = (OutputAssembly) ? ".ll" : ".bc";
488-
std::string CurOutFileName = makeResultFileName(FileExt, I, IsEsimd);
490+
std::string CurOutFileName = makeResultFileName(FileExt, I, Suffix);
489491
saveModule(*ResModules[I].get(), CurOutFileName);
490492
Res.emplace_back(std::move(CurOutFileName));
491493
}
@@ -586,7 +588,7 @@ static string_vector saveDeviceImageProperty(
586588
}
587589
std::error_code EC;
588590
std::string SCFile =
589-
makeResultFileName(".prop", I, ImgPSInfo.IsEsimdKernel);
591+
makeResultFileName(".prop", I, ImgPSInfo.IsEsimdKernel ? "esimd_" : "");
590592
raw_fd_ostream SCOut(SCFile, EC);
591593
PropSet.write(SCOut);
592594
Res.emplace_back(std::move(SCFile));
@@ -598,12 +600,12 @@ static string_vector saveDeviceImageProperty(
598600
// Saves specified collection of symbols lists to files.
599601
// Saves file list if user specified corresponding filename.
600602
static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists,
601-
bool IsEsimd) {
603+
StringRef Suffix) {
602604
string_vector Res;
603605

604606
std::string TxtFilesList;
605607
for (size_t I = 0; I < ResSymbolsLists.size(); ++I) {
606-
std::string CurOutFileName = makeResultFileName(".sym", I, IsEsimd);
608+
std::string CurOutFileName = makeResultFileName(".sym", I, Suffix);
607609
writeToFile(CurOutFileName, ResSymbolsLists[I]);
608610
Res.emplace_back(std::move(CurOutFileName));
609611
}
@@ -682,7 +684,7 @@ static TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
682684
// reuse input module if there were no spec constants and no splitting
683685
string_vector Files =
684686
SpecConstsMet || (ResultModules.size() > 1) || SyclAndEsimdKernels
685-
? saveResultModules(ResultModules, IsEsimd)
687+
? saveResultModules(ResultModules, IsEsimd ? "esimd_" : "")
686688
: string_vector{InputFilename};
687689
// "Code" column is always output
688690
std::copy(Files.begin(), Files.end(),
@@ -696,7 +698,6 @@ static TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
696698
string_vector Files = saveDeviceImageProperty(ResultModules, ImgPSInfo);
697699
std::copy(Files.begin(), Files.end(),
698700
std::back_inserter(TblFiles[COL_PROPS]));
699-
700701
}
701702
if (DoSymGen) {
702703
// extract symbols per each module
@@ -706,7 +707,8 @@ static TableFiles processOneModule(std::unique_ptr<Module> M, bool IsEsimd,
706707
assert(ResultModules.size() == 1);
707708
ResultSymbolsLists.push_back("");
708709
}
709-
string_vector Files = saveResultSymbolsLists(ResultSymbolsLists, IsEsimd);
710+
string_vector Files =
711+
saveResultSymbolsLists(ResultSymbolsLists, IsEsimd ? "esimd_" : "");
710712
std::copy(Files.begin(), Files.end(),
711713
std::back_inserter(TblFiles[COL_SYM]));
712714
}
@@ -750,6 +752,36 @@ static ModulePair splitSyclEsimd(std::unique_ptr<Module> M) {
750752
std::move(ResultModules[1]));
751753
}
752754

755+
static TableFiles processInputModule(std::unique_ptr<Module> M) {
756+
if (!SplitEsimd)
757+
return processOneModule(std::move(M), false, false);
758+
759+
std::unique_ptr<Module> SyclModule;
760+
std::unique_ptr<Module> EsimdModule;
761+
std::tie(SyclModule, EsimdModule) = splitSyclEsimd(std::move(M));
762+
763+
// Do we have both Sycl and Esimd kernels?
764+
bool SyclAndEsimdKernels = SyclModule && EsimdModule;
765+
766+
TableFiles SyclTblFiles =
767+
processOneModule(std::move(SyclModule), false, SyclAndEsimdKernels);
768+
TableFiles EsimdTblFiles =
769+
processOneModule(std::move(EsimdModule), true, SyclAndEsimdKernels);
770+
771+
// Merge the two resulting file maps
772+
TableFiles MergedTblFiles;
773+
for (auto &ColumnStr : {COL_CODE, COL_PROPS, COL_SYM}) {
774+
auto &SyclFiles = SyclTblFiles[ColumnStr];
775+
auto &EsimdFiles = EsimdTblFiles[ColumnStr];
776+
auto &MergedFiles = MergedTblFiles[ColumnStr];
777+
std::copy(SyclFiles.begin(), SyclFiles.end(),
778+
std::back_inserter(MergedFiles));
779+
std::copy(EsimdFiles.begin(), EsimdFiles.end(),
780+
std::back_inserter(MergedFiles));
781+
}
782+
return MergedTblFiles;
783+
}
784+
753785
int main(int argc, char **argv) {
754786
InitLLVM X{argc, argv};
755787

@@ -761,13 +793,19 @@ int main(int argc, char **argv) {
761793
"This is a collection of utilities run on device code's LLVM IR before\n"
762794
"handing off to back-end for further compilation or emitting SPIRV.\n"
763795
"The utilities are:\n"
796+
"- SYCL and ESIMD kernels can be split into separate modules with\n"
797+
" '-split-esimd' option. The option has no effect when there is only\n"
798+
" one type of kernels in the input module.\n"
764799
"- Module splitter to split a big input module into smaller ones.\n"
765800
" Groups kernels using function attribute 'sycl-module-id', i.e.\n"
766801
" kernels with the same values of the 'sycl-module-id' attribute will\n"
767802
" be put into the same module. If -split=kernel option is specified,\n"
768803
" one module per kernel will be emitted.\n"
769804
" '-split=auto' mode automatically selects the best way of splitting\n"
770805
" kernels into modules based on some heuristic.\n"
806+
" The '-split' option is compatible with '-split-esimd'. In this case,\n"
807+
" first input module will be split into SYCL and ESIMD modules. Then\n"
808+
" both modules will be further split according to the '-split' option.\n"
771809
"- If -symbols options is also specified, then for each produced module\n"
772810
" a text file containing names of all spir kernels in it is generated.\n"
773811
"- Specialization constant intrinsic transformer. Replaces symbolic\n"
@@ -792,10 +830,11 @@ int main(int argc, char **argv) {
792830
"than 'auto'.\n");
793831

794832
bool DoSplit = SplitMode.getNumOccurrences() > 0;
833+
bool DoSplitEsimd = SplitEsimd.getNumOccurrences() > 0;
795834
bool DoSpecConst = SpecConstLower.getNumOccurrences() > 0;
796835
bool DoParamInfo = EmitKernelParamInfo.getNumOccurrences() > 0;
797836

798-
if (!DoSplit && !DoSpecConst && !DoSymGen && !DoParamInfo) {
837+
if (!DoSplit && !DoSpecConst && !DoSymGen && !DoParamInfo && !DoSplitEsimd) {
799838
errs() << "no actions specified; try --help for usage info\n";
800839
return 1;
801840
}
@@ -804,6 +843,11 @@ int main(int argc, char **argv) {
804843
<< " can't be used with -" << IROutputOnly.ArgStr << "\n";
805844
return 1;
806845
}
846+
if (IROutputOnly && DoSplitEsimd) {
847+
errs() << "error: -" << SplitEsimd.ArgStr << " can't be used with -"
848+
<< IROutputOnly.ArgStr << "\n";
849+
return 1;
850+
}
807851
if (IROutputOnly && DoSymGen) {
808852
errs() << "error: -" << DoSymGen.ArgStr << " can't be used with -"
809853
<< IROutputOnly.ArgStr << "\n";
@@ -840,58 +884,22 @@ int main(int argc, char **argv) {
840884
if (OutputFilename.getNumOccurrences() == 0)
841885
OutputFilename = (Twine(sys::path::stem(InputFilename)) + ".files").str();
842886

843-
std::unique_ptr<Module> SyclModule;
844-
std::unique_ptr<Module> EsimdModule;
845-
std::tie(SyclModule, EsimdModule) = splitSyclEsimd(std::move(M));
846-
847-
// Do we have both Sycl and Esimd kernels?
848-
bool SyclAndEsimdKernels = SyclModule && EsimdModule;
849-
850-
TableFiles SyclTblFiles =
851-
processOneModule(std::move(SyclModule), false, SyclAndEsimdKernels);
887+
TableFiles TblFiles = processInputModule(std::move(M));
852888

853-
// TODO: Currently -ir-output-only option doesn't work when there is a mix
854-
// of SYCL and ESIMD kernels. The option requires a single LLVM IR output
855-
// file, which we cannot provide since SYCL and ESIMD kernels should always
856-
// be split.
857-
// Today, -ir-output-only is an FPGA use case, while ESIMD kernels only appear
858-
// in programs that run on a GPU, so they are orthogonal. But once there
859-
// would be a use case for -ir-output-only on a module that has SYCL and ESIMD
860-
// code, we need to address it.
889+
// Input module was processed and a single output file was requested.
861890
if (IROutputOnly)
862891
return 0;
863892

864-
TableFiles EsimdTblFiles =
865-
processOneModule(std::move(EsimdModule), true, SyclAndEsimdKernels);
866-
893+
// Populate and emit the resulting table
867894
util::SimpleTable Table;
895+
for (auto &ColumnStr : {COL_CODE, COL_PROPS, COL_SYM})
896+
if (!TblFiles[ColumnStr].empty())
897+
CHECK_AND_EXIT(Table.addColumn(ColumnStr, TblFiles[ColumnStr]));
868898

869-
auto addTableColumn = [&Table, &SyclTblFiles,
870-
&EsimdTblFiles](std::string Str) {
871-
auto &SyclFiles = SyclTblFiles[Str];
872-
auto &EsimdFiles = EsimdTblFiles[Str];
873-
string_vector Files(SyclFiles);
874-
std::copy(EsimdFiles.begin(), EsimdFiles.end(), std::back_inserter(Files));
875-
if (Files.empty())
876-
return 0;
877-
Error Err = Table.addColumn(Str, Files);
878-
CHECK_AND_EXIT(Err);
879-
return 0;
880-
};
881-
882-
int Res;
883-
if ((Res = addTableColumn(COL_CODE)) != 0)
884-
return Res;
885-
if ((Res = addTableColumn(COL_PROPS)) != 0)
886-
return Res;
887-
if ((Res = addTableColumn(COL_SYM)) != 0)
888-
return Res;
899+
std::error_code EC;
900+
raw_fd_ostream Out{OutputFilename, EC, sys::fs::OF_None};
901+
checkError(EC, "error opening file '" + OutputFilename + "'");
902+
Table.write(Out);
889903

890-
{
891-
std::error_code EC;
892-
raw_fd_ostream Out{OutputFilename, EC, sys::fs::OF_None};
893-
checkError(EC, "error opening file '" + OutputFilename + "'");
894-
Table.write(Out);
895-
}
896904
return 0;
897905
}

0 commit comments

Comments
 (0)