Skip to content

Commit 9d5047e

Browse files
author
Salinas, David
authored
[Comgr][Cache] Late code reviews cherry-picked from staging to mainline (llvm#1271)
2 parents 20fbc4b + 74d62d7 commit 9d5047e

File tree

10 files changed

+288
-234
lines changed

10 files changed

+288
-234
lines changed

amd/comgr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ set(SOURCES
7474
src/comgr-cache.cpp
7575
src/comgr-cache-command.cpp
7676
src/comgr-cache-bundler-command.cpp
77+
src/comgr-clang-command.cpp
7778
src/comgr-compiler.cpp
7879
src/comgr.cpp
7980
src/comgr-device-libs.cpp

amd/comgr/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@ If an issue arises during cache initialization, the execution will proceed with
132132
the cache turned off.
133133

134134
By default, the cache is turned off, set the environment variable
135-
`AMD_COMGR_CACHE=1` to enable it. This may change in a future release.
135+
`AMD_COMGR_CACHE=1` to enable it.
136136

137137
* `AMD_COMGR_CACHE`: When unset or set to 0, the cache is turned off.
138-
* `AMD_COMGR_CACHE_DIR`: When set to "", the cache is turned off. If assigned a
139-
value, that value is used as the path for cache storage. By default, it is
140-
directed to "$XDG_CACHE_HOME/comgr_cache" (which defaults to
141-
"$USER/.cache/comgr_cache" on Linux, and "%LOCALAPPDATA%\cache\comgr_cache"
138+
* `AMD_COMGR_CACHE_DIR`: If assigned a non-empty value, that value is used as
139+
the path for cache storage. If the variable is unset or set to an empty string `""`,
140+
it is directed to "$XDG_CACHE_HOME/comgr" (which defaults to
141+
"$USER/.cache/comgr" on Linux, and "%LOCALAPPDATA%\cache\comgr"
142142
on Microsoft Windows).
143143
* `AMD_COMGR_CACHE_POLICY`: If assigned a value, the string is interpreted and
144144
applied to the cache pruning policy. The cache is pruned only upon program

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

Lines changed: 9 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ bool isalnum(char c) {
2727
}
2828
return false;
2929
}
30+
} // namespace
3031

31-
std::optional<size_t> searchComgrTmpModel(StringRef S) {
32+
std::optional<size_t> CachedCommandAdaptor::searchComgrTmpModel(StringRef S) {
3233
// Ideally, we would use std::regex_search with the regex
3334
// "comgr-[[:alnum:]]{6}". However, due to a bug in stdlibc++
3435
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85824) we have to roll our
@@ -53,77 +54,14 @@ std::optional<size_t> searchComgrTmpModel(StringRef S) {
5354
return Pos;
5455
}
5556

56-
bool hasDebugOrProfileInfo(ArrayRef<const char *> Args) {
57-
// These are too difficult to handle since they generate debug info that
58-
// refers to the temporary paths used by comgr.
59-
const StringRef Flags[] = {"-fdebug-info-kind", "-fprofile", "-coverage",
60-
"-ftime-trace"};
61-
62-
for (StringRef Arg : Args) {
63-
for (StringRef Flag : Flags) {
64-
if (Arg.starts_with(Flag))
65-
return true;
66-
}
67-
}
68-
return false;
69-
}
70-
71-
Error addFile(CachedCommandAdaptor::HashAlgorithm &H, StringRef Path) {
72-
auto BufOrError = MemoryBuffer::getFile(Path);
73-
if (std::error_code EC = BufOrError.getError()) {
74-
return errorCodeToError(EC);
75-
}
76-
StringRef Buf = BufOrError.get()->getBuffer();
77-
78-
CachedCommandAdaptor::addFileContents(H, Buf);
79-
80-
return Error::success();
81-
}
82-
83-
template <typename IteratorTy>
84-
bool skipProblematicFlag(IteratorTy &It, const IteratorTy &End) {
85-
// Skip include paths, these should have been handled by preprocessing the
86-
// source first. Sadly, these are passed also to the middle-end commands. Skip
87-
// debug related flags (they should be ignored) like -dumpdir (used for
88-
// profiling/coverage/split-dwarf)
89-
StringRef Arg = *It;
90-
static const StringSet<> FlagsWithPathArg = {"-I", "-dumpdir"};
91-
bool IsFlagWithPathArg = It + 1 != End && FlagsWithPathArg.contains(Arg);
92-
if (IsFlagWithPathArg) {
93-
++It;
94-
return true;
95-
}
96-
97-
// Clang always appends the debug compilation dir,
98-
// even without debug info (in comgr it matches the current directory). We
99-
// only consider it if the user specified debug information
100-
bool IsFlagWithSingleArg = Arg.starts_with("-fdebug-compilation-dir=");
101-
if (IsFlagWithSingleArg) {
102-
return true;
103-
}
104-
105-
return false;
106-
}
107-
108-
SmallVector<StringRef, 1> getInputFiles(driver::Command &Command) {
109-
const auto &CommandInputs = Command.getInputInfos();
110-
111-
SmallVector<StringRef, 1> Paths;
112-
Paths.reserve(CommandInputs.size());
113-
114-
for (const auto &II : CommandInputs) {
115-
if (!II.isFilename())
116-
continue;
117-
Paths.push_back(II.getFilename());
118-
}
119-
120-
return Paths;
121-
}
122-
123-
bool isSourceCodeInput(const driver::InputInfo &II) {
124-
return driver::types::isSrcFile(II.getType());
57+
void CachedCommandAdaptor::addString(CachedCommandAdaptor::HashAlgorithm &H,
58+
StringRef S) {
59+
// hash size + contents to avoid collisions
60+
// for example, we have to ensure that the result of hashing "AA" "BB" is
61+
// different from "A" "ABB"
62+
H.update(S.size());
63+
H.update(S);
12564
}
126-
} // namespace
12765

12866
void CachedCommandAdaptor::addFileContents(
12967
CachedCommandAdaptor::HashAlgorithm &H, StringRef Buf) {
@@ -136,22 +74,12 @@ void CachedCommandAdaptor::addFileContents(
13674
addString(H, Buf);
13775
break;
13876
}
139-
14077
StringRef ToHash = Buf.substr(0, *ComgrTmpPos);
14178
addString(H, ToHash);
14279
Buf = Buf.substr(ToHash.size() + StringRef("comgr-xxxxxx").size());
14380
}
14481
}
14582

146-
void CachedCommandAdaptor::addString(CachedCommandAdaptor::HashAlgorithm &H,
147-
StringRef S) {
148-
// hash size + contents to avoid collisions
149-
// for example, we have to ensure that the result of hashing "AA" "BB" is
150-
// different from "A" "ABB"
151-
H.update(S.size());
152-
H.update(S);
153-
}
154-
15583
Expected<CachedCommandAdaptor::Identifier>
15684
CachedCommandAdaptor::getIdentifier() const {
15785
CachedCommandAdaptor::HashAlgorithm H;
@@ -205,101 +133,4 @@ CachedCommandAdaptor::readUniqueExecuteOutput(StringRef OutputFilename) {
205133

206134
return std::move(*MBOrErr);
207135
}
208-
209-
ClangCommand::ClangCommand(driver::Command &Command,
210-
DiagnosticOptions &DiagOpts,
211-
llvm::vfs::FileSystem &VFS,
212-
ExecuteFnTy &&ExecuteImpl)
213-
: Command(Command), DiagOpts(DiagOpts), VFS(VFS),
214-
ExecuteImpl(std::move(ExecuteImpl)) {}
215-
216-
Error ClangCommand::addInputIdentifier(HashAlgorithm &H) const {
217-
auto Inputs(getInputFiles(Command));
218-
for (StringRef Input : Inputs) {
219-
if (Error E = addFile(H, Input)) {
220-
// call Error's constructor again to silence copy elision warning
221-
return Error(std::move(E));
222-
}
223-
}
224-
return Error::success();
225-
}
226-
227-
void ClangCommand::addOptionsIdentifier(HashAlgorithm &H) const {
228-
auto Inputs(getInputFiles(Command));
229-
StringRef Output = Command.getOutputFilenames().front();
230-
ArrayRef<const char *> Arguments = Command.getArguments();
231-
for (auto It = Arguments.begin(), End = Arguments.end(); It != End; ++It) {
232-
if (skipProblematicFlag(It, End))
233-
continue;
234-
235-
StringRef Arg = *It;
236-
static const StringSet<> FlagsWithFileArgEmbededInComgr = {
237-
"-include-pch", "-mlink-builtin-bitcode"};
238-
if (FlagsWithFileArgEmbededInComgr.contains(Arg)) {
239-
// The next argument is a path to a "secondary" input-file (pre-compiled
240-
// header or device-libs builtin)
241-
// These two files kinds of files are embedded in comgr at compile time,
242-
// and in normally their remain constant with comgr's build. The user is
243-
// not able to change them.
244-
++It;
245-
if (It == End)
246-
break;
247-
continue;
248-
}
249-
250-
// input files are considered by their content
251-
// output files should not be considered at all
252-
bool IsIOFile = Output == Arg || is_contained(Inputs, Arg);
253-
if (IsIOFile)
254-
continue;
255-
256-
#ifndef NDEBUG
257-
bool IsComgrTmpPath = searchComgrTmpModel(Arg).has_value();
258-
// On debug builds, fail on /tmp/comgr-xxxx/... paths.
259-
// Implicit dependencies should have been considered before.
260-
// On release builds, add them to the hash to force a cache miss.
261-
assert(!IsComgrTmpPath &&
262-
"Unexpected flag and path to comgr temporary directory");
263-
#endif
264-
265-
addString(H, Arg);
266-
}
267-
}
268-
269-
ClangCommand::ActionClass ClangCommand::getClass() const {
270-
return Command.getSource().getKind();
271-
}
272-
273-
bool ClangCommand::canCache() const {
274-
bool HasOneOutput = Command.getOutputFilenames().size() == 1;
275-
bool IsPreprocessorCommand = getClass() == driver::Action::PreprocessJobClass;
276-
277-
// This reduces the applicability of the cache, but it helps us deliver
278-
// something now and deal with the PCH issues later. The cache would still
279-
// help for spirv compilation (e.g. bitcode->asm) and for intermediate
280-
// compilation steps
281-
bool HasSourceCodeInput = any_of(Command.getInputInfos(), isSourceCodeInput);
282-
283-
return HasOneOutput && !IsPreprocessorCommand && !HasSourceCodeInput &&
284-
!hasDebugOrProfileInfo(Command.getArguments());
285-
}
286-
287-
Error ClangCommand::writeExecuteOutput(StringRef CachedBuffer) {
288-
StringRef OutputFilename = Command.getOutputFilenames().front();
289-
return CachedCommandAdaptor::writeUniqueExecuteOutput(OutputFilename,
290-
CachedBuffer);
291-
}
292-
293-
Expected<StringRef> ClangCommand::readExecuteOutput() {
294-
auto MaybeBuffer = CachedCommandAdaptor::readUniqueExecuteOutput(
295-
Command.getOutputFilenames().front());
296-
if (!MaybeBuffer)
297-
return MaybeBuffer.takeError();
298-
Output = std::move(*MaybeBuffer);
299-
return Output->getBuffer();
300-
}
301-
302-
amd_comgr_status_t ClangCommand::execute(llvm::raw_ostream &LogS) {
303-
return ExecuteImpl(Command, LogS, DiagOpts, VFS);
304-
}
305136
} // namespace COMGR

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

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,6 @@
4242
#include <llvm/Support/Error.h>
4343
#include <llvm/Support/MemoryBuffer.h>
4444
#include <llvm/Support/SHA256.h>
45-
#include <llvm/Support/VirtualFileSystem.h>
46-
47-
namespace clang {
48-
class DiagnosticOptions;
49-
namespace driver {
50-
class Command;
51-
} // namespace driver
52-
} // namespace clang
5345

5446
namespace llvm {
5547
class raw_ostream;
@@ -74,7 +66,8 @@ class CachedCommandAdaptor {
7466

7567
// helper to work around the comgr-xxxxx string appearing in files
7668
static void addFileContents(HashAlgorithm &H, llvm::StringRef Buf);
77-
static void addString(HashAlgorithm &H, llvm::StringRef Buf);
69+
static void addString(HashAlgorithm &H, llvm::StringRef S);
70+
static std::optional<size_t> searchComgrTmpModel(llvm::StringRef S);
7871

7972
// helper since several command types just write to a single output file
8073
static llvm::Error writeUniqueExecuteOutput(llvm::StringRef OutputFilename,
@@ -87,40 +80,6 @@ class CachedCommandAdaptor {
8780
virtual void addOptionsIdentifier(HashAlgorithm &) const = 0;
8881
virtual llvm::Error addInputIdentifier(HashAlgorithm &) const = 0;
8982
};
90-
91-
class ClangCommand final : public CachedCommandAdaptor {
92-
public:
93-
using ExecuteFnTy = std::function<amd_comgr_status_t(
94-
clang::driver::Command &, llvm::raw_ostream &, clang::DiagnosticOptions &,
95-
llvm::vfs::FileSystem &)>;
96-
97-
private:
98-
clang::driver::Command &Command;
99-
clang::DiagnosticOptions &DiagOpts;
100-
llvm::vfs::FileSystem &VFS;
101-
ExecuteFnTy ExecuteImpl;
102-
103-
// To avoid copies, store the output of execute, such that readExecuteOutput
104-
// can return a reference.
105-
std::unique_ptr<llvm::MemoryBuffer> Output;
106-
107-
public:
108-
ClangCommand(clang::driver::Command &Command,
109-
clang::DiagnosticOptions &DiagOpts, llvm::vfs::FileSystem &VFS,
110-
ExecuteFnTy &&ExecuteImpl);
111-
112-
bool canCache() const override;
113-
llvm::Error writeExecuteOutput(llvm::StringRef CachedBuffer) override;
114-
llvm::Expected<llvm::StringRef> readExecuteOutput() override;
115-
amd_comgr_status_t execute(llvm::raw_ostream &LogS) override;
116-
117-
~ClangCommand() override = default;
118-
119-
protected:
120-
ActionClass getClass() const override;
121-
void addOptionsIdentifier(HashAlgorithm &) const override;
122-
llvm::Error addInputIdentifier(HashAlgorithm &) const override;
123-
};
12483
} // namespace COMGR
12584

12685
#endif

0 commit comments

Comments
 (0)