Skip to content

Commit 6df65af

Browse files
committed
TableGen: Convert to new ActionCache APIs
A few notes based on using ActionCache somewhere: - If ActionDescription owned its parameters it'd be easier to build. Seems a bit error-prone right now. - Needed to find a place to store the command-line for "extra data". If we wanted more stuff in ExtraData, this'd get pretty tough. - Needed to create a SmallVector to hold the InputIDs. - But, it's a nice property that ActionDescription is immutable. - If the content (not just the cache) is mutable then it's hard to reason about. - Potential fix: - Make ActionDescription own what it references. - Could allow the errors to be lazy about printing the action as well (store a copy of the description, and just print in `ErrorInfo::log()`). - Add ActionDescriptionBuilder, with simple mutating APIs, and a constructor `ActionDescription(ActionDescriptionBuilder&&)`. - ActionDescriptionRef is lightweight and can be used without building (... but maybe this one isn't useful in practice?) - Conversions between CASID and UniqueIDRef are annoying... but that's just a transition problem.
1 parent 4859af2 commit 6df65af

File tree

4 files changed

+84
-72
lines changed

4 files changed

+84
-72
lines changed

llvm/include/llvm/CAS/CASDB.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,18 @@ class CASDB {
329329

330330
Error getPrintedCASID(CASID ID, SmallVectorImpl<char> &Reference);
331331

332+
/// Translate from CASID and UniqueIDRef.
333+
UniqueIDRef getUniqueID(CASID ID) const {
334+
return UniqueIDRef(getNamespace(), ID.getHash());
335+
}
336+
/// Translate from UniqueIDRef to CASID.
337+
CASID getCASID(UniqueIDRef ID) const {
338+
assert(&ID.getNamespace() == &getNamespace());
339+
return CASID(ID.getHash());
340+
}
341+
/// Beware of lifetime issues.
342+
CASID getCASID(const UniqueID &ID) const = delete;
343+
332344
virtual Expected<BlobRef> createBlob(StringRef Data) = 0;
333345

334346
virtual Expected<TreeRef>

llvm/include/llvm/TableGen/ScanDependencies.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
namespace llvm {
2020

2121
namespace cas {
22+
class ActionCache;
2223
class CachingOnDiskFileSystem;
2324
} // end namespace cas
2425

@@ -42,8 +43,8 @@ void scanTextForIncludes(StringRef Input, SmallVectorImpl<StringRef> &Includes);
4243
///
4344
/// \p ExecID is the Blob for the running executable. It can be used as part of
4445
/// the key for caching to avoid (fixed) bugs poisoning results.
45-
Error scanTextForIncludes(cas::CASDB &CAS, cas::CASID ExecID,
46-
const cas::BlobRef &Blob,
46+
Error scanTextForIncludes(cas::CASDB &CAS, cas::ActionCache &Cache,
47+
cas::CASID ExecID, const cas::BlobRef &Blob,
4748
SmallVectorImpl<StringRef> &Includes);
4849

4950
/// Match logic from SourceMgr::AddIncludeFile.
@@ -57,7 +58,8 @@ Optional<cas::CASID> lookupIncludeID(cas::CachingOnDiskFileSystem &FS,
5758
///
5859
/// \p ExecID is the Blob for the running executable. It can be used as part of
5960
/// the key for caching to avoid (fixed) bugs poisoning results.
60-
Error accessAllIncludes(cas::CachingOnDiskFileSystem &FS, cas::CASID ExecID,
61+
Error accessAllIncludes(cas::ActionCache &Cache,
62+
cas::CachingOnDiskFileSystem &FS, cas::CASID ExecID,
6163
ArrayRef<std::string> IncludeDirs,
6264
const cas::BlobRef &MainFileBlob);
6365

@@ -79,8 +81,8 @@ struct ScanIncludesResult {
7981
/// it'd be useful for build systems that want to collect dependencies ahead of
8082
/// time. Maybe can separate a tool/etc. for that.
8183
Expected<ScanIncludesResult>
82-
scanIncludes(cas::CASDB &CAS, cas::CASID ExecID, StringRef MainFilename,
83-
ArrayRef<std::string> IncludeDirs,
84+
scanIncludes(cas::CASDB &CAS, cas::ActionCache &Cache, cas::CASID ExecID,
85+
StringRef MainFilename, ArrayRef<std::string> IncludeDirs,
8486
ArrayRef<MappedPrefix> PrefixMappings = None,
8587
Optional<TreePathPrefixMapper> *CapturedPM = nullptr);
8688

@@ -91,8 +93,8 @@ scanIncludes(cas::CASDB &CAS, cas::CASID ExecID, StringRef MainFilename,
9193
/// \p ExecID is the Blob for the running executable. It can be used as part of
9294
/// the key for caching to avoid (fixed) bugs poisoning results.
9395
Expected<ScanIncludesResult>
94-
scanIncludesAndRemap(cas::CASDB &CAS, cas::CASID ExecID,
95-
std::string &MainFilename,
96+
scanIncludesAndRemap(cas::CASDB &CAS, cas::ActionCache &Cache,
97+
cas::CASID ExecID, std::string &MainFilename,
9698
std::vector<std::string> &IncludeDirs,
9799
ArrayRef<MappedPrefix> PrefixMappings);
98100

llvm/lib/TableGen/Main.cpp

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/ScopeExit.h"
2020
#include "llvm/ADT/SmallString.h"
2121
#include "llvm/ADT/StringExtras.h"
22+
#include "llvm/CAS/ActionCache.h"
2223
#include "llvm/CAS/CASFileSystem.h"
2324
#include "llvm/CAS/CachingOnDiskFileSystem.h"
2425
#include "llvm/CAS/HierarchicalTreeBuilder.h"
@@ -248,10 +249,15 @@ int llvm::TableGenMain(const char *argv0, TableGenMainFn *MainFn) {
248249
namespace {
249250
struct TableGenCache {
250251
std::unique_ptr<cas::CASDB> CAS;
252+
std::unique_ptr<cas::ActionCache> Cache;
251253
Optional<cas::CASID> ExecutableID;
252254
Optional<cas::CASID> IncludesTreeID;
253-
Optional<cas::CASID> ActionID;
254-
Optional<cas::CASID> ResultID;
255+
256+
SmallVector<cas::UniqueIDRef> ActionInputs;
257+
SmallString<256> SerializedCommandLine;
258+
Optional<cas::ActionDescription> Action;
259+
260+
Optional<cas::UniqueIDRef> ResultID;
255261
Optional<cas::CASID> MainFileID;
256262
std::unique_ptr<MemoryBuffer> MainFile;
257263
Optional<std::string> OriginalInputFilename;
@@ -264,7 +270,7 @@ struct TableGenCache {
264270
~TableGenCache() { CreateDependencyFilePM = nullptr; }
265271

266272
Expected<cas::CASID> createExecutableBlob(StringRef Argv0);
267-
Expected<cas::CASID> createCommandLineBlob(ArrayRef<const char *> Args);
273+
void serializeCommandLine(ArrayRef<const char *> Args);
268274
Error createAction(ArrayRef<const char *> Args);
269275

270276
Error lookupCachedResult(ArrayRef<const char *> Args);
@@ -295,15 +301,12 @@ Expected<cas::CASID> TableGenCache::createExecutableBlob(StringRef Argv0) {
295301
return *Blob;
296302
}
297303

298-
Expected<cas::CASID>
299-
TableGenCache::createCommandLineBlob(ArrayRef<const char *> Args) {
300-
SmallString<1024> CommandLine;
301-
302-
// Use raw_svector_stream since it doesn't buffer.
303-
raw_svector_ostream OS(CommandLine);
304+
void TableGenCache::serializeCommandLine(ArrayRef<const char *> Args) {
305+
assert(SerializedCommandLine.empty());
306+
raw_svector_ostream OS(SerializedCommandLine);
304307
auto serializeArg = [&](StringRef Arg) {
305308
OS << Arg;
306-
CommandLine.push_back(0);
309+
SerializedCommandLine.push_back(0);
307310
};
308311
serializeArg(sys::path::filename(Args[0]));
309312
Args = Args.drop_front();
@@ -340,41 +343,37 @@ TableGenCache::createCommandLineBlob(ArrayRef<const char *> Args) {
340343
serializeArg(Args.front());
341344
Args = Args.drop_front();
342345
}
343-
344-
Expected<cas::BlobRef> Blob = CAS->createBlob(CommandLine);
345-
if (!Blob)
346-
return Blob.takeError();
347-
return *Blob;
348346
}
349347

350348
Error TableGenCache::createAction(ArrayRef<const char *> Args) {
351-
Expected<cas::CASID> CommandLineID = createCommandLineBlob(Args);
352-
if (!CommandLineID)
353-
return CommandLineID.takeError();
354-
355-
cas::HierarchicalTreeBuilder Builder;
356-
Builder.push(*IncludesTreeID, cas::TreeEntry::Tree, "includes");
357-
Builder.push(*MainFileID, cas::TreeEntry::Regular, "input");
358-
Builder.push(*ExecutableID, cas::TreeEntry::Regular, "executable");
359-
Builder.push(*CommandLineID, cas::TreeEntry::Regular, "command-line");
360-
Expected<cas::TreeRef> Tree = Builder.create(*CAS);
361-
if (!Tree)
362-
return Tree.takeError();
363-
ActionID = *Tree;
349+
assert(!Action);
350+
serializeCommandLine(Args);
351+
352+
assert(ActionInputs.empty());
353+
ActionInputs.push_back(CAS->getUniqueID(*IncludesTreeID));
354+
ActionInputs.push_back(CAS->getUniqueID(*MainFileID));
355+
ActionInputs.push_back(CAS->getUniqueID(*ExecutableID));
356+
Action.emplace("llvm::tablegen::generate", ActionInputs,
357+
SerializedCommandLine);
364358
return Error::success();
365359
}
366360

367361
Error TableGenCache::lookupCachedResult(ArrayRef<const char *> Args) {
368362
if (Error E =
369363
cas::createOnDiskCAS(cas::getDefaultOnDiskCASPath()).moveInto(CAS))
370364
return E;
365+
if (Error E = cas::createOnDiskActionCache(
366+
CAS->getNamespace(), cas::getDefaultOnDiskActionCachePath())
367+
.moveInto(Cache))
368+
return E;
371369

372370
if (Error E = createExecutableBlob(Args[0]).moveInto(ExecutableID))
373371
return E;
374372

375373
OriginalInputFilename = InputFilename.getValue();
376-
Expected<ScanIncludesResult> Scan = scanIncludesAndRemap(
377-
*CAS, *ExecutableID, InputFilename, *&IncludeDirs, PrefixMappings);
374+
Expected<ScanIncludesResult> Scan =
375+
scanIncludesAndRemap(*CAS, *Cache, *ExecutableID, InputFilename,
376+
*&IncludeDirs, PrefixMappings);
378377
if (!Scan)
379378
return Scan.takeError();
380379

@@ -387,9 +386,7 @@ Error TableGenCache::lookupCachedResult(ArrayRef<const char *> Args) {
387386
if (Error E = createAction(Args))
388387
return E;
389388

390-
// Not an error for the result to be missing.
391-
ResultID = expectedToOptional(CAS->getCachedResult(*ActionID));
392-
return Error::success();
389+
return Cache->get(*Action, ResultID);
393390
}
394391

395392
namespace {
@@ -427,7 +424,7 @@ Error TableGenCache::computeResult(TableGenMainFn *MainFn) {
427424
SmallString<256> DependStorage;
428425

429426
CapturedDiagnostics Diags;
430-
if (ActionID) {
427+
if (Action) {
431428
assert(IncludesTreeID && "Expected an input tree...");
432429
if (auto FS = cas::createCASFileSystem(*CAS, *IncludesTreeID))
433430
SrcMgr.setFileSystem(std::move(*FS));
@@ -448,7 +445,7 @@ Error TableGenCache::computeResult(TableGenMainFn *MainFn) {
448445
return E;
449446

450447
// Caching not turned on.
451-
if (!ActionID)
448+
if (!Action)
452449
return Error::success();
453450

454451
cas::HierarchicalTreeBuilder Builder;
@@ -472,13 +469,13 @@ Error TableGenCache::computeResult(TableGenMainFn *MainFn) {
472469
Expected<cas::TreeRef> Tree = Builder.create(*CAS);
473470
if (!Tree)
474471
return Tree.takeError();
475-
return CAS->putCachedResult(*ActionID, *Tree);
472+
return Cache->put(*Action, CAS->getUniqueID(*Tree));
476473
}
477474

478475
Error TableGenCache::replayResult() {
479476
assert(ResultID && "Need a result!");
480477

481-
Expected<cas::TreeRef> Tree = CAS->getTree(*ResultID);
478+
Expected<cas::TreeRef> Tree = CAS->getTree(CAS->getCASID(*ResultID));
482479
if (!Tree)
483480
return Tree.takeError();
484481

llvm/lib/TableGen/ScanDependencies.cpp

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/TableGen/ScanDependencies.h"
10+
#include "llvm/CAS/ActionCache.h"
1011
#include "llvm/CAS/CachingOnDiskFileSystem.h"
1112
#include "llvm/Support/MemoryBuffer.h"
1213
#include "llvm/Support/PrefixMapper.h"
@@ -83,7 +84,8 @@ fetchCachedIncludedFiles(cas::CASDB &CAS, cas::CASID ID,
8384
return Error::success();
8485
}
8586

86-
static Error computeIncludedFiles(cas::CASDB &CAS, cas::CASID Key,
87+
static Error computeIncludedFiles(cas::CASDB &CAS, cas::ActionCache &Cache,
88+
const cas::ActionDescription &Action,
8789
StringRef Input,
8890
SmallVectorImpl<StringRef> &IncludedFiles) {
8991
SmallString<256> ResultToCache;
@@ -93,24 +95,20 @@ static Error computeIncludedFiles(cas::CASDB &CAS, cas::CASID Key,
9395
Expected<cas::BlobRef> ExpectedResult = CAS.createBlob(ResultToCache);
9496
if (!ExpectedResult)
9597
return ExpectedResult.takeError();
96-
if (Error E = CAS.putCachedResult(Key, *ExpectedResult))
97-
return E;
98-
return Error::success();
98+
return Cache.put(Action, CAS.getUniqueID(*ExpectedResult));
9999
}
100100

101-
Error tablegen::scanTextForIncludes(cas::CASDB &CAS, cas::CASID ExecID,
102-
const cas::BlobRef &Blob,
101+
Error tablegen::scanTextForIncludes(cas::CASDB &CAS, cas::ActionCache &Cache,
102+
cas::CASID ExecID, const cas::BlobRef &Blob,
103103
SmallVectorImpl<StringRef> &Includes) {
104-
constexpr StringLiteral CacheKeyData = "llvm::tablegen::scanTextForIncludes";
105-
106-
Expected<cas::NodeRef> Key = CAS.createNode({ExecID, Blob}, CacheKeyData);
107-
if (!Key)
108-
return Key.takeError();
109-
110-
if (Optional<cas::CASID> ResultID =
111-
expectedToOptional(CAS.getCachedResult(*Key)))
112-
return fetchCachedIncludedFiles(CAS, *ResultID, Includes);
113-
return computeIncludedFiles(CAS, *Key, Blob.getData(), Includes);
104+
cas::UniqueIDRef Inputs[] = {CAS.getUniqueID(ExecID), CAS.getUniqueID(Blob)};
105+
cas::ActionDescription Action("llvm::tablegen::scanTextForIncludes", Inputs);
106+
Optional<cas::UniqueIDRef> ResultID;
107+
if (Error E = Cache.get(Action, ResultID))
108+
return E;
109+
if (ResultID)
110+
return fetchCachedIncludedFiles(CAS, CAS.getCASID(*ResultID), Includes);
111+
return computeIncludedFiles(CAS, Cache, Action, Blob.getData(), Includes);
114112
}
115113

116114
Optional<cas::CASID>
@@ -132,7 +130,8 @@ tablegen::lookupIncludeID(cas::CachingOnDiskFileSystem &FS,
132130
return ID;
133131
}
134132

135-
Error tablegen::accessAllIncludes(cas::CachingOnDiskFileSystem &FS,
133+
Error tablegen::accessAllIncludes(cas::ActionCache &Cache,
134+
cas::CachingOnDiskFileSystem &FS,
136135
cas::CASID ExecID,
137136
ArrayRef<std::string> IncludeDirs,
138137
const cas::BlobRef &MainFileBlob) {
@@ -157,8 +156,8 @@ Error tablegen::accessAllIncludes(cas::CachingOnDiskFileSystem &FS,
157156
SmallVector<StringRef> IncludedFiles;
158157
while (!Worklist.empty()) {
159158
IncludedFiles.clear();
160-
if (Error E = scanTextForIncludes(CAS, ExecID, Worklist.pop_back_val(),
161-
IncludedFiles))
159+
if (Error E = scanTextForIncludes(CAS, Cache, ExecID,
160+
Worklist.pop_back_val(), IncludedFiles))
162161
return E;
163162

164163
// Add included files to the worklist. Ignore files not found, since the
@@ -199,10 +198,12 @@ Error tablegen::createMainFileError(StringRef MainFilename,
199198
"': " + EC.message());
200199
}
201200

202-
Expected<ScanIncludesResult> tablegen::scanIncludes(
203-
cas::CASDB &CAS, cas::CASID ExecID, StringRef MainFilename,
204-
ArrayRef<std::string> IncludeDirs, ArrayRef<MappedPrefix> PrefixMappings,
205-
Optional<TreePathPrefixMapper> *CapturedPM) {
201+
Expected<ScanIncludesResult>
202+
tablegen::scanIncludes(cas::CASDB &CAS, cas::ActionCache &Cache,
203+
cas::CASID ExecID, StringRef MainFilename,
204+
ArrayRef<std::string> IncludeDirs,
205+
ArrayRef<MappedPrefix> PrefixMappings,
206+
Optional<TreePathPrefixMapper> *CapturedPM) {
206207
IntrusiveRefCntPtr<cas::CachingOnDiskFileSystem> FS;
207208
if (Error E = cas::createCachingOnDiskFileSystem(CAS).moveInto(FS))
208209
return std::move(E);
@@ -213,7 +214,7 @@ Expected<ScanIncludesResult> tablegen::scanIncludes(
213214
return MainBlob.takeError();
214215

215216
// Helper for adding to the worklist.
216-
if (Error E = accessAllIncludes(*FS, ExecID, IncludeDirs, *MainBlob))
217+
if (Error E = accessAllIncludes(Cache, *FS, ExecID, IncludeDirs, *MainBlob))
217218
return std::move(E);
218219

219220
Optional<TreePathPrefixMapper> LocalPM;
@@ -236,13 +237,13 @@ Expected<ScanIncludesResult> tablegen::scanIncludes(
236237
}
237238

238239
Expected<ScanIncludesResult>
239-
tablegen::scanIncludesAndRemap(cas::CASDB &CAS, cas::CASID ExecID,
240-
std::string &MainFilename,
240+
tablegen::scanIncludesAndRemap(cas::CASDB &CAS, cas::ActionCache &Cache,
241+
cas::CASID ExecID, std::string &MainFilename,
241242
std::vector<std::string> &IncludeDirs,
242243
ArrayRef<MappedPrefix> PrefixMappings) {
243244
Optional<TreePathPrefixMapper> PM;
244-
auto Result =
245-
scanIncludes(CAS, ExecID, MainFilename, IncludeDirs, PrefixMappings, &PM);
245+
auto Result = scanIncludes(CAS, Cache, ExecID, MainFilename, IncludeDirs,
246+
PrefixMappings, &PM);
246247
if (!Result)
247248
return Result.takeError();
248249

0 commit comments

Comments
 (0)