2222#include " llvm/CAS/HierarchicalTreeBuilder.h"
2323#include " llvm/CAS/ObjectStore.h"
2424#include " llvm/Support/Debug.h"
25+ #include " llvm/Support/Mutex.h"
2526#include < optional>
2627
2728#define DEBUG_TYPE " swift-cas-backend"
@@ -112,6 +113,9 @@ class SwiftCASOutputBackend::Implementation {
112113 Error storeImpl (StringRef Path, StringRef Bytes, unsigned InputIndex,
113114 file_types::ID OutputKind);
114115
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);
115119 Error finalizeCacheKeysFor (unsigned InputIndex);
116120
117121private:
@@ -123,6 +127,9 @@ class SwiftCASOutputBackend::Implementation {
123127 const FrontendOptions &Opts;
124128 FrontendOptions::ActionType Action;
125129
130+ // Lock for updating output file status.
131+ llvm::sys::SmartMutex<true > OutputLock;
132+
126133 // Map from output path to the input index and output kind.
127134 StringMap<std::pair<unsigned , file_types::ID>> OutputToInputMap;
128135
@@ -197,8 +204,10 @@ Error SwiftCASOutputBackend::storeMCCASObjectID(StringRef OutputFilename,
197204 return createStringError (" Invalid CASID: " + ID.toString () +
198205 " . No associated ObjectRef found!" );
199206
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 ();
202211}
203212
204213void SwiftCASOutputBackend::Implementation::initBackend (
@@ -249,23 +258,29 @@ Error SwiftCASOutputBackend::Implementation::storeImpl(
249258 << " \' for input \' " << InputIndex << " \' : \' "
250259 << CAS.getID (*BytesRef).toString () << " \'\n " ;);
251260
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});
253272
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+ });
255277}
256278
257279Error SwiftCASOutputBackend::Implementation::finalizeCacheKeysFor (
258280 unsigned InputIndex) {
259- auto ProducedOutputs = OutputRefs[InputIndex];
281+ const auto & ProducedOutputs = OutputRefs[InputIndex];
260282 assert (!ProducedOutputs.empty () && " Expect outputs for this input" );
261283
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-
269284 std::vector<std::pair<file_types::ID, ObjectRef>> OutputsForInput;
270285 llvm::for_each (ProducedOutputs, [&OutputsForInput](auto E) {
271286 OutputsForInput.emplace_back (E.first , E.second );
0 commit comments