Commit Graph
123 Commits
Author SHA1 Message Date
Richard Smith 9a5f2d734b Include a fingerprint of the specific arguments in mangled names. (#4771)
Instead of including the raw index of the specific, which is unstable
across files and across unrelated changes, use a fingerprint of the
constant values of the specific arguments. This is a placeholder until
we decide on how we want to mangle specific functions.
2025-01-08 20:23:12 +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 SmithandDana Jansens 19182f08aa Compute a fingerprint for constants and import_ref instructions. (#4763)
Use it in the instruction namer to make instruction names more stable
across unrelated changes to the toolchain or the prelude.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-01-07 20:41:44 +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 7d8d59cb7e Make snegate / unegate overflow handling consistent with other builtins. (#4744)
Make `int.snegate` ignore the signedness of its operand and
unconditionally check for signed overflow like all the other `int.s*`
builtins do. Fix the prelude implementation of unary `-` for `Core.UInt`
to use `int.unegate` instead of `int.snegate`.

Fix the test for unsigned negate to actually test negating unsigned
integers, and add some tests that unary `-` also works.
2024-12-26 22:07:47 +00:00
Dana Jansens 9290ee2bcf Use unsigned arithmetic builtins for UInt(N) operations (#4740)
We were mistakenly using the signed builtins, which produce the same
lowering for add/multiply right now, but don't for division and modulus.

When manually flipping SignedOverflowIsUB on, the signed version of add
gains the nsw (no signed wrap) flag, while the unsigned version
(correctly after this change) does not:
```
// CHECK:STDOUT: define i32 @_Cadd_i32.Main(i32 %a, i32 %b) !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT:   %int.sadd = add nsw i32 %a, %b, !dbg !7
// CHECK:STDOUT:   ret i32 %int.sadd, !dbg !8
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @_Cadd_u32.Main(i32 %a, i32 %b) !dbg !9 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT:   %int.uadd = add i32 %a, %b, !dbg !10
// CHECK:STDOUT:   ret i32 %int.uadd, !dbg !11
// CHECK:STDOUT: }
```
2024-12-26 00:36:33 +00:00
Dana Jansensandjonmeow 6cb660f5ad Avoid recursion in InstNamer::CollectNamesInBlock (#4706)
Use a deque to maintain the set of instructions to be walked over. so
that the loop can append more instructions (with their related scope)
during iteration without requiring recursion.

---------

Co-authored-by: jonmeow <jperkins@google.com>
2024-12-20 16:12:06 +00:00
Richard Smith 6fe8e0b5aa Provide generic impls for Core.Int and Core.UInt operations. (#4693)
Instead of providing operations only for `i32`, provide them for all
`iN` and `uN` types.

For now, this excludes the `*Assign`, `Inc` and `Dec` interfaces,
because the implementations for those are defined as Carbon functions
rather than builtins, and we can't yet lower definitions for specific
functions, so converting those to be generic breaks the build for our
examples.
2024-12-19 22:02:18 +00:00
Richard Smith b54a27e9e7 Fix incorrect lowering of mixed constant / non-constant aggregate initialization. (#4704)
We defer lowering initialization with constant values, because the use
of the constant can itself be part of a larger constant that we don't
want to emit. However, when the initialization is for an element of a
non-constant aggregate, we do need to initialize the constant portion.
2024-12-19 01:13:29 +00:00
Richard Smith c1590f886a Add equality comparison support for bool. (#4701) 2024-12-18 00:47:03 +00:00
David Blaikie 4d0a6db49b Abort checking when encountering an invalid parse node (#4700)
Short term solution/block for #4689
2024-12-18 00:19:12 +00:00
Richard Smith c04d62a7d1 Ensure that all allocas are created in the entry block. (#4685)
Non-entry-block allocas will allocate new stack memory each time they're
reached, resulting in leaking stack memory over time for allocas in a
loop. Move all such allocas to the entry block instead, and use an LLVM
intrinsic to mark when the lifetime of the variable actually begins.
2024-12-17 00:55:06 +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 Smith a10c79569e Model Core.Int as a class type (#4644)
Instead of treating `Core.Int` as the toolchain's builtin `IntType`,
model it as a class that adapts the builtin type. This aligns us better
with the intended language model, gives an associated library for
`impl`s involving `Core.Int` to live within, and opens the door adding
member functions to `Core.Int` if we decide that is desirable.
Remarkably it also seems to make the formatted SemIR a little smaller,
because a call to a generic class generates less IR than a call to a
function.
2024-12-16 22:19:23 +00:00
Richard Smith 7b45a28a82 Fix lowering of array indexing with an int literal. (#4686)
Such indexing operations are created by array initialization. Since we
switched integer literals to be of type IntLiteral we've been attempting
to index arrays with the (empty) representation of an IntLiteral rather
than with an actual integer value.
2024-12-14 04:47:32 +00:00
Richard Smith 3e0fdd04eb Lower global variables as global definitions, not global declarations. (#4674) 2024-12-12 22:23:00 +00:00
David Blaikie a2c939a2a2 Add an instruction for vptr initialization (#4633)
This fixes a crash in lowering, at least (though only initializes the
vptr to
null for now) - certainly open to naming feedback on the instruction, or
the
exact semantics (we could have a global vptr instruction that's
referenced from
the existing instructions for reading globals, for instance).

I guess we'll want one type parameter for the vptr_init instruction,
which is
the type that this is a vptr for? (can do that here or in a follow-on
patch)
2024-12-06 18:51:36 +00:00
David Blaikie 5719687438 Fix crash in lowering use of a global variable (#4631)
Actually presenting two options in this one review - if you look at the
specific
commits in this PR, the first commit represents my first attempt - and
if you
look at the overall PR change for the second attempt.

But I'm totally open to completely different approaches/ideas - these
were just
my rough guesses.
2024-12-06 17:34:29 +00:00
Richard Smith 1b13125d19 Avoid relying on an implicit conversion in builtin lowering test. (#4630)
This test is trying to explicitly test builtin functions, so use an
explicit call to a builtin function for the conversion too.
2024-12-05 01:33:42 +00:00
josh11bandJosh L 5d1b39e1f2 More instructions get named (#4615)
Goal is to reduce churn in names in test updates (by churning a lot of
them in this PR).

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-12-03 20:47:53 +00:00
Richard SmithandJon Ross-Perkins e4412a95dd Factor out machinery for forming int type literals. (#4616)
Use it in the remaining few places where we currently hardcode `i32`: as
the index type in array indexing, as the type for literals in `if`
expressions, and as a valid return type for `Run`.

In preparation for changing `Core.Int` to be a class.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-12-03 18:46:27 +00:00
Richard Smith 63ff0cca1a Include the call arguments in the location of a call. (#4602)
Underline the entire call in diagnostics, not only the portion up to the
`(`.
2024-12-02 18:51:44 +00:00
Richard Smith 831dd2c929 Fix importing of the complete_type_witness for a generic class. (#4600)
We need to create an instruction on import to attach the generic
constant value to.
2024-11-28 00:13:21 +00:00
David BlaikieandRichard Smith f921923b4b lazy field index (#4514)
We considered a couple of other options for this:
* https://github.com/carbon-language/carbon-lang/pull/4515 Keep the
`ElementIndex` numbering vptr-ignorant, and do +1 offsets as needed -
seems subtle/easy to miss
* https://github.com/carbon-language/carbon-lang/pull/4517 Always have a
zeroth element in the object representation, make it zero-size in the
case of no-vptr - @zygoloid was concerned this would add overhead
especially to stateless objects used in type-trait-like things.

But currently moving forward with this direction - of initializing field
indexes with an invalid value until the end of the class definition,
then assigning field indexes during construction of the class's object
representation struct type. This direction might reinforce/help avoid
premature access to the object representation before the class is
complete, and give a single place where class layout is done (at class
completion) if we want to add more options there, such as class layout
optimizations, etc.

This patch still has problems with object initialization (that #4515
does not have/does address) but does address normal `obj.member` access
correctly.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-11-26 18:16:25 +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 bc395eb889 Represent integer literals as IntLiteral not as i32. (#4532)
When an `IntLiteral` appears as an operand of an `if` expression,
convert it to `i32` for now, so that we don't reject things like `if
cond then 1 else 2` due to having a non-constant value of type
`IntLiteral`.

For tuple indexing expressions such as `(a, b).0`, convert the index to
type `IntLiteral`, not to type `i32`. This isn't strictly necessary to
do in this PR, but avoids the need to provide an `IntLiteral` -> `i32`
implicit conversion for `no_prelude` tests using this syntax.
2024-11-15 23:24:15 +00:00
Jon Ross-Perkins b2ea19f269 Add a small lowering test with an imported argument. (#4529)
We don't have much import coverage at present, but this seems worth a
tiny bit of validation. I believe the LLVM IR is currently correct.
2024-11-14 21:16:46 +00:00
Richard Smith 2c1d02d991 Don't eagerly materialize an initializing expression used as the object in a compound member access. (#4496)
Instead, wait until we know whether it is used as a value or reference
expression. This allows us to avoid materializing a temporary if it is
used as a value and the initializing representation holds a copy of a
value representation.
2024-11-11 21:32:33 +00:00
Jon Ross-Perkins 10e256a241 Name empty tuples distinctly in SemIR. (#4503)
Building on #4502, give empty tuple values a distinct name, and also
explicitly name tuple types (previously values but not types were
named).
2024-11-08 17:14:52 +00:00
Richard Smith a68acb1975 Fix crash lowering an imported impl method. (#4489)
While we don't need a lookup table for an imported impl from a different
library, we do still need to import the name scope so we can compute the
parent scope for mangling purposes.
2024-11-05 20:38:26 +00:00
Richard Smith 26d7717d60 Insert a value_of_initializer after a call to ImplicitAs where possible. (#4473)
This avoids going through memory when performing an implicit conversion
to a type with a by-copy value representation, such as i32.
2024-11-04 16:06:19 +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 32e5212daa Fix lowering of a conversion from a type with a pointer value representation to a type with a copy value representation. (#4467)
We previously generated a `value_bind` instruction of the wrong type,
resulting in lowering building bad LLVM IR.

Also fix another issue exposed by this change, where we would import
constants without marking their types as complete, and then crash in
lowering while trying to lower them. This happens in particular for the
`FunctionType`s of functions in `ImplDecl`s. Address this by skipping
lowering for constants with incomplete types.
2024-11-01 14:52:57 +00:00
Richard Smith e2ab97672d Fix lowering of specific_functions referring to methods. (#4464)
In this case, the callee may be non-constant because it includes a
reference to `self`, so we need to be able to lower a non-constant
`specific_function`.
2024-10-31 20:07:30 +00:00
Richard Smith 2e63da1a40 Move diagnostic kind name to the end of the diagnostic. (#4437)
Also surround it in square brackets rather than parentheses. This
matches the format used by Clang and GCC, and means diagnostics will
still match the `file:line:col: error: ` pattern used by some IDE tools.

Before:
```console
fail_builtins.carbon:11:11: error(AliasRequiresNameRef): alias initializer must be a name reference
```

After:
```console
fail_builtins.carbon:11:11: error: alias initializer must be a name reference [AliasRequiresNameRef]
```

Also tighten up test regex to only match on `STDERR` lines that list a
file name.
2024-10-23 16:56:23 +00:00
Jon Ross-Perkins 62c36eceda Support printing the diagnostic kind for verification. (#4425)
This is to help identify which diagnostics we're actually using.

Note that driver/testdata still has tests which don't pass this flag,
and so continue to test the kind-less (default) behavior.
2024-10-18 22:33:56 +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
David BlaikieandRichard Smith dfed743de2 Add vtable pointers to class layout (#4407)
A small step to virtual functions - adding vtable pointers to the
layout, but not initializing or otherwise using them at this stage.

A few open design questions I'd love feedback on:

* Is this the right/good enough SemIR representation for now? This patch
adds a `is_dynamic` attribute to `SemIR::Class` and populates/flags it
based on the flag of the base class, or if any virtual function is
declared in the class (or, at least that's my intent). Some other
options include:
* Each `Class` could store a `ClassId` (or `TypeId`?) of the (possibly
indirect, possibly self) base class that is the first one that is
dynamic/has a vtable pointer
* Could make the property narrower, like `has vtable pointer` and have
it `true` only on the type that introduces the vtable - then derived
classes would have to walk their base classes to check if they're the
one that needs to define the vtable pointer or not
* Should the vtable be the first element in the type? If there's a
non-dynamic base type, we could have a layout that's `{<non-dynamic base
type>, vtable ptr, <derived members>}`? Derived types would still be
able to uniquely identify where their vtable pointer is just fine... -
and the vtable pointer is, in a sense, a member of that intermediate
type, so it does seem a bit strange to force it to the front - but I
guess it's probably more efficient in some ways?

Open to any other suggestions/advice/thoughts on the direction, etc.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-10-16 21:26:17 +00:00
Geoff RomerandJon Ross-Perkins 9d942f4633 Generate parameter pattern-match IR from pattern IR (#4388)
Also propagate the pattern IR along with the pattern-match IR, and use
it where appropriate.

Strictly speaking, some parts of the pattern-match IR are allocated
eagerly, while traversing the pattern's parse tree, but they still
aren't actually emitted until we traverse the associated pattern insts.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-16 19:15:29 +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
Jon Ross-PerkinsandRichard Smith e7aebbe581 Update basic diagnostic capitalization/punctuation (#4328)
This is a primarily automated change:

- Search & replace for capitalization
-
`(CARBON_DIAGNOSTIC\((?:\n\s+)?\w+,(?:\n\s+)?\s\w+,(?:\n\s+)?\s")([A-Z])`
    - `$1\L$2`
- Search & replace for period
-
`(CARBON_DIAGNOSTIC\((?:\n\s+)?\w+,(?:\n\s+)?\s\w+,(?:\n\s+)?\s"(?:[^)]|\n)+)\.("[,)])`
    - `$1$2`
- Limited search & replace for `ERROR: ` -> `error: ` in streamed things
- Leaving a TODO for command_line because there's more cleanup that can
be done there
- Modify diagnostic_consumer.cpp
    - ERROR -> error
    - WARNING -> warning

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-09-19 21:32:53 +00:00
David BlaikieandJon Ross-Perkins 4631767943 Stop name mangling at an imported package name (#4294)
To ensure the outer package name is not mangled into imported names.

With this change I can successfully link/run a two-file example:
```
package Mod;
fn HelloWorld() {
  Core.Print(42);
}
```
```
import Mod;
fn Run() -> i32 {
  Mod.HelloWorld();
  return 0;
}
```
```
$ carbon compile mod.carbon main.carbon
$ carbon link mod.o main.o --output=a.out
$ ./a.out
42
```
\o/

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-18 22:01:08 +00:00
Brymer Meneses 7f930d0f58 Use TupleAccess instead of TupleIndex (#4318)
This change removes the `TupleIndex` instruction, and instead
consolidate it with the `TupleAccess` instruction, per this
[discussion](https://discord.com/channels/655572317891461132/655578254970716160/1271195835975204946).
This change, in turn removes `AnyAggregateIndex`.
2024-09-17 20:26:48 +00:00
Jon Ross-Perkins d4c7743d18 Update tests to use [[@TEST_NAME]] (#4293)
Applies #4278 TEST_NAME substitution to tests. Note I've tried to
structure commits as:

1. Do all the replacements.
2. autoupdate (nothing else) -- this shows incorrect updates.
3. Fix up manually, including autoupdates to get back to original
output.
2024-09-10 22:52:23 +00:00
a548eff0bb Rudimentary name mangling support (#4267)
This seems to be enough to avoid naming collisions for functions in any
of the current test cases (verified by asserting that the name of the
`llvm::Function` matches the name passed to create it - not triggering
LLVM's numbering that happens when names collide)

It currently implements mangling for namespace scopes, class scopes, and
impls.
Nothing generic is mangled yet - haven't looked at how that works,
though evidently it's not covered by existing testing, I guess.

Follow-up change will document the current mangling algorithm in
`toolchain/docs/lower.md`

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2024-09-06 23:10:21 +00:00
Jon Ross-PerkinsandDavid Blaikie 1412ecd3f4 Handle unknown lines in DebugInfo (#4252)
Mainly, changes the default from -1 to 0 in DiagnosticLoc, still trying
to keep reusing that. Nothing except for the lowered output is affected,
so I think this is fine.

Also, have lowering consistently call GetDiagnosticLoc.

Pulls in one of the CHECKs suggested from #4251 

Co-authored-by: David Blaikie <dblaikie@gmail.com>
2024-09-04 21:25:02 +00:00
Richard Smith 16fd645663 Add source locations to interface_witness and interface_witness_access instructions. (#4265) 2024-08-28 23:30:00 +00:00
David Blaikie 67b287a2f2 DebugInfo: Add the name as-written, separate from the mangled name (#4253)
There's not much mangling happening yet - but Run -> main (and some
overloading numbering happening, maybe LLVM is doing that 'helpfully'
under the hood?) is enough to demonstrate this improvement/fix.

Ah, here it is:
```
#0  llvm::ValueSymbolTable::makeUniqueName (this=0x50287fe5b6c0, V=0x50287fe827e8, UniqueName="F") at external/_main~llvm_project~llvm-project/llvm/lib/IR/ValueSymbolTable.cpp:45
#1  0x000055555c40f964 in llvm::ValueSymbolTable::reinsertValue (this=0x50287fe5b6c0, V=0x50287fe827e8) at external/_main~llvm_project~llvm-project/llvm/lib/IR/ValueSymbolTable.cpp:100
#2  0x000055555c2a91df in llvm::SymbolTableListTraits<llvm::Function>::addNodeToList (this=0x50287fd16f18, V=0x50287fe827e8) at external/_main~llvm_project~llvm-project/llvm/lib/IR/SymbolTableListTraitsImpl.h:75
#3  0x000055555c2a90e5 in llvm::iplist_impl<llvm::simple_ilist<llvm::Function>, llvm::SymbolTableListTraits<llvm::Function> >::insert (this=0x50287fd16f18, where=..., New=0x50287fe827e8)
    at external/_main~llvm_project~llvm-project/llvm/include/llvm/ADT/ilist.h:166
#4  0x000055555c27fef2 in llvm::iplist_impl<llvm::simple_ilist<llvm::Function>, llvm::SymbolTableListTraits<llvm::Function> >::push_back (this=0x50287fd16f18, val=0x50287fe827e8) at external/_main~llvm_project~llvm-project/llvm/include/llvm/ADT/ilist.h:250
#5  0x000055555c27faeb in llvm::Function::Function (this=0x50287fe827e8, Ty=0x50287fd43058, Linkage=llvm::GlobalValue::ExternalLinkage, AddrSpace=0, name="F", ParentModule=0x50287fd16f00) at external/_main~llvm_project~llvm-project/llvm/lib/IR/Function.cpp:521
#6  0x0000555559441f95 in llvm::Function::Create (Ty=0x50287fd43058, Linkage=llvm::GlobalValue::ExternalLinkage, AddrSpace=0, N="F", M=0x50287fd16f00) at external/_main~llvm_project~llvm-project/llvm/include/llvm/IR/Function.h:175
#7  0x000055555c27ebac in llvm::Function::Create (Ty=0x50287fd43058, Linkage=llvm::GlobalValue::ExternalLinkage, N="F", M=...) at external/_main~llvm_project~llvm-project/llvm/lib/IR/Function.cpp:398
#8  0x0000555558ce7bb5 in Carbon::Lower::FileContext::BuildFunctionDecl (this=0x7fffffffc438, function_id=...) at toolchain/lower/file_context.cpp:257
```

That's where LLVM decides to make a new name (name.number) when asked to
create a new global with the same name as an existing global.

It's not a valid mangling scheme - since the name won't be stable
between different compilations, but it is enough to make
single-compilation code build/run for now.
2024-08-28 19:18:54 +00:00
David Blaikie 2a7c2c5df2 Add test coverage for lowering raw identifiers in function names (#4257) 2024-08-27 19:49:18 +00:00
David Blaikie 5177ebbe2a Fix crash when disabling debug info (#4249)
The source line debug info generation assumed that the function would
have debug info. Check for a non-null di_subprogram_ to ensure we are
emitting debug info for the function.

Rather than checking the di_builder_ - this way if we implement
`nodebug` function attributes, it'll fall out naturally (by creating a
null di_subprogram_) rather than having to come back and change this
from "is debug info enabled" to "is debug info enabled for this
function" later on.
2024-08-26 21:13:39 +00:00