Commit Graph
18 Commits
Author SHA1 Message Date
Chandler Carruth e041afd98d Centralize benchmarking infrastructure and the toolchain-wide benchmarks (#7212)
The benchmarks themselves aren't really specific to `driver`.

Keeping the source generation near to the primary use case of
benchmarking also seems like a more discoverable location.

I feel a little bad doing this reorganization right after I gave a talk
with links to a bunch of this code, but seems good to reorganize a bit
before doing some work to extend things now that we have full standard
library support for C++ benchmarking and other improvements.

Assisted-by: Antigravity with Gemini
2026-05-15 20:17:23 +00:00
Jon Ross-Perkins fbe917b949 Create a UnifiedDiffMatcher to make golden test failures easier to understand (#6897)
Right now I think everyone has the habit of doing an autoupdate then
using source control for a diff. This is offering an option of better
diff output from the test.

For example:

```
TEST: toolchain/driver/testdata/fail_flush_errors.carbon !
Ran 1 tests in 81 ms wall time, 8 ms across threads
testing/file_test/file_test_base.cpp:264: Failure
Value of: SplitOutput(test_file.actual_stderr)
Expected: matches elements with union diff
  Actual: { "fail_flush_errors.carbon:22:3: error: name `undeclared1` not found [NameNotFound]", "  undeclared1;", "  ^~~~~~~~~~~", "", "fail_flush_errors.carbon:31:3: error: `Core.String` implicitly referenced here, but package `Core` not found [CoreNotFound]", "  \"undec\\x6Cared2\";", "  ^~~~~~~~~~~~~~~~", "", "fail_flush_errors.carbon:35:3: error: name `undeclared2` not found [NameNotFound]", "  undeclared2;", "  ^~~~~~~~~~~", "", "fail_flush_errors.carbon:43:3: error: name `undeclared3` not found [NameNotFound]", "  undeclared3;", "  ^~~~~~~~~~~", "", "" }, union diff (- expected, + actual):
=== diff in expected elements 0 to 2:
+ fail_flush_errors.carbon:22:3: error: name `undeclared1` not found [NameNotFound]
    undeclared1;
    ^~~~~~~~~~~

=== diff in expected elements 4 to 9:
    "undec\x6Cared2";
    ^~~~~~~~~~~~~~~~

+ fail_flush_errors.carbon:35:3: error: name `undeclared2` not found [NameNotFound]
    undeclared2;
    ^~~~~~~~~~~

=== diff end

Stack trace:
  0x55e476d29efd: Carbon::Testing::FileTestCase::TestBody()
  0x55e476dbd1f2: testing::internal::HandleExceptionsInMethodIfSupported<>()
  0x55e476dbcf57: testing::Test::Run()
  0x55e476dbf0bf: testing::TestInfo::Run()
... Google Test internal frames ...


To test this file alone, run:
  bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/driver/testdata/fail_flush_errors.carbon

testing/file_test/file_test_base.cpp:277: Failure
Failed
Autoupdate would make changes to the file content. Run:
bazel run //toolchain/testing:file_test -- --autoupdate --file_tests=toolchain/driver/testdata/fail_flush_errors.carbon
Stack trace:
  0x55e476d2a5f0: Carbon::Testing::FileTestCase::TestBody()
  0x55e476dbd1f2: testing::internal::HandleExceptionsInMethodIfSupported<>()
  0x55e476dbcf57: testing::Test::Run()
  0x55e476dbf0bf: testing::TestInfo::Run()
... Google Test internal frames ...

[  FAILED  ] ToolchainFileTest.toolchain/driver/testdata/fail_flush_errors.carbon, where GetParam() = toolchain/driver/testdata/fail_flush_errors.carbon (93 ms)
```

Assisted-by: Google Antigravity with Gemini
2026-03-13 21:39:21 +00:00
Chandler Carruth 5d0d443c98 Move the :install_paths library to //toolchain/base (#6457)
Previously this was kept in `//toolchain/install` so it would be near to
the code that actually defines the installation layout. However, that
creates somewhat unfortunate dependency cycles between
`//toolchain/install` and other directories. Exacerbating this, a
subsequent PR is likely to add dependencies on it from
`//toolchain/base` itself that suggests that is the correct layering.

This PR just moves the code mechanically with as few other edits as
possible.
2025-12-03 17:14:34 +00:00
Jon Ross-PerkinsandChandler Carruth 59619fa8eb Make driver fuzzing more robust for clang flags (#5845)
I'm not sure the target in use here will reliably crash over time, but
it does right now, and that seems reasonable...?

Example crash:

```
file_test: external/+llvm_project+llvm-project/clang/lib/Driver/ToolChains/Darwin.h:505: bool clang::driver::toolchains::Darwin::isTargetWatchOSBased() const: Assertion `TargetInitialized && "Target not initialized!"' failed.
```

Stack fragment:

```
...
#10 0x0000562ba07dec33 isTargetWatchOSBased /proc/self/cwd/external/+llvm_project+llvm-project/clang/lib/Driver/ToolChains/Darwin.h:505:5
#11 0x0000562ba07dec33 clang::driver::toolchains::DarwinClang::addClangWarningOptions(llvm::SmallVector<char const*, 16u>&) const /proc/self/cwd/external/+llvm_project+llvm-project/clang/lib/Driver/ToolChains/Darwin.cpp:1188:7
#12 0x0000562ba072afc7 clang::driver::tools::Clang::ConstructJob(clang::driver::Compilation&, clang::driver::JobAction const&, clang::driver::InputInfo const&, llvm::SmallVector<clang::driver::InputInfo, 4u> const&, llvm::opt::ArgList const&, char const*) const /proc/self/cwd/external/+llvm_project+llvm-project/clang/lib/Driver/ToolChains/Clang.cpp:0:6
#13 0x0000562ba06306d8 clang::driver::Driver::BuildJobsForActionNoCache(clang::driver::Compilation&, clang::driver::Action const*, clang::driver::ToolChain const*, llvm::StringRef, bool, bool, char const*, std::__1::map<std::__1::pair<clang::driver::Action const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, llvm::SmallVector<clang::driver::InputInfo, 4u>, std::__1::less<std::__1::pair<clang::driver::Action const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>, std::__1::allocator<std::__1::pair<std::__1::pair<clang::driver::Action const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> const, llvm::SmallVector<clang::driver::InputInfo, 4u>>>>&, clang::driver::Action::OffloadKind) const /proc/self/cwd/external/+llvm_project+llvm-project/clang/lib/Driver/Driver.cpp:6083:10
...
#28 0x0000562b9e479d1f Carbon::BuildClangInvocation(Carbon::Diagnostics::Consumer&, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>) /proc/self/cwd/toolchain/base/clang_invocation.cpp:103:21
...
```

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-07-24 20:00:41 +00:00
Jon Ross-Perkins 8c3fa80691 Add cc rule wrappers for cc_env (#5277)
Rules executed by bazel don't necessarily have the right environment to
find the symbolizer, which was the intent of `cc_env` setting
`LLVM_SYMBOLIZER_PATH`. So far, this has kind of been a case-by-case
fix, but every so often I'm trying to debug a crash in a test that
doesn't provide it. Rather continuing down this route, instead add
drop-in wrappers for cc rules so that it's hard to forget.

Note `bazel/cc_rules` is intended to mirror `bazel/carbon_rules` and
`bazel/cc_toolchains`, rather than `@rules_cc`.

AFAICT there isn't a great way to add this as a default for the `bazel
run` environment. It's not typically going to be set on its own,
forwarding `$PATH` would be too broad, and the [action
`env_sets`](https://bazel.build/docs/cc-toolchain-config-reference#using-action-config)
I think are not quite what we need (I think those don't include output
execution, only compilation).
2025-04-11 19:58:54 +00:00
Chandler Carruth cf29449faf Move test file writing to our common testing file_helpers (#4971)
This will make it easy to share across tests. Factored out of a change
adding new uses of the file.
2025-02-18 03:27:49 +00:00
Chandler Carruth 151bd14fd3 Refactor stdout and stderr capturing to a library (#4970)
This should make it easy to add more tests which need the specific
behavior here. It also isolates where we reach into GoogleTest's
internals to a single common place.
2025-02-16 16:12:14 +00:00
Jon Ross-PerkinsandRichard Smith 38d25cf622 Share ReadFile in tests (#4967)
Small cleanup for code sharing. Note, `*ReadFile` will trigger a
CHECK-failure on error; the relevant implementations would previously
have failed silently (empty string).

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-02-15 00:17:01 +00:00
Jon Ross-PerkinsandGeoff Romer 4c4c4a4d2c Add RawStringOstream for slightly simpler streaming to strings (#4817)
This adds a RawStringOstream. Versus TestRawOstream, which is
consolidated over to RawStringOstream, it uses a string for storage
instead of a vector, mainly to support move-to-string semantics. Versus
llvm::raw_string_ostream, it owns the string and supports pwrite (which
is needed for driver and its fd_ostream compatibility requirement).

This converts most uses of llvm::raw_string_ostream, leaving behind a
few in InstNamer that explicitly cannot own the string, such as:

```
     llvm::raw_string_ostream(name)
          << "_" << tree.tokens().GetColumnNumber(token);
```

I have this as its own library so that it can use CHECK.

Yes this doesn't save much code, but it's code we repeatedly write.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-01-18 01:11:44 +00:00
Jon Ross-Perkins e382e6fd97 Refactor FindPreludeFiles into InstallPaths (#4268)
From the driver's perspective, `FindPreludeFiles` is closely tied to
`compile`. This makes it difficult to refactor commands without
affecting the test dependencies on `FindPreludeFiles`. `InstallPaths`
seems like a decent home since it is responsible for the install
structure.

I'm switching to an `Error` return to allow callers to choose how to
handle it (e.g., in file tests, we typically don't want the direct error
stream).
2024-09-04 22:22:48 +00:00
Chandler Carruth 72cb9d0d06 Refactor testing exe path and benchmark main handling. (#4216)
Consolidates both main libraries into `//testing/base`, and factors out
the exe path handling for benchmarks and unit tests into a common
library to remove duplication. Refactors how that logic is managed to be
cleaner and avoid a confusing bool that came up in code review.

Updates all the tests and benchmarks that use these. I still need to
update other benchmarks to use the same main, but I wanted to keep this
PR somewhat minimal.

This also fixes a bug noticed in passing that the compilation benchmark
didn't have the required dependency on the benchmark library itself,
just the benchmark main library.
2024-08-14 17:50:08 +00:00
a9c815c9f4 Introduce a source generator and end-to-end compile benchmarks (#4124)
The big addition here is a very, very rough and very early skeleton of a
source code generator framework. This builds upon the lexers identifier
synthesis logic, improving on its framework and wiring it up with the
most rudimentary of source file generation. This is just enough to
roughly replicate my "big API file" source code benchmarks.

The source generation works *very* hard to both vary the structure and
content of the source as much as possible while ensuring the same
*total* amount of each construct is in use, from bytes in identifiers to
line breaks, parameters, etc. This lets us generate randomly structure
inputs that should consistently take the exact same amount of total work
to compile.

The complex identifier synthesis logic from the lexer's benchmark is
moved over here and the lexer uses APIs in the source generator for
identifiers. The other source synthesis in the lexer's benchmark isn't
yet moved over, but should likely be slowly absorbed here as it can be
refactored into a more principled and re-usable form. Some bits may stay
of course if they're just too lexer-specific.

Next, this adds a simple end-to-end compile benchmark for the driver
that directly and much more clearly reproduces all the measurements I've
done manually up until now. It should also be easy to extend to more
patterns over time as we add support to the source generator to produce
those patterns.

Last but not least, I've added a tiny CLI to the source generator so
that you can generate source code manually. This is especially nice for
generating demo source code to actually run through the driver or look
at in an editor. The CLI can also generate C++ source code which lets us
do some minimal comparative benchmarking between Carbon and C++/Clang.

There are huge number of TODOs in the source generation framework. This
is going to be a large ongoing effort I suspect.

There are also a bunch of rough edges I've left to try and get this out
for review sooner. I've left TODOs for refactorings that really need to
be done here, but hoping these can maybe be follow-ups. If not, please
flag and I'll try to layer them on here.

Sample compile benchmark output, nicely showing where we are w.r.t. our
goal speeds (2x behind on lex and check, 5x on parse) at least on a
recent AMD server CPU:
```
------------------------------------------------------------------------------------------------------
Benchmark                                                 Time             CPU   Iterations      Lines
------------------------------------------------------------------------------------------------------
BM_CompileAPIFileDenseDecls<Phase::Lex>/256           29420 ns        29419 ns        22860 6.62847M/s
BM_CompileAPIFileDenseDecls<Phase::Lex>/1024         146130 ns       146128 ns         4840 6.69959M/s
BM_CompileAPIFileDenseDecls<Phase::Lex>/4096         601584 ns       601577 ns         1020 6.69573M/s
BM_CompileAPIFileDenseDecls<Phase::Lex>/16384       2547578 ns      2547313 ns          280   6.404M/s
BM_CompileAPIFileDenseDecls<Phase::Lex>/65536      10816591 ns     10816389 ns           80 6.05193M/s
BM_CompileAPIFileDenseDecls<Phase::Lex>/262144     52191320 ns     52189828 ns           20 5.02261M/s
BM_CompileAPIFileDenseDecls<Phase::Parse>/256        101706 ns       101698 ns         6900 1.91745M/s
BM_CompileAPIFileDenseDecls<Phase::Parse>/1024       512161 ns       512162 ns         1380  1.9115M/s
BM_CompileAPIFileDenseDecls<Phase::Parse>/4096      2078426 ns      2078430 ns          340   1.938M/s
BM_CompileAPIFileDenseDecls<Phase::Parse>/16384     8795786 ns      8795583 ns          100 1.85468M/s
BM_CompileAPIFileDenseDecls<Phase::Parse>/65536    35073596 ns     35072973 ns           20 1.86639M/s
BM_CompileAPIFileDenseDecls<Phase::Parse>/262144  151100688 ns    151097370 ns           20 1.73483M/s
BM_CompileAPIFileDenseDecls<Phase::Check>/256        957059 ns       957049 ns          740 203.751k/s
BM_CompileAPIFileDenseDecls<Phase::Check>/1024      1956134 ns      1955985 ns          360 500.515k/s
BM_CompileAPIFileDenseDecls<Phase::Check>/4096      5797864 ns      5797417 ns          120 694.792k/s
BM_CompileAPIFileDenseDecls<Phase::Check>/16384    21219608 ns     21217584 ns           40 768.843k/s
BM_CompileAPIFileDenseDecls<Phase::Check>/65536    96311116 ns     96302334 ns           20 679.734k/s
BM_CompileAPIFileDenseDecls<Phase::Check>/262144  371637963 ns    371609964 ns           20 705.387k/s
```

Lest someone think this is *bad*, the fact that we're already within 2x
of our rather audacious goals makes me quite happy. =D

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-08-13 19:37:55 +00:00
Chandler Carruth 582b2c04dd Allow GoogleTest tests to locate their executable path. (#3992)
This also factors out the code for doing this location from the driver
to a tiny helper library.

The motivation for this is letting tests locate data files like the
prelude or other files needed by the toolchain more easily. A subsequent
PR will use this heavily in the Clang runner and related logic for
example.
2024-05-28 23:50:57 +00:00
Jon Ross-Perkins a3b1c433be Remove legacy repo_name settings (#3772)
I'd kept these in to separate the bazel module update from the BUILD
file changes, then forgot about it. I think all of these can be cleanly
removed now. I think it's something we should clean up for consistency
with the bazel central repository names; I think it's best to reduce
that divergence.

llvm_zlib and llvm_zstd remain because of how llvm depends on the
particular names.
2024-03-13 22:58:56 +00:00
Richard SmithandJon Ross-Perkins bf8697113a Move llvm::Initialize* calls to main. (#3449)
Per their documentation, the `llvm::Initialize*` functions are only
supposed to be called by the main program, not by a library like
toolchain/codegen. Fixes a hang due to a data race in multithreaded
autoupdate.

Add a utility class `Carbon::InitLLVM` to do the common LLVM
initialization shared by all Carbon tools, optionally including
initializing the LLVM targets. Because the LLVM targets add a lot of
binary size, only initialize them for binaries that opt in by depending
on a new target `//common:all_llvm_targets`.

Also fix `//explorer:file_test` and `//explorer:file_test.trace` to
share a binary rather than linking an identical binary twice.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-07 01:45:47 +00:00
Jonathan B. CoeandChandler Carruth 8c28a0494e Add size="small" to test targets where advised (#3326)
Running `bazel test //...` reported:

```
Test execution time outside of range for MODERATE tests.
Consider setting timeout="short" or size="small".
```

This change adds size="small" to avoid such warnings being reported.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2023-10-24 06:52:00 +00:00
Jon Ross-Perkins 605763d62d Add lint fixes to the buildifier setup. (#3109)
The main motivation for this is to get python loads in using the
`native-py` lint fix. However, enabling that made me wonder, maybe we
should fix in general?

`native-cc` is delayed, but not wholly cancelled (and `native-py`
picking up might indicate `native-cc` won't be too far behind). There's
also some automated fixes for `.append` and dict sorting -- this felt
okay to me, maybe not something to eagerly add but probably not worth
stopping buildifier from fixing (I've noticed the warnings in the past
and had been ignoring them).

Running everything does mean that load orders are sorted automatically
now, which I think is a positive. Most generally, I think these fixes
aren't _harmful_, and having them done automatically seems beneficial:
my biggest concern about `native-py` and `native-cc` was actually that
regressions wouldn't be caught, but this addresses that issue
automatically.
2023-08-22 21:01:42 +00:00
Jon Ross-Perkins fa857e42be Rename //testing/util to base (#3104)
Renaming per #3100
2023-08-15 21:28:56 +00:00