22
22
#include " llvm/CAS/HierarchicalTreeBuilder.h"
23
23
#include " llvm/CAS/ObjectStore.h"
24
24
#include " llvm/Support/Debug.h"
25
+ #include " llvm/Support/Mutex.h"
25
26
#include < optional>
26
27
27
28
#define DEBUG_TYPE " swift-cas-backend"
@@ -112,6 +113,9 @@ class SwiftCASOutputBackend::Implementation {
112
113
Error storeImpl (StringRef Path, StringRef Bytes, unsigned InputIndex,
113
114
file_types::ID OutputKind);
114
115
116
+ // Return true if all the outputs are produced for the given index.
117
+ bool addProducedOutput (unsigned InputIndex, file_types::ID OutputKind,
118
+ ObjectRef BytesRef);
115
119
Error finalizeCacheKeysFor (unsigned InputIndex);
116
120
117
121
private:
@@ -123,6 +127,9 @@ class SwiftCASOutputBackend::Implementation {
123
127
const FrontendOptions &Opts;
124
128
FrontendOptions::ActionType Action;
125
129
130
+ // Lock for updating output file status.
131
+ llvm::sys::SmartMutex<true > OutputLock;
132
+
126
133
// Map from output path to the input index and output kind.
127
134
StringMap<std::pair<unsigned , file_types::ID>> OutputToInputMap;
128
135
@@ -197,8 +204,10 @@ Error SwiftCASOutputBackend::storeMCCASObjectID(StringRef OutputFilename,
197
204
return createStringError (" Invalid CASID: " + ID.toString () +
198
205
" . No associated ObjectRef found!" );
199
206
200
- Impl.OutputRefs [InputIndex].insert ({file_types::TY_Object, *MCRef});
201
- return Impl.finalizeCacheKeysFor (InputIndex);
207
+ if (Impl.addProducedOutput (InputIndex, file_types::TY_Object, *MCRef))
208
+ return Impl.finalizeCacheKeysFor (InputIndex);
209
+
210
+ return Error::success ();
202
211
}
203
212
204
213
void SwiftCASOutputBackend::Implementation::initBackend (
@@ -249,23 +258,29 @@ Error SwiftCASOutputBackend::Implementation::storeImpl(
249
258
<< " \' for input \' " << InputIndex << " \' : \' "
250
259
<< CAS.getID (*BytesRef).toString () << " \'\n " ;);
251
260
252
- OutputRefs[InputIndex].insert ({OutputKind, *BytesRef});
261
+ if (addProducedOutput (InputIndex, OutputKind, *BytesRef))
262
+ return finalizeCacheKeysFor (InputIndex);
263
+ return Error::success ();
264
+ }
265
+
266
+ bool SwiftCASOutputBackend::Implementation::addProducedOutput (
267
+ unsigned InputIndex, file_types::ID OutputKind,
268
+ ObjectRef BytesRef) {
269
+ llvm::sys::SmartScopedLock<true > LockOutput (OutputLock);
270
+ auto &ProducedOutputs = OutputRefs[InputIndex];
271
+ ProducedOutputs.insert ({OutputKind, BytesRef});
253
272
254
- return finalizeCacheKeysFor (InputIndex);
273
+ return llvm::all_of (OutputToInputMap, [&](auto &E) {
274
+ return (E.second .first != InputIndex ||
275
+ ProducedOutputs.count (E.second .second ));
276
+ });
255
277
}
256
278
257
279
Error SwiftCASOutputBackend::Implementation::finalizeCacheKeysFor (
258
280
unsigned InputIndex) {
259
- auto ProducedOutputs = OutputRefs[InputIndex];
281
+ const auto & ProducedOutputs = OutputRefs[InputIndex];
260
282
assert (!ProducedOutputs.empty () && " Expect outputs for this input" );
261
283
262
- // If not all outputs for the input are emitted, return.
263
- if (!llvm::all_of (OutputToInputMap, [&](auto &E) {
264
- return (E.second .first != InputIndex ||
265
- ProducedOutputs.count (E.second .second ));
266
- }))
267
- return Error::success ();
268
-
269
284
std::vector<std::pair<file_types::ID, ObjectRef>> OutputsForInput;
270
285
llvm::for_each (ProducedOutputs, [&OutputsForInput](auto E) {
271
286
OutputsForInput.emplace_back (E.first , E.second );
0 commit comments