Age | Commit message (Collapse) | Author |
|
This commit adds missing quotation marks around the argument to the
function, and changes the value of `-x' option to `c` (lowercase) as per
GCC manual [1].
[1]: https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Overall-Options.html
|
|
|
|
|
|
In presence of jump loops, the algorithm would
create cycles in the disjoint-set data structure.
This caused infinite recursion and stack overflows.
|
|
The arm64 might have the same problem but it
is currently unable to handle them even in
instruction selection.
Thanks to Jean Dao for reporting the bug.
|
|
The stashing of constants in gas.c was also
changed to support 16-bytes constants.
|
|
|
|
It never worked until today.
|
|
|
|
Symbols in the source file are still limited in
length because the rest of the code assumes that
strings always fit in NString bytes.
Regardless, there is already a benefit because
comparing/copying symbol names does not require
using strcmp()/strcpy() anymore.
|
|
The previous heuristics were ad hoc and it was
hard to understand why they worked at all.
This patch can be summarized in three points:
1. When a register is freed (an instruction
assigns it), we try to find if a temporary
would like to be in it, and if we find one,
we move it in the newly freed register.
I call this an "eager move".
2. Temporaries now remember in what register
they were last allocated; this information
is stored in the field Tmp.visit, and
prevails on the field Tmp.hint when it is
set. (This makes having the same hint for
interfering temporaries not so disastrous.)
3. Blocks are now allocated in "onion" order,
from the innermost loop to the outermost.
This is the change I am the least sure
about; it should be evaluated thorougly.
|
|
I now take the view that a phi is "used" at the
end of all the predecessors. (Think that copies
are made to phis at the end of all predecessors.)
|
|
Before this commit, I tried to make sure that
two interfering temporaries never ended up in
the same phi class.
This was to make sure that their register hints
were not counterproductively stepping on each
other's toes. The idea is fine, but:
* the implementation is clumsy because it
mixes the orthogonal concepts of
(i) interference and (ii) phi classes;
* the hinting process in the register
allocator is hard to understand because
the disjoint-set data structure used for
phi classes is cut in arbitrary places.
After this commit, the phi classes *really* are
phi classes represented with a proper disjoint-set
data structure.
|
|
|
|
|
|
Since the environment can only be of type `l`, do
not require to write it down.
I also tightened the type information of the `pare`
and `arge` instructions.
|
|
|
|
|
|
|
|
Ori needs this. It should not cost much more memory at runtime,
only a minimal amount of address space.
|
|
The previous code was buggy. It would put a stack
pointer on the heap when handling "add $foo, 42".
The new code is more straightforward and hopefully
more correct. Only temporaries with a "stack"
alias class will have a slot pointer.
|
|
|
|
With the default toolchain, it looks like we have to
make sure all symbols are loaded using rip-relative
addressing.
|
|
Intended usage: c_count `make src` (or similar).
|
|
|
|
|
|
|
|
|
|
The vararg tests had to be changed because
va_list is 32-bit wide on arm. The astute
reader will notice that the way we pass
va_list values is wrong, we should be using
the ':valist' type as defined below instead
of 'l'. But eh, that works for now, because
of the ABI.
type :valist = align 8 { 32 }
|
|
|
|
|
|
The arm64 ABI needs to know precisely what
floating point types are being used, so we
need to store that information.
I also made typ[] a dynamic array.
|
|
This big diff does multiple changes to allow
the addition of new targets to qbe. The
changes are listed below in decreasing order
of impact.
1. Add a new Target structure.
To add support for a given target, one has to
implement all the members of the Target
structure. All the source files where changed
to use this interface where needed.
2. Single out amd64-specific code.
In this commit, the amd64 target T_amd64_sysv
is the only target available, it is implemented
in the amd64/ directory. All the non-static
items in this directory are prefixed with either
amd64_ or amd64_sysv (for items that are
specific to the System V ABI).
3. Centralize Ops information.
There is now a file 'ops.h' that must be used to
store all the available operations together with
their metadata. The various targets will only
select what they need; but it is beneficial that
there is only *one* place to change to add a new
instruction.
One good side effect of this change is that any
operation 'xyz' in the IL now as a corresponding
'Oxyz' in the code.
4. Misc fixes.
One notable change is that instruction selection
now generates generic comparison operations and
the lowering to the target's comparisons is done
in the emitter.
GAS directives for data are the same for many
targets, so data emission was extracted in a
file 'gas.c'.
5. Modularize the Makefile.
The Makefile now has a list of C files that
are target-independent (SRC), and one list
of C files per target. Each target can also
use its own 'all.h' header (for example to
define registers).
|
|
The size of a union is the size of the largest
element aligned with the largest alignment.
For example, the size of the following union is
16, not 13 (as returned before this patch).
union {
char c[13];
int i;
};
|
|
The register allocation now has stricter assertions
about global registers. The stricter assertions
required changes in the spiller: We now correctly
indicate to the register allocator what registers
are used by "ret" instructions.
|
|
|
|
|
|
|
|
|
|
|
|
The spec says that numbers can be arbitrarily
big, and only the last 64 bits will be taken
into consideration. Calling sscanf does not
implement this, so I wrote an ad-hoc function.
|
|
Notably, this adds a new pass to get rid of
jumps on jumps.
|
|
|
|
|
|
|
|
|
|
|
|
When a temporary marked local is escaping,
the whole slot must be marked as such. To
solve this, Alias now holds a pointer to
the alias information of the slot. For
simplicity of the code, this pointer is
always valid and fetching ->type out of it
is meaningful.
|
|
|
|
When eliminating `load %foo`, don't limit the
search to the live range of %foo, but to the
live range of its aliasing information.
For example, if %foo is a constant offset into
a stack-allocated slot,
%foo =l add %slot, 42
the search will proceed on all the code in
which %slot is live, not only below the
definition of %foo, like before.
|