Commit Graph
35 Commits
Author SHA1 Message Date
Richard Smith 0e6dd7e701 Add MaybeUnformed(T) type. (#5989)
This type has the same object representation as `T`, but always uses a
pointer type as its value representation. No other semantics are
provided for it yet.
2025-09-02 20:50:49 +00:00
Richard Smith 742017c475 Widen integer loads and stores to a multiple of 8 bits. (#5986)
This makes Carbon's loads and stores ABI-compatible with Clang's for
`bool` and `_BitInt(N)`.
2025-08-26 21:49:24 +00:00
Richard Smith 816d4589cd Make use of new ArrayRef::consume_* functions. (#5975)
Minor code simplifications.
2025-08-21 21:41:53 +00:00
694c00c7eb Make Core.Float a class. Add missing builtins for float support. (#5932)
Add missing builtins for float compound assignment, for building a
FloatType, and for converting a float literal to FloatType. Switch
`Core.Float` to being a class and add impls for the various
floating-point operators.

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2025-08-11 21:01:34 +00:00
37d5046ceb Support parse/check/lower for char (#5901)
toolchain/check/testdata/builtins/char/basics.carbon and
toolchain/lower/testdata/builtins/char.carbon are probably the most
interesting tests here. The parse tests is required because this adds a
new node kind, and we need coverage of it; but the attached info is
minor. There's a fair amount of test churn here because I'm adding the
Core.Char and Core.CharLiteral types as new singletons.

My intent here is that `CharId` is always a unicode code point, even
when the type is a `Char` and thus must be a single UTF-8 code unit
(single byte). This mainly means the stored value of a `CharValue` can
be printed internally without knowing the type.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-08-06 20:39:01 +00:00
Jon Ross-Perkins 0722dab0ef Reimplement destroy as an interface (#5678)
This changes `Destroy` to use an interface for its implementation.

Note that this change includes a lot of test updates. Even when
`Destroy` is a no-op, it still causes code generation as part of
determining that.

Originally I was trying to use ranges to cut down the scope of this, and
to a degree I think they have. But a flipside here is that cases where
no destructors should be generated -- particularly globals -- would be
needed to completely remove destructor calls. Even for ranges, the range
can often include the destructor placement. So I've shifted
frame-of-thought a little: accept a bunch of destructor churn, because
destructors are needed and will be prevalent. The verbosity is a feature
of the design to make desugaring apparent in IR, not a bug.
2025-06-27 21:57:14 +00:00
Richard SmithandGeoff Romer 7215302a27 Clean up and extend support for cross-file lowering of specific functions. (#5688)
Update remaining parts of lowering, in particular the lowering of
aggregates, to handle lowering within a specific from a different file
than its generic. Look up information about a type in the current
specific and in its file rather than performing lookups for the type in
the generic and its file.

Remove or fix all remaining uses of raw `TypeId` in
lower/function_context and lower/handle*, so that the type from the
specific is consistently always used when lowering a specific function.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-06-24 17:22:48 +00:00
Richard Smith 4e5dccdbf7 When making a direct call to a thunk, inline the call in SemIR. (#5642)
This preserves the constant values of the arguments to the thunk, which
is important if the thunk requires conversion of an `IntLiteral` to some
other type. This should become unnecessary once we have form support,
but avoiding the indirection through a thunk function seems valuable
even once that support is in place.

To support this, track whether a function is a thunk on the Function
object, and if so, what the callee of the thunk is. This information is
also included in formatted SemIR when dumping the thunk.
2025-06-11 21:34:01 +00:00
Richard Smith 14e4f219b1 Support lowering specifics for an imported generic function. (#5475)
When lowering a specific function whose generic was defined in a
different file, switch to that other file's `FileContext` and lower the
generic there. Also pass the `FileContext` corresponding to the specific
into the `FunctionContext`, and use that `FileContext` for resolving
requests for constants and types from the specific.
2025-06-02 21:14:34 +00:00
Alina Sbirlea 77afd0678b Prototype for coalescing equivalent specifics of the same generic. (#5314)
This is a working version for coalescing equivalent specifics of the
same generic, with *many* things to add and improve.
2025-05-29 22:24:13 +00:00
Boaz Brickner 4901db832c Deduplicate getting the function in HandleInst() for Call (#5515)
Part of #5514.
2025-05-22 15:45:10 +00:00
Richard Smith b5ae988a08 Add builtins for compound assignment operators. (#5335)
Provide builtins for compound assignments instead of defining them in
the prelude as a use of a binary operator and an assignment. This allows
us to lower compound assignment directly to LLVM operations instead of
producing a function call. In the short term this also allows us to
define a type-generic compound assignment in the prelude.
2025-04-21 20:38:11 +00:00
Thomas Köppe bf32da8dad Add missing standard library header inclusions (#5316)
Discovered by clang-tidy.
2025-04-17 15:37:57 +00:00
David Blaikie f45a632d77 Implement virtual call dispatch (#5308)
Adds a `virtual_index` to `SemIR::Function` used to determine which
vtable slot
to use when calling the given function.

Then use that to lower the function call to use the vtable and
specifically the
relative vtable ABI to match the vtable entries.
2025-04-17 14:42:30 +00:00
Jon Ross-PerkinsandChandler Carruth b49e89e97e Add a no-op builtin function which shouldn't generate code. (#5306)
This is part of a broader plan to have noop destructor functions for
trivial destruction.

Note this emits a SemIR call (`%no_op: init %empty_tuple.type = call
%NoOp.ref() [concrete = constants.%empty_tuple]`), but not LLVM IR. My
thought was this was probably okay, since even though it'll be a little
spammy with destructor calls, the flipside is there'll probably already
be a fair amount for the name reference, and this at least shows when
the call is injected (and discarded).

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-04-15 00:33:39 +00:00
Alina Sbirlea 7da972b773 Create a single global for the PrintInt format string. (#5275)
Create a single global for the PrintInt format string. Cleaner tests.
2025-04-09 16:47:32 +00:00
Richard Smith c33adfafd3 Replace GetTypeInSpecific with GetTypeOfInstInSpecific. (#5232)
Reduce usage of `GetConstantInSpecific` to a single caller in constant
evaluation, with a TODO to remove that.

This gets us closer to being able to fully perform type-checking against
abstract types instead of types anchored within a particular generic.
2025-04-02 22:52:11 +00:00
Alina Sbirlea d3869a529b Continue: emit function definitions for specifics. (#5068)
Resolve instruction id depending on the context from which a function is
called.

Calling a function in a function context that does not have a definition
emitted before reaching lowering will cause a crash. This needs a change
in check/eval layer.
2025-03-06 17:40:35 +00:00
Alina Sbirlea 4e21c0c1fc Basic lowering generic function definitions. (#5016)
Resolve the specific type for the callee, to lower the proper specific
function called.
2025-03-04 18:41:29 +00:00
Dana JansensandJon Ross-Perkins 129cf35d78 Support BitAnd operator between facet types (#5022)
Doing so results in TODOs in the resulting semir, since we don't handle
combining the facet types together properly or doing lookup into them.
There's a test added demonstrating this, which will be made to work in
followups.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-02-27 17:53:48 +00:00
Jon Ross-Perkins 6b5eb1a101 Id::Invalid -> Id::None (#4834)
High level, replacing `Id::Invalid` with `Id::None` and `Id::is_valid`
with `Id::has_value` for clarity, as discussed
[here](https://discord.com/channels/655572317891461132/655578254970716160/1331664574545395794).
The `IntId` refactoring is needed together with `AnyIdBase` because it's
also used with `ValueStore`.

Note, trying to be careful not to rewrite `EnumBase::InvalidIndex`, or
`is_valid` in general (e.g., `IdKind::is_valid`).

I've tried to sequence commits here:

1. Automatic replacements:

- `((?:Id|Index)(?: |::|\(|Base(?:\(|::)))Invalid((?:Index)?\W)` ->
`$1None$2`
  - `<invalid>` -> `<none>`
  - `InvalidNodeId` -> `NoneNodeId`
  - `/\*invalid\*/` -> `/*none*/`
  - `id((?:_|\(\))(?:\.|->))is_valid` -> `id$1has_value`

2. Manual edits:

  - In `int.h` and `int_test.cpp`
    - `IntT` has `is_value`, which I'm renaming to `is_embedded_value`.
    - Manual edits to comments in this file.
  - `AnyIdBase` and `IdBase`
- Declaration of `is_valid` -> `has_value`, `InvalidIndex` ->
`NoneIndex`.
  - In `ids.h` and `ids.cpp`
    - `is_valid` -> `has_value`
- `// An explicitly invalid ID.` -> `// An ID with no value.`; similar
for index
    - Various math on `InvalidIndex` -> `NoneIndex`
    - Various mentions of "valid" in comments
  - In `value_store.h`, for `IdT::Invalid`, plus one comment
- In `impl.h` and `tokenized_buffer.h`, we had different initialization
of `::None` values (versus `ids.h` syntax) that I fixed manually.
  - Spot checks to compile
- Particularly where `is_valid` replacements didn't catch spots due to
different naming.

3. Autoupdate tests

4. verbose.carbon (NOAUTOUPDATE)

5. Comment spot checks

Note there are probably other mentions of "Invalid" that should be swept
up, but I'd like to argue for merging and separating out remaining
cleanup since this is so sweeping (and likely to hit merge conflicts
from churn). We'll probably have lingering mentions of "invalid" for a
bit regardless, just because there are uses of "invalid" in non-Id APIs.
2025-01-22 23:15:00 +00:00
Richard Smith 246ec785df Add support for converting between integer types (#4753)
Add a builtin `"int.convert"` supporting unchecked conversions between
different integer types. This performs a truncation, zero-extension, or
sign-extension, depending on the widths of the operands and the
signedness of the source type. Add explicit `As` support to the prelude.
No implicit conversions are supported yet as we don't have a way to
express the constraint that we can only implicitly convert to wider
types.
2025-01-08 08:25:20 +00:00
Richard Smith 4a7aefefaa Add support for operators on Core.IntLiteral. (#4716)
Fixes integer builtins to produce the correct values (and not
CHECK-fail) when used on integer literals. Also adds impls to the
prelude to use the new builtins to perform operations on integer
literals.

Perhaps most importantly, this allows directly initializing `i32` values
with negative numbers, as the negation operation on integer literals now
works.

For testing I've added tests for use of literals with one operator in
each class (addition, multiplication, ordering, bitwise, etc) for which
there are distinct rules or overflow behavior, rather than exhaustively
testing all the combinations. This is aimed at finding a good tradeoff
between maintainability of the tests and thorough test coverage.

Also fixes lowering of heterogeneous shifts and comparisons. These are
currently disabled when one of the operands is an integer literal, but
we may want to allow that when the integer literal operand has a known
constant value.
2024-12-31 06:36:43 +00:00
Richard Smith c1590f886a Add equality comparison support for bool. (#4701) 2024-12-18 00:47:03 +00:00
Richard Smith 3645143e27 Add solutions for advent of code 2024 day 1 to examples/. (#4673)
In order to support these examples, this adds two new builtins to the
toolchain: `print.char` and `read.char`, which map to the libc functions
`putchar` and `getchar`.
2024-12-17 00:47:51 +00:00
Richard SmithandJon Ross-Perkins e2ae5f212c Remove the special case for i32. (#4543)
For the few remaining uses of the builtin `i32` type, manually build an
`IntType(Signed, 32)` value instead. These are:

- The return type of `Run`.
- The type that int literals in an `if` expression are converted into.
- The type of an array index expression.

We should consider converting those three cases away from `i32` over
time.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-11-18 23:19:36 +00:00
Richard Smith cbd88e5c72 Add builtin for performing checked conversion between integer types. (#4523)
As a prerequisite for switching the type of int literals to be the
`IntLiteral` type, add support for performing conversions of in-bounds
integer constant values to other integer types in which they fit.

This incidentally is our first compile-time-only builtin function, so
add very minimal support for compile-time-only functions while we're
here.
2024-11-14 00:27:40 +00:00
Richard Smith 44fe65fbe5 Rename BigInt to IntLiteral. (#4476)
In preparation for changing the type of integer literals to
`IntLiteral`.
2024-11-02 02:09:10 +00:00
Richard Smith a02dfe0226 Superficial support for Core.BigInt type (#4414)
Add a `Core.BigInt` type and a corresponding builtin type in the
toolchain. See [corresponding section of the
design](https://docs.carbon-lang.dev/docs/design/expressions/literals.html#defined-types).

So far this type is not used for anything, and there is no way to create
an instance of it.
2024-10-16 23:27:01 +00:00
Richard Smith 851ef2c517 Initial, very rough lowering for calls to specific functions and specific function declarations. (#4399)
Generate declarations of specific functions on demand. Definitions are
not emitted yet, and I'm using a temporary, known-broken scheme for name
mangling.
2024-10-10 23:37:16 +00:00
4845f40dff Switch CARBON_CHECK to a format string API (#4285)
This switches `DCHECK` and `FATAL` as well.

The goal is to reduce the code size impact of these assertions so that
we can keep more of them enabled. Currently, the largest cost I see from
`CHECK` is not the actual check or the cold code itself, but actually
the failure to inline trivial functions due to the presence of the cold
code. This means that our goal isn't to reduce apparent code size in the
final binary but the LLVM IR cost assessed for these routines in the
inliner, which closely correlates with code size but is a bit different.

As discussed in #4283, experimentation shows that a single function call
with a minimal number of arguments is the lowest cost model for these.
This is easily achieved with a format-string API that internally uses
`llvm::formatv`. This PR is essentially the `CHECK` version of #4283.

However, the check macros are substantially harder to make work with
both format strings and streaming because they also take a condition.
Also, unexpectedly, I was very successful at devising a regular
expression based automated rewrite from the streaming to the format
string form with only low 10s of manual fixes. This includes compacting
strings broken up across lines, etc. Given how well that went, I've
prepared this PR which just directly switches to the format string API
and migrate everything to use it.

One nice side-effect is that the format string approach ends up greatly
simplifying the implementation here as well.

This is ... *shockingly* effective. Parsing speeds up by more than 3%
with just this change. And checking speeds up by **8%** with this change
alone:
```
BM_CompileAPIFileDenseDecls<Phase::Parse>/256      86.3µs ± 1%  82.9µs ± 1%  -3.94%  (p=0.000 n=17+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/1024      431µs ± 1%   415µs ± 1%  -3.76%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/4096     1.77ms ± 1%  1.71ms ± 1%  -3.18%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/16384    7.44ms ± 1%  7.17ms ± 2%  -3.56%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Parse>/65536    30.7ms ± 1%  29.7ms ± 1%  -3.15%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Parse>/262144    131ms ± 1%   127ms ± 1%  -2.81%  (p=0.000 n=18+18)
BM_CompileAPIFileDenseDecls<Phase::Check>/256       878µs ± 2%   800µs ± 1%  -8.91%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/1024     1.88ms ± 2%  1.72ms ± 1%  -8.56%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/4096     5.78ms ± 2%  5.28ms ± 1%  -8.70%  (p=0.000 n=20+18)
BM_CompileAPIFileDenseDecls<Phase::Check>/16384    21.9ms ± 1%  20.1ms ± 1%  -8.02%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/65536    90.4ms ± 2%  83.1ms ± 1%  -8.04%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/262144    381ms ± 2%   352ms ± 1%  -7.79%  (p=0.000 n=19+19)
```

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2024-09-12 16:42:08 +00:00
Richard Smith 37a8bfa488 Refactor ReturnTypeInfo and InitRepr. (#4169)
Rename `ReturnInfo` to `ReturnTypeInfo`. Move it and `InitRepr` into
`type_info.h` alongside `ValueRepr`. Replace `ReturnSlot` with
`InitRepr`, and extend `InitRepr` to be able to represent the
incomplete-type case instead of CHECK-failing. Remove `has_return_slot`
from `InitRepr` and instead only provide that as part of
`ReturnTypeInfo`.
2024-07-25 21:41:33 +00:00
Jon Ross-Perkins 6d2d1cf7ca Refactor lower handlers to use overloads. (#4120)
Renames Lower::Handle* to Lower::LowerFunctionInst. This allows writing
a templated handler for instructions, moving code out of the macro
expansion and removing some of the redundancy in things like
`HandleAddrOf(..., SemIR::AddrOf inst)`
2024-07-11 22:12:04 +00:00
Jon Ross-Perkins a81d67c629 Rename Builtin to BuiltinInst, particularly to get BuiltinInstKind (#4115)
I'm trying to increase the distinction between BuiltinKind and
BuiltinFunctionKind. BuiltinKind is for instructions,
BuiltinFunctionKind is for function definitions. To get to this point,
I'm doing a few changes:

- BuiltinKind -> BuiltinInstKind
    - builtin_kind.* -> builtin_inst_kind.*: filename consistency
- Builtin -> BuiltinInst: mainly for consistency with the above
- Builtin::builtin_kind -> BuiltinInst::builtin_inst_kind: somewhat
repetitive but seems like a consistent edit
- Function::builtin_kind -> Function::builtin_function_kind: seems a
useful distinction

I'm leaving alone things like (and mentioning in case there's a desire
for more renames):

- InstId::BuiltinError, InstId::ForBuiltin: these I think are more
apparent because they're directly associated with Inst.
- GetBuiltinICmpPredicate in lowering: maybe builtin function handling
should be in its own file, but these local names don't feel problematic
to me.
- GetBuiltinType, BuildBuiltinValueRepr, PerformBuiltinIntComparison:
similar to the above, names don't feel too problematic
2024-07-11 18:24:17 +00:00
Jon Ross-Perkins a4ef5dd591 Move Lower::HandleCall out to its own file. (#4116)
This is over half of handle.cpp right now, due to builtin function
logic.
2024-07-09 21:46:54 +00:00