5
5
#include " comgr.h"
6
6
7
7
#include < clang/Basic/Version.h>
8
- #include < clang/Driver/Job.h>
9
8
#include < llvm/ADT/StringExtras.h>
10
- #include < llvm/ADT/StringSet.h>
11
9
12
10
#include < optional>
13
11
@@ -28,7 +26,9 @@ bool isalnum(char c) {
28
26
return false ;
29
27
}
30
28
31
- std::optional<size_t > searchComgrTmpModel (StringRef S) {
29
+ } // namespace
30
+
31
+ std::optional<size_t > CachedCommandAdaptor::searchComgrTmpModel (StringRef S) {
32
32
// Ideally, we would use std::regex_search with the regex
33
33
// "comgr-[[:alnum:]]{6}". However, due to a bug in stdlibc++
34
34
// (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) {
53
53
return Pos;
54
54
}
55
55
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) {
72
58
// hash size + contents to avoid collisions
73
59
// for example, we have to ensure that the result of hashing "AA" "BB" is
74
60
// different from "A" "ABB"
75
61
H.update (S.size ());
76
62
H.update (S);
77
63
}
78
64
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
-
136
65
void CachedCommandAdaptor::addFileContents (
137
66
CachedCommandAdaptor::HashAlgorithm &H, StringRef Buf) {
138
67
// this is a workaround temporary paths getting in the output files of the
@@ -169,120 +98,4 @@ CachedCommandAdaptor::getIdentifier() const {
169
98
toHex (H.final (), true , Id);
170
99
return Id;
171
100
}
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
- }
288
101
} // namespace COMGR
0 commit comments