| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
| |
There's plenty of code duplication like this around I'm looking to
reduce.
|
| | |
|
| |
|
|
|
|
|
| |
Was used for situation where we needed to spill more than 1 temporary
and have to use a register that is already used. Instead of push/pop, we
can just allocate and set aside specific stack slots for this purpose.
Also, reworked linearscan() interval sets to separate FPR/GPR intervals.
|
| | |
|
| |
|
|
| |
Also, in regalloc ensure fixed intervals are sorted
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
Also changed the type to size_t for portability
|
| |
|
|
|
|
|
| |
deltrivialphis() was iterating over every variably instead of just
looking at the variable being examined. And I'd been wondering why
mem2reg was such a bottleneck for a testcase like sqlite3 amalgamation..
it's easy to miss the forest for the trees.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Interned strings are used pervasively, so it's a good idea to add a
layer of type safety to differentiate them from general cstrs and avoid
potential bugs from comparing non-interned and interned strings. Not
that that's happened so far that I can remember, but it could.
I'm 90% sure it's legal to alias `struct {char c;}` pointers with `char`
pointers. This specific typedef gives type safety but with a simple
one-way `internstr -> const char *` typecast (with `&istr->c`).
Converting the other way around is more intentional: a straight up cast
`(internstr)cstr` which sticks out as unchecked and probably wrong, or
calling the intern(cstr) function, which is the right way.
|
| |
|
|
|
| |
Being in lex.c was vestigial, since it was being used all over the
frontend and backend.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously, given something like
```
1 a = ...
2 loop { // outer
3 b = do something with a
4 loop { // inner
5 ...
6 if (b < 0)
7 break 'inner;
8 if (b == 0)
9 return;
10 ...
11 }
12 }
```
Regalloc thought outer goes from 2..6, because 6 is the last place where
flow jumps directly back to 2. So `a` would have the lifetime [1,7).
However if neither the break nor return are taken, the inner loop
repeats and then control could flow back to 7 -> 3. But now the physical
location for `a` might have been clobbered between 8..10, which is
wrong. This fixes that by making sure the outer loop is considered to
span 2..10.
The way I went about it might not be the best way of doing it. I'm not
100% certain that it's fully correct and will always find the correct
loopend, either. It's surprising it took this long to hit this edge
case.
|
| |
|
|
|
| |
This uncovered a edgecase with loops and lifetime construction in
regalloc!
|
| | |
|
| | |
|
| |
|
|
| |
This is a common non-standard GNU extension.
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
| |
Treated as unsized array T[]. This shows up in some linux headers
as a non-standard way to have flexible array members.
|
| | |
|
| |
|
|
| |
Isel had this forever, but the matching code for it in emit wasn't there
|
| |
|
|
| |
signed/unsigned char pointer
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
With 59ca5a8db, querying if a symbol is defined is cheap. If we're
compiling code that calls foo() and we defined foo() in this compilation
unit, we already know its offset within the .text section, so use it
instead of emitting a relocation for the linker to handle. Also, put
small literal data in the .text section instead of .rodata. This seems
to improve performance (cache locality?), and as a bonus, it will be
good for aarch64's instr encoding with smallish PC-relative offsets.
|
| |
|
|
|
| |
Gets rid of linear-time findsym(), though needs some extra indirection
to emit sorted symbols.
|
| | |
|
| | |
|
| |
|
|
|
| |
sqlite3 was falling back to `((void*)&((char*)0)[X])` for INT_TO_PTR,
which this handles now.
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
| |
For `extern int x[1];`, can use PCREL32 for &x. But for `extern int
x(int)`, must use GOTREL, when not being called directly (that's PLT).
Therefore the type of an external symbol (actually just whether it
denotes a function) matters when deciding what kind of relocation to
emit, so keep that information.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
For duplicate cases, case value overflow
|
| | |
|
| |
|
|
| |
To reduce hashmap code repetition. Also add pmap_del for this purpose
|