Skip to content

Commit 085b846

Browse files
committed
[Review] Move ClangCommand to its own header/source files clang-clang-command.h/cpp
1 parent 07d460c commit 085b846

File tree

6 files changed

+291
-235
lines changed

6 files changed

+291
-235
lines changed

amd/comgr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ option(COMGR_BUILD_SHARED_LIBS "Build the shared library"
7171
set(SOURCES
7272
src/comgr-cache.cpp
7373
src/comgr-cache-command.cpp
74+
src/comgr-clang-command.cpp
7475
src/comgr-compiler.cpp
7576
src/comgr.cpp
7677
src/comgr-device-libs.cpp

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

Lines changed: 5 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
#include "comgr.h"
66

77
#include <clang/Basic/Version.h>
8-
#include <clang/Driver/Job.h>
98
#include <llvm/ADT/StringExtras.h>
10-
#include <llvm/ADT/StringSet.h>
119

1210
#include <optional>
1311

@@ -28,7 +26,9 @@ bool isalnum(char c) {
2826
return false;
2927
}
3028

31-
std::optional<size_t> searchComgrTmpModel(StringRef S) {
29+
} // namespace
30+
31+
std::optional<size_t> CachedCommandAdaptor::searchComgrTmpModel(StringRef S) {
3232
// Ideally, we would use std::regex_search with the regex
3333
// "comgr-[[:alnum:]]{6}". However, due to a bug in stdlibc++
3434
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85824) we have to roll our
@@ -53,86 +53,15 @@ std::optional<size_t> searchComgrTmpModel(StringRef S) {
5353
return Pos;
5454
}
5555

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-
void addString(CachedCommandAdaptor::HashAlgorithm &H, StringRef S) {
56+
void CachedCommandAdaptor::addString(CachedCommandAdaptor::HashAlgorithm &H,
57+
StringRef S) {
7258
// hash size + contents to avoid collisions
7359
// for example, we have to ensure that the result of hashing "AA" "BB" is
7460
// different from "A" "ABB"
7561
H.update(S.size());
7662
H.update(S);
7763
}
7864

79-
Error addFile(CachedCommandAdaptor::HashAlgorithm &H, StringRef Path) {
80-
auto BufOrError = MemoryBuffer::getFile(Path);
81-
if (std::error_code EC = BufOrError.getError()) {
82-
return errorCodeToError(EC);
83-
}
84-
StringRef Buf = BufOrError.get()->getBuffer();
85-
86-
CachedCommandAdaptor::addFileContents(H, Buf);
87-
88-
return Error::success();
89-
}
90-
91-
template <typename IteratorTy>
92-
bool skipProblematicFlag(IteratorTy &It, const IteratorTy &End) {
93-
// Skip include paths, these should have been handled by preprocessing the
94-
// source first. Sadly, these are passed also to the middle-end commands. Skip
95-
// debug related flags (they should be ignored) like -dumpdir (used for
96-
// profiling/coverage/split-dwarf)
97-
StringRef Arg = *It;
98-
static const StringSet<> FlagsWithPathArg = {"-I", "-dumpdir"};
99-
bool IsFlagWithPathArg = It + 1 != End && FlagsWithPathArg.contains(Arg);
100-
if (IsFlagWithPathArg) {
101-
++It;
102-
return true;
103-
}
104-
105-
// Clang always appends the debug compilation dir,
106-
// even without debug info (in comgr it matches the current directory). We
107-
// only consider it if the user specified debug information
108-
bool IsFlagWithSingleArg = Arg.starts_with("-fdebug-compilation-dir=");
109-
if (IsFlagWithSingleArg) {
110-
return true;
111-
}
112-
113-
return false;
114-
}
115-
116-
SmallVector<StringRef, 1> getInputFiles(driver::Command &Command) {
117-
const auto &CommandInputs = Command.getInputInfos();
118-
119-
SmallVector<StringRef, 1> Paths;
120-
Paths.reserve(CommandInputs.size());
121-
122-
for (const auto &II : CommandInputs) {
123-
if (!II.isFilename())
124-
continue;
125-
Paths.push_back(II.getFilename());
126-
}
127-
128-
return Paths;
129-
}
130-
131-
bool isSourceCodeInput(const driver::InputInfo &II) {
132-
return driver::types::isSrcFile(II.getType());
133-
}
134-
} // namespace
135-
13665
void CachedCommandAdaptor::addFileContents(
13766
CachedCommandAdaptor::HashAlgorithm &H, StringRef Buf) {
13867
// this is a workaround temporary paths getting in the output files of the
@@ -169,120 +98,4 @@ CachedCommandAdaptor::getIdentifier() const {
16998
toHex(H.final(), true, Id);
17099
return Id;
171100
}
172-
173-
ClangCommand::ClangCommand(driver::Command &Command,
174-
DiagnosticOptions &DiagOpts,
175-
llvm::vfs::FileSystem &VFS,
176-
ExecuteFnTy &&ExecuteImpl)
177-
: Command(Command), DiagOpts(DiagOpts), VFS(VFS),
178-
ExecuteImpl(std::move(ExecuteImpl)) {}
179-
180-
Error ClangCommand::addInputIdentifier(HashAlgorithm &H) const {
181-
auto Inputs(getInputFiles(Command));
182-
for (StringRef Input : Inputs) {
183-
if (Error E = addFile(H, Input)) {
184-
// call Error's constructor again to silence copy elision warning
185-
return Error(std::move(E));
186-
}
187-
}
188-
return Error::success();
189-
}
190-
191-
void ClangCommand::addOptionsIdentifier(HashAlgorithm &H) const {
192-
auto Inputs(getInputFiles(Command));
193-
StringRef Output = Command.getOutputFilenames().front();
194-
ArrayRef<const char *> Arguments = Command.getArguments();
195-
for (auto It = Arguments.begin(), End = Arguments.end(); It != End; ++It) {
196-
if (skipProblematicFlag(It, End))
197-
continue;
198-
199-
StringRef Arg = *It;
200-
static const StringSet<> FlagsWithFileArgEmbededInComgr = {
201-
"-include-pch", "-mlink-builtin-bitcode"};
202-
if (FlagsWithFileArgEmbededInComgr.contains(Arg)) {
203-
// The next argument is a path to a "secondary" input-file (pre-compiled
204-
// header or device-libs builtin)
205-
// These two files kinds of files are embedded in comgr at compile time,
206-
// and in normally their remain constant with comgr's build. The user is
207-
// not able to change them.
208-
++It;
209-
if (It == End)
210-
break;
211-
continue;
212-
}
213-
214-
// input files are considered by their content
215-
// output files should not be considered at all
216-
bool IsIOFile = Output == Arg || is_contained(Inputs, Arg);
217-
if (IsIOFile)
218-
continue;
219-
220-
#ifndef NDEBUG
221-
bool IsComgrTmpPath = searchComgrTmpModel(Arg).has_value();
222-
// On debug builds, fail on /tmp/comgr-xxxx/... paths.
223-
// Implicit dependencies should have been considered before.
224-
// On release builds, add them to the hash to force a cache miss.
225-
assert(!IsComgrTmpPath &&
226-
"Unexpected flag and path to comgr temporary directory");
227-
#endif
228-
229-
addString(H, Arg);
230-
}
231-
}
232-
233-
ClangCommand::ActionClass ClangCommand::getClass() const {
234-
return Command.getSource().getKind();
235-
}
236-
237-
bool ClangCommand::canCache() const {
238-
bool HasOneOutput = Command.getOutputFilenames().size() == 1;
239-
bool IsPreprocessorCommand = getClass() == driver::Action::PreprocessJobClass;
240-
241-
// This reduces the applicability of the cache, but it helps us deliver
242-
// something now and deal with the PCH issues later. The cache would still
243-
// help for spirv compilation (e.g. bitcode->asm) and for intermediate
244-
// compilation steps
245-
bool HasSourceCodeInput = any_of(Command.getInputInfos(), isSourceCodeInput);
246-
247-
return HasOneOutput && !IsPreprocessorCommand && !HasSourceCodeInput &&
248-
!hasDebugOrProfileInfo(Command.getArguments());
249-
}
250-
251-
Error ClangCommand::writeExecuteOutput(StringRef CachedBuffer) {
252-
StringRef OutputFilename = Command.getOutputFilenames().front();
253-
std::error_code EC;
254-
raw_fd_ostream Out(OutputFilename, EC);
255-
if (EC) {
256-
Error E = createStringError(EC, Twine("Failed to open ") + OutputFilename +
257-
" : " + EC.message() + "\n");
258-
return E;
259-
}
260-
261-
Out.write(CachedBuffer.data(), CachedBuffer.size());
262-
Out.close();
263-
if (Out.has_error()) {
264-
Error E = createStringError(EC, Twine("Failed to write ") + OutputFilename +
265-
" : " + EC.message() + "\n");
266-
return E;
267-
}
268-
269-
return Error::success();
270-
}
271-
272-
Expected<StringRef> ClangCommand::readExecuteOutput() {
273-
StringRef OutputFilename = Command.getOutputFilenames().front();
274-
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
275-
MemoryBuffer::getFile(OutputFilename);
276-
if (!MBOrErr) {
277-
std::error_code EC = MBOrErr.getError();
278-
return createStringError(EC, Twine("Failed to open ") + OutputFilename +
279-
" : " + EC.message() + "\n");
280-
}
281-
Output = std::move(*MBOrErr);
282-
return Output->getBuffer();
283-
}
284-
285-
amd_comgr_status_t ClangCommand::execute(llvm::raw_ostream &LogS) {
286-
return ExecuteImpl(Command, LogS, DiagOpts, VFS);
287-
}
288101
} // namespace COMGR

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

Lines changed: 2 additions & 42 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;
@@ -73,46 +65,14 @@ class CachedCommandAdaptor {
7365

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

7771
protected:
7872
virtual ActionClass getClass() const = 0;
7973
virtual void addOptionsIdentifier(HashAlgorithm &) const = 0;
8074
virtual llvm::Error addInputIdentifier(HashAlgorithm &) const = 0;
8175
};
82-
83-
class ClangCommand final : public CachedCommandAdaptor {
84-
public:
85-
using ExecuteFnTy = std::function<amd_comgr_status_t(
86-
clang::driver::Command &, llvm::raw_ostream &, clang::DiagnosticOptions &,
87-
llvm::vfs::FileSystem &)>;
88-
89-
private:
90-
clang::driver::Command &Command;
91-
clang::DiagnosticOptions &DiagOpts;
92-
llvm::vfs::FileSystem &VFS;
93-
ExecuteFnTy ExecuteImpl;
94-
95-
// To avoid copies, store the output of execute, such that readExecuteOutput
96-
// can return a reference.
97-
std::unique_ptr<llvm::MemoryBuffer> Output;
98-
99-
public:
100-
ClangCommand(clang::driver::Command &Command,
101-
clang::DiagnosticOptions &DiagOpts, llvm::vfs::FileSystem &VFS,
102-
ExecuteFnTy &&ExecuteImpl);
103-
104-
bool canCache() const override;
105-
llvm::Error writeExecuteOutput(llvm::StringRef CachedBuffer) override;
106-
llvm::Expected<llvm::StringRef> readExecuteOutput() override;
107-
amd_comgr_status_t execute(llvm::raw_ostream &LogS) override;
108-
109-
~ClangCommand() override = default;
110-
111-
protected:
112-
ActionClass getClass() const override;
113-
void addOptionsIdentifier(HashAlgorithm &) const override;
114-
llvm::Error addInputIdentifier(HashAlgorithm &) const override;
115-
};
11676
} // namespace COMGR
11777

11878
#endif

0 commit comments

Comments
 (0)