Skip to content

[sycl-post-link][NFC] Extracted the code into a subroutine #3042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 18, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 89 additions & 74 deletions llvm/tools/sycl-post-link/sycl-post-link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,91 @@ static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists) {
} \
}

static int processOneModule(std::unique_ptr<Module> M,
util::SimpleTable &Table) {
std::map<StringRef, std::vector<Function *>> GlobalsSet;

bool DoSplit = SplitMode.getNumOccurrences() > 0;
bool DoSpecConst = SpecConstLower.getNumOccurrences() > 0;

if (DoSplit || DoSymGen) {
KernelMapEntryScope Scope = Scope_Global;
if (DoSplit) {
if (SplitMode == SPLIT_AUTO)
Scope = selectDeviceCodeSplitScopeAutomatically(*M);
else
Scope =
SplitMode == SPLIT_PER_KERNEL ? Scope_PerKernel : Scope_PerModule;
}
collectKernelModuleMap(*M, GlobalsSet, Scope);
}

std::vector<std::unique_ptr<Module>> ResultModules;
string_vector ResultSymbolsLists;

bool SpecConstsMet = false;
bool SetSpecConstAtRT = DoSpecConst && (SpecConstLower == SC_USE_RT_VAL);

if (DoSpecConst) {
// perform the spec constant intrinsics transformation and enumeration on
// the whole module
ModulePassManager RunSpecConst;
ModuleAnalysisManager MAM;
SpecConstantsPass SCP(SetSpecConstAtRT);
// Register required analysis
MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
RunSpecConst.addPass(SCP);
if (!DoSplit)
// This pass deletes unreachable globals. Code splitter runs it later.
RunSpecConst.addPass(GlobalDCEPass());
PreservedAnalyses Res = RunSpecConst.run(*M, MAM);
SpecConstsMet = !Res.areAllPreserved();
}
if (IROutputOnly) {
// the result is the transformed input LLVMIR file rather than a file table
saveModule(*M, OutputFilename);
return 0;
}
if (DoSplit) {
splitModule(*M, GlobalsSet, ResultModules);
// post-link always produces a code result, even if it is unmodified input
if (ResultModules.size() == 0)
ResultModules.push_back(std::move(M));
} else
ResultModules.push_back(std::move(M));

{
// reuse input module if there were no spec constants and no splitting
string_vector Files = SpecConstsMet || (ResultModules.size() > 1)
? saveResultModules(ResultModules)
: string_vector{InputFilename};
// "Code" column is always output
Error Err = Table.addColumn(COL_CODE, Files);
CHECK_AND_EXIT(Err);
}

{
ImagePropSaveInfo ImgPSInfo = {true, DoSpecConst, SetSpecConstAtRT,
SpecConstsMet, EmitKernelParamInfo};
string_vector Files = saveDeviceImageProperty(ResultModules, ImgPSInfo);
Error Err = Table.addColumn(COL_PROPS, Files);
CHECK_AND_EXIT(Err);
}
if (DoSymGen) {
// extract symbols per each module
collectSymbolsLists(GlobalsSet, ResultSymbolsLists);
if (ResultSymbolsLists.empty()) {
// push empty symbols list for consistency
assert(ResultModules.size() == 1);
ResultSymbolsLists.push_back("");
}
string_vector Files = saveResultSymbolsLists(ResultSymbolsLists);
Error Err = Table.addColumn(COL_SYM, Files);
CHECK_AND_EXIT(Err);
}
return 0;
}

int main(int argc, char **argv) {
InitLLVM X{argc, argv};

Expand Down Expand Up @@ -704,84 +789,14 @@ int main(int argc, char **argv) {
if (OutputFilename.getNumOccurrences() == 0)
OutputFilename = (Twine(sys::path::stem(InputFilename)) + ".files").str();

std::map<StringRef, std::vector<Function *>> GlobalsSet;

if (DoSplit || DoSymGen) {
KernelMapEntryScope Scope = Scope_Global;
if (DoSplit) {
if (SplitMode == SPLIT_AUTO)
Scope = selectDeviceCodeSplitScopeAutomatically(*MPtr);
else
Scope =
SplitMode == SPLIT_PER_KERNEL ? Scope_PerKernel : Scope_PerModule;
}
collectKernelModuleMap(*MPtr, GlobalsSet, Scope);
}

std::vector<std::unique_ptr<Module>> ResultModules;
string_vector ResultSymbolsLists;

util::SimpleTable Table;
bool SpecConstsMet = false;
bool SetSpecConstAtRT = DoSpecConst && (SpecConstLower == SC_USE_RT_VAL);
int Res = processOneModule(std::move(M), Table);
if (Res)
return Res;

if (DoSpecConst) {
// perform the spec constant intrinsics transformation and enumeration on
// the whole module
ModulePassManager RunSpecConst;
ModuleAnalysisManager MAM;
SpecConstantsPass SCP(SetSpecConstAtRT);
// Register required analysis
MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
RunSpecConst.addPass(SCP);
if (!DoSplit)
// This pass deletes unreachable globals. Code splitter runs it later.
RunSpecConst.addPass(GlobalDCEPass());
PreservedAnalyses Res = RunSpecConst.run(*MPtr, MAM);
SpecConstsMet = !Res.areAllPreserved();
}
if (IROutputOnly) {
// the result is the transformed input LLVMIR file rather than a file table
saveModule(*MPtr, OutputFilename);
if (IROutputOnly)
return 0;
}
if (DoSplit) {
splitModule(*MPtr, GlobalsSet, ResultModules);
// post-link always produces a code result, even if it is unmodified input
if (ResultModules.size() == 0)
ResultModules.push_back(std::move(M));
} else
ResultModules.push_back(std::move(M));

{
// reuse input module if there were no spec constants and no splitting
string_vector Files = SpecConstsMet || (ResultModules.size() > 1)
? saveResultModules(ResultModules)
: string_vector{InputFilename};
// "Code" column is always output
Error Err = Table.addColumn(COL_CODE, Files);
CHECK_AND_EXIT(Err);
}

{
ImagePropSaveInfo ImgPSInfo = {true, DoSpecConst, SetSpecConstAtRT,
SpecConstsMet, EmitKernelParamInfo};
string_vector Files = saveDeviceImageProperty(ResultModules, ImgPSInfo);
Error Err = Table.addColumn(COL_PROPS, Files);
CHECK_AND_EXIT(Err);
}
if (DoSymGen) {
// extract symbols per each module
collectSymbolsLists(GlobalsSet, ResultSymbolsLists);
if (ResultSymbolsLists.empty()) {
// push empty symbols list for consistency
assert(ResultModules.size() == 1);
ResultSymbolsLists.push_back("");
}
string_vector Files = saveResultSymbolsLists(ResultSymbolsLists);
Error Err = Table.addColumn(COL_SYM, Files);
CHECK_AND_EXIT(Err);
}
{
std::error_code EC;
raw_fd_ostream Out{OutputFilename, EC, sys::fs::OF_None};
Expand Down