Skip to content

Commit 307113e

Browse files
jmmartinezkzhuravl
authored andcommitted
[Comgr][SPIRV][Cache] Support for caching of spirv converstion to bitcode
1 parent 3309e50 commit 307113e

File tree

6 files changed

+210
-28
lines changed

6 files changed

+210
-28
lines changed

amd/comgr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ set(SOURCES
8383
src/comgr-metadata.cpp
8484
src/comgr-objdump.cpp
8585
src/comgr-signal.cpp
86+
src/comgr-spirv-command.cpp
8687
src/comgr-symbol.cpp
8788
src/comgr-symbolizer.cpp
8889
src/time-stat/time-stat.cpp)

amd/comgr/src/comgr-cache-command.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class raw_ostream;
5757
namespace COMGR {
5858
class CachedCommandAdaptor {
5959
public:
60-
using ActionClass = clang::driver::Action::ActionClass;
60+
using ActionClass =
61+
std::underlying_type_t<clang::driver::Action::ActionClass>;
6162
using HashAlgorithm = llvm::SHA256;
6263
using Identifier = llvm::SmallString<64>;
6364

amd/comgr/src/comgr-compiler.cpp

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "comgr-device-libs.h"
4242
#include "comgr-diagnostic-handler.h"
4343
#include "comgr-env.h"
44+
#include "comgr-spirv-command.h"
4445
#include "lld/Common/CommonLinkerContext.h"
4546
#include "lld/Common/Driver.h"
4647
#include "clang/Basic/Version.h"
@@ -85,10 +86,6 @@
8586
#include "llvm/Support/WithColor.h"
8687
#include "llvm/TargetParser/Host.h"
8788

88-
#ifndef COMGR_DISABLE_SPIRV
89-
#include "LLVMSPIRVLib/LLVMSPIRVLib.h"
90-
#endif
91-
9289
#include "time-stat/ts-interface.h"
9390

9491
#include <csignal>
@@ -1903,10 +1900,7 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19031900
return Status;
19041901
}
19051902

1906-
LLVMContext Context;
1907-
Context.setDiagnosticHandler(
1908-
std::make_unique<AMDGPUCompilerDiagnosticHandler>(this->LogS), true);
1909-
1903+
auto Cache = CommandCache::get(LogS);
19101904
for (auto *Input : InSet->DataObjects) {
19111905

19121906
if (env::shouldSaveTemps()) {
@@ -1919,28 +1913,19 @@ amd_comgr_status_t AMDGPUCompiler::translateSpirvToBitcode() {
19191913
return AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT;
19201914
}
19211915

1922-
// TODO: With C++23, we should investigate replacing with spanstream
1923-
// to avoid memory copies:
1924-
// https://en.cppreference.com/w/cpp/io/basic_ispanstream
1925-
std::istringstream ISS(std::string(Input->Data, Input->Size));
1926-
1927-
llvm::Module *M;
1928-
std::string Err;
1929-
1930-
SPIRV::TranslatorOpts Opts;
1931-
Opts.enableAllExtensions();
1932-
Opts.setDesiredBIsRepresentation(SPIRV::BIsRepresentation::OpenCL20);
1916+
SmallString<0> OutBuf;
1917+
SPIRVCommand SPIRV(Input, OutBuf);
19331918

1934-
if (!llvm::readSpirv(Context, Opts, ISS, M, Err)) {
1935-
LogS << "Failed to load SPIR-V as LLVM Module: " << Err << '\n';
1936-
return AMD_COMGR_STATUS_ERROR;
1919+
amd_comgr_status_t Status;
1920+
if (!Cache) {
1921+
Status = SPIRV.execute(LogS);
1922+
} else {
1923+
Status = Cache->execute(SPIRV, LogS);
19371924
}
19381925

1939-
SmallString<0> OutBuf;
1940-
BitcodeWriter Writer(OutBuf);
1941-
Writer.writeModule(*M, false, nullptr, false, nullptr);
1942-
Writer.writeSymtab();
1943-
Writer.writeStrtab();
1926+
if (Status) {
1927+
return Status;
1928+
}
19441929

19451930
amd_comgr_data_t OutputT;
19461931
if (auto Status = amd_comgr_create_data(AMD_COMGR_DATA_KIND_BC, &OutputT)) {

amd/comgr/src/comgr-spirv-command.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*******************************************************************************
2+
*
3+
* University of Illinois/NCSA
4+
* Open Source License
5+
*
6+
* Copyright (c) 2003-2017 University of Illinois at Urbana-Champaign.
7+
* Modifications (c) 2018 Advanced Micro Devices, Inc.
8+
* All rights reserved.
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* with the Software without restriction, including without limitation the
13+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
14+
* sell copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* * Redistributions of source code must retain the above copyright notice,
18+
* this list of conditions and the following disclaimers.
19+
*
20+
* * Redistributions in binary form must reproduce the above copyright
21+
* notice, this list of conditions and the following disclaimers in the
22+
* documentation and/or other materials provided with the distribution.
23+
*
24+
* * Neither the names of the LLVM Team, University of Illinois at
25+
* Urbana-Champaign, nor the names of its contributors may be used to
26+
* endorse or promote products derived from this Software without specific
27+
* prior written permission.
28+
*
29+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32+
* CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
35+
* THE SOFTWARE.
36+
*
37+
******************************************************************************/
38+
39+
#include "comgr-spirv-command.h"
40+
41+
#ifndef COMGR_DISABLE_SPIRV
42+
#include "comgr-diagnostic-handler.h"
43+
44+
#include <LLVMSPIRVLib/LLVMSPIRVLib.h>
45+
#include <llvm/Bitcode/BitcodeWriter.h>
46+
#include <llvm/IR/LLVMContext.h>
47+
48+
#include <sstream>
49+
#endif
50+
51+
namespace COMGR {
52+
using namespace llvm;
53+
Error SPIRVCommand::writeExecuteOutput(StringRef CachedBuffer) {
54+
assert(OutputBuffer.empty());
55+
OutputBuffer.reserve(CachedBuffer.size());
56+
OutputBuffer.insert(OutputBuffer.end(), CachedBuffer.begin(),
57+
CachedBuffer.end());
58+
return Error::success();
59+
}
60+
61+
Expected<StringRef> SPIRVCommand::readExecuteOutput() {
62+
return StringRef(OutputBuffer.data(), OutputBuffer.size());
63+
}
64+
65+
amd_comgr_status_t SPIRVCommand::execute(raw_ostream &LogS) {
66+
#ifndef COMGR_DISABLE_SPIRV
67+
LLVMContext Context;
68+
Context.setDiagnosticHandler(
69+
std::make_unique<AMDGPUCompilerDiagnosticHandler>(LogS), true);
70+
71+
// TODO: With C++23, we should investigate replacing with spanstream
72+
// to avoid memory copies:
73+
// https://en.cppreference.com/w/cpp/io/basic_ispanstream
74+
std::istringstream ISS(std::string(InputBuffer.data(), InputBuffer.size()));
75+
76+
Module *M;
77+
std::string Err;
78+
79+
if (!readSpirv(Context, ISS, M, Err)) {
80+
LogS << "Failed to load SPIR-V as LLVM Module: " << Err << '\n';
81+
return AMD_COMGR_STATUS_ERROR;
82+
}
83+
84+
BitcodeWriter Writer(OutputBuffer);
85+
Writer.writeModule(*M, false, nullptr, false, nullptr);
86+
Writer.writeSymtab();
87+
Writer.writeStrtab();
88+
return AMD_COMGR_STATUS_SUCCESS;
89+
#else
90+
return AMD_COMGR_STATUS_ERROR;
91+
#endif
92+
}
93+
94+
SPIRVCommand::ActionClass SPIRVCommand::getClass() const {
95+
// return an action class that is not allocated to distinguish it from any
96+
// clang action
97+
return clang::driver::Action::ActionClass::JobClassLast + 1;
98+
}
99+
100+
void SPIRVCommand::addOptionsIdentifier(HashAlgorithm &) const {
101+
// do nothing, there are no options
102+
return;
103+
}
104+
105+
Error SPIRVCommand::addInputIdentifier(HashAlgorithm &H) const {
106+
addString(H, InputBuffer);
107+
return Error::success();
108+
}
109+
} // namespace COMGR

amd/comgr/src/comgr-spirv-command.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*******************************************************************************
2+
*
3+
* University of Illinois/NCSA
4+
* Open Source License
5+
*
6+
* Copyright (c) 2003-2017 University of Illinois at Urbana-Champaign.
7+
* Modifications (c) 2018 Advanced Micro Devices, Inc.
8+
* All rights reserved.
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* with the Software without restriction, including without limitation the
13+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
14+
* sell copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* * Redistributions of source code must retain the above copyright notice,
18+
* this list of conditions and the following disclaimers.
19+
*
20+
* * Redistributions in binary form must reproduce the above copyright
21+
* notice, this list of conditions and the following disclaimers in the
22+
* documentation and/or other materials provided with the distribution.
23+
*
24+
* * Neither the names of the LLVM Team, University of Illinois at
25+
* Urbana-Champaign, nor the names of its contributors may be used to
26+
* endorse or promote products derived from this Software without specific
27+
* prior written permission.
28+
*
29+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32+
* CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
35+
* THE SOFTWARE.
36+
*
37+
******************************************************************************/
38+
39+
#ifndef COMGR_SPIRV_COMMAND_H
40+
#define COMGR_SPIRV_COMMAND_H
41+
42+
#include "comgr-cache-command.h"
43+
#include "comgr.h"
44+
45+
namespace COMGR {
46+
class SPIRVCommand : public CachedCommandAdaptor {
47+
public:
48+
llvm::StringRef InputBuffer;
49+
llvm::SmallVectorImpl<char> &OutputBuffer;
50+
51+
public:
52+
SPIRVCommand(DataObject *Input, llvm::SmallVectorImpl<char> &OutputBuffer)
53+
: InputBuffer(Input->Data, Input->Size), OutputBuffer(OutputBuffer) {}
54+
55+
bool canCache() const final { return true; }
56+
llvm::Error writeExecuteOutput(llvm::StringRef CachedBuffer) final;
57+
llvm::Expected<llvm::StringRef> readExecuteOutput() final;
58+
amd_comgr_status_t execute(llvm::raw_ostream &LogS) final;
59+
60+
~SPIRVCommand() override = default;
61+
62+
protected:
63+
ActionClass getClass() const override;
64+
void addOptionsIdentifier(HashAlgorithm &) const override;
65+
llvm::Error addInputIdentifier(HashAlgorithm &) const override;
66+
};
67+
} // namespace COMGR
68+
69+
#endif
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// REQUIRES: comgr-has-spirv
2+
// COM: Same as spirv-translator but with the cache
3+
4+
// COM: Generate a spirv-targeted LLVM IR file from an OpenCL kernel
5+
// RUN: clang -c -emit-llvm --target=spirv64 %s -o %t.bc
6+
7+
// COM: Translate LLVM IR to SPIRV format
8+
// RUN: amd-llvm-spirv --spirv-target-env=CL2.0 %t.bc -o %t.spv
9+
10+
// COM: Run Comgr Translator to covert SPIRV back to LLVM IR
11+
// RUN: export AMD_COMGR_CACHE=1
12+
// RUN: AMD_COMGR_CACHE_DIR=%t.cache spirv-translator %t.spv -o %t.translated.bc
13+
// RUN: COUNT=$(ls "%t.cache" | wc -l)
14+
// RUN: [ 2 -eq $COUNT ]
15+
16+
// COM: Dissasemble LLVM IR bitcode to LLVM IR text
17+
// RUN: llvm-dis %t.translated.bc -o - | FileCheck %S/spirv-translator.cl

0 commit comments

Comments
 (0)