Commit Graph

1443 Commits

Author SHA1 Message Date
Quentin Carbonneaux
ac79f8fd02 mcf comments 2026-05-01 19:44:44 +02:00
Quentin Carbonneaux
84516c7484 relax assert in emitcon 2026-05-01 19:40:10 +02:00
Quentin Carbonneaux
f36c06c3ee rework docs 2026-04-29 11:22:19 +02:00
Quentin Carbonneaux
8c16de02ed rv64: got-free addresses for SGlo 2026-04-29 10:54:26 +02:00
Quentin Carbonneaux
63bb04f759 more fixes 2026-04-29 10:15:11 +02:00
Quentin Carbonneaux
6abea36b9b nits 2026-04-28 16:48:43 +02:00
Quentin Carbonneaux
b8b95a99df asserts in emitcon() 2026-04-28 16:23:47 +02:00
Quentin Carbonneaux
a9796317aa apple tls is global 2026-04-28 16:11:47 +02:00
Quentin Carbonneaux
5ac78c67c9 nits 2026-04-28 16:01:48 +02:00
Quentin Carbonneaux
fee64f4341 mcf review 2026-04-28 14:16:34 +02:00
Quentin Carbonneaux
7ab2fbe07c extern DYNCONST 2026-04-27 18:42:35 +02:00
Michael Forney
dba8d5a4bf update debug flag list for gvn/gcm 2026-04-27 10:08:45 +02:00
Michael Forney
504a2012f4 fix float neg on mach-o
neg for float uses xorp[sd] with a 16-byte memory operand.

This matches what clang emits with --target=x86_64-apple-darwin.
2026-04-25 18:51:46 +02:00
Quentin Carbonneaux
b58e2e695b fix exponential complexity in usewidthle() 2026-04-21 13:25:00 +02:00
willow
8ff0651552 parse: deny non-digit after minus in getint
also: '0' <= c <= '9' -> isdigit(c)
Signed-off-by: willow <im@purring.fyi>
2026-02-28 19:05:57 +01:00
willow
7ac9722ccb remove unused variable
Signed-off-by: willow <im@purring.fyi>
2026-02-28 19:05:15 +01:00
Quentin Carbonneaux
4f9b94a9b3 formatting fixes in tests 2026-02-12 09:23:13 +01:00
Quentin Carbonneaux
5f40188f9e cosmetics in emit.c 2026-02-12 09:21:15 +01:00
Scott Graham
01102ad63b winabi: fix isel of large consts
ABI lowering for winabi was incorrectly using a Kl cls when emitting
Ostorel, which in turn was causing isel to fail to lower large constants
in to temporaries ( https://c9x.me/git/qbe.git/tree/amd64/isel.c#n107 )
when necessary.

(This should be applied on the 'winabi' branch.)
2026-02-12 09:17:17 +01:00
Scott Graham
d5f02dc67c winabi: fix allocation of parameters to regs with hidden arg
In the presence of the hidden arg for return-by-value, the
registers used for natural arguments were incorrect.

(This should be applied on the 'winabi' branch.)
2026-02-12 09:17:17 +01:00
Scott Graham
d166a61141 Implementation of Windows amd64_win target
This is an implementation of the Windows ABI. It supports most features
(struct passing/returning, varargs, env). TLS is not yet supported.

This patch does not actually port QBE to Windows, it only allows QBE to
generate correct asm to target Windows. As a result, testing is
accomplished on a Linux host, by using a cross-compiling toolchain, and
running the resulting binaries by using wine. See:

	TARGET=amd64_win tools/test.sh all

A few cross-platform tests were changed from 'long' to 'long long' in
driver code because long in C does not match the size of a QBE 'l' on
Windows.
2026-02-12 09:17:17 +01:00
Richard McCormack
cf06ce159d Modify amd64 fixarg to fix calling constant addresses
On x86_64, direct calls are always PC-relative. This means that
in order to call an absolute address, the call must be indirect.

To accomplish this, update fixarg to introduce a temporary before
emitting.
2026-01-13 21:24:31 +01:00
Quentin Carbonneaux
640c78d0da fix typo in simplcfg 2026-01-13 20:36:23 +01:00
Quentin Carbonneaux
afd5d2e518 drop dead preds in fixphis
It is possible that GVN removes
some dead blocks, this could lead
to odd - but probably harmless -
phi args appearing in the IL.
This patch cleans things up during
fillcfg().
2026-01-13 18:27:50 +01:00
Quentin Carbonneaux
e8365dd0a2 new simplcfg pass
Useful for ifopt to match more
often. Empty blocks are fused
and conditional jumps on empty
blocks with the same successor
(and no phis in the successor)
are collapsed.
2026-01-13 18:17:35 +01:00
Quentin Carbonneaux
c6336557da ifopt simplifications 2026-01-13 18:11:37 +01:00
Roland Paterson-Jones
5c1eb24e2c If-conversion RFC 4 - x86 only (for now), use cmovXX
Replacement of tiny conditional jump graphlets with
conditional move instructions.

Currently enabled only for x86. Arm64 support using cselXX
will be essentially identical.

Adds (internal) frontend sel0/sel1 ops with flag-specific
backend xselXX following jnz implementation pattern.

Testing: standard QBE, cproc, harec, hare, roland
2026-01-13 18:11:30 +01:00
Quentin Carbonneaux
7201079137 update copyright years 2026-01-13 17:09:41 +01:00
Quentin Carbonneaux
112cc1b824 rv64: handle slots in jnz 2026-01-13 17:09:41 +01:00
Quentin Carbonneaux
6a2dca8b99 fix jmp arg spilling
In case we need to spill to accomodate
for the jump argument, piggyback the
reloads from slots to regalloc so that
they can be correctly inserted on edges.
2026-01-13 17:09:41 +01:00
Quentin Carbonneaux
e0ded59639 please as with truncated constants
Apple's assembler actually hard
crashed on overflows.
2026-01-06 20:43:42 +01:00
Quentin Carbonneaux
0f6bbb1c7c arm64_apple: fix argxbh support 2026-01-06 20:43:42 +01:00
Quentin Carbonneaux
73f0accb45 arm64: prevent bogus IP1 clobbers 2026-01-06 20:43:38 +01:00
Quentin Carbonneaux
03da40271f rv64: fix invalid float immediates
Thanks to Luke Graham for reporting
and fixing this issue.
2026-01-05 22:19:53 +01:00
Quentin Carbonneaux
120f316162 skip deleted phis in use width scan 2025-05-30 17:40:17 +02:00
Quentin Carbonneaux
8d5b86ac4c fix fp constants on big endian hosts 2025-04-16 10:29:00 +02:00
Horst H. von Brand
348f2eac90 minic: C23 doesn't allow bool as identifier
Signed-off-by: Horst H. von Brand <vonbrand@inf.utfsm.cl>
2025-03-16 11:27:49 +01:00
Antonio Terceiro
903610de4f tools/test.sh: test the native architecture without QEMU
While at it, extract most duplicated code across targets into a
function.
2025-03-15 14:43:33 +01:00
Antonio Terceiro
f7ab20680b tools/test.sh: allow running against installed package
If $bin is set in the environment, use it instead of using `qbe` from
the source tree. The same for $binref. This supports the following use
cases:

- I have a qbe package installed, and I want to test my local changes
  with the installed packages as a reference:

  $ binref=/usr/bin/qbe ./tools/test.sh all

- I want to test the installed qbe against new tests that I have
  written, to reproduce a bug:

  $ bin=/usr/bin/qbe ./tools/test.sh test/newtest.ssa

In Debian, we also run tests against the installed package when
dependencies change, etc. We will also run on several architectures
where the necessary cross compilers might not be available. So make
tests that cannot be run because of a missing compiler exit with 77,
signaling to Debian's autopkgtest that the test is skipped.
2025-03-15 14:43:00 +01:00
Antonio Terceiro
789e38fdb2 Makefile: add explicit target to test the x86_64 backend
When developing on an arm64 machine, it's useful to be able to test the
x86_64 target.
2025-03-15 14:40:55 +01:00
Quentin Carbonneaux
86d13b93e8 arm64: use IP1 as scratch register
On Apple platforms x18 is not guaranteed
to be preserved across context switches.
So we now use IP1 as scratch register.

En passant, one dubious use of IP0 in
arm64/emit.c fixarg() was transitioned
to IP1. I believe the previous code could
clobber a user value if IP0 was live.
2025-03-15 14:27:34 +01:00
Quentin Carbonneaux
ec5502645f 10 years of qbe! 2025-03-14 13:09:42 +01:00
Quentin Carbonneaux
f3ca257737 gvn/gcm review
- Many stylistic nits.
- Removed blkmerge().
- Some minor bug fixes.
- GCM reassoc is now "sink"; a pass that
  moves trivial ops in their target block
  with the same goal of reducing register
  pressure, but starting from instructions
  that benefit from having their inputs
  close.
2025-03-14 13:09:21 +01:00
Roland Paterson-Jones
1cb255cb04 Get rid of movins() infra. 2025-03-14 13:07:40 +01:00
Roland Paterson-Jones
c2ff93e75e Global Value Numbering / Global Code Motion
More or less as proposed in its ninth iteration with the
addition of a gcmmove() functionality to restore coherent
local schedules.

Changes since RFC 8:

Features:

 - generalization of phi 1/0 detection
 - collapse linear jmp chains before GVN; simplifies if-graph
     detection used in 0/non-0 value inference and if-elim...
 - infer 0/non-0 values from dominating blk jnz; eliminates
     redundant cmp eq/ne 0 and associated jnz/blocks, for example
     redundant null pointer checks (hare codebase likes this)
 - remove (emergent) empty if-then-else graphlets between GVN and
     GCM; improves GCM instruction placement, particularly cmps.
 - merge %addr =l add %addr1, N sequences - reduces tmp count,
     register pressure.
 - squash consecutive associative ops with constant args, e.g.
     t1 = add t, N ... t2 = add t2, M -> t2 = add t, N+M

Bug Fixes:

 - remove "cmp eq/ne of non-identical RCon's " in copyref().
   RCon's are not guaranteed to be dedup'ed, and symbols can
   alias.

Codebase:

  - moved some stuff into cfg.c including blkmerge()
  - some refactoring in gvn.c
  - simplification of reassoc.c - always reassoc all cmp ops
      and Kl add %t, N. Better on coremark, smaller codebase.
  - minor simplification of movins() - use vins

Testing - standard QBE, cproc, hare, harec, coremark
          [still have Rust build issues with latest roland]

Benchmark
- coremark is ~15%+ faster than master
- hare "HARETEST_INCLUDE='slow' make check" ~8% faster
    (crypto::sha1::sha1_1gb is biggest obvious win - ~25% faster)

Changes since RFC 7:

Bug fixes:

- remove isbad4gcm() in GVN/GCM - it is unsound due to different state
    at GVN vs GCM time; replace with "reassociation" pass after GCM
- fix intra-blk use-before-def after GCM
- prevent GVN from deduping trapping instructions cos GCM will not
    move them
- remove cmp eq/ne identical arg copy detection for floating point, it
    is not valid for NaN
- fix cges/cged flagged as commutative in ops.h instead of cnes/cned
    respectively; just a typo

Minor features:

- copy detection handles cmp le/lt/ge/gt with identical args
- treat (integer) div/rem by non-zero constant as non-trapping
- eliminate add N/sub N pairs in copy detection
- maintain accurate tmp use in GVN; not strictly necessary but enables
    interim global state sanity checking
- "reassociation" of trivial constant offset load/store addresses, and
    cmp ops with point-of-use in pass after GCM
- normalise commutative op arg order - e.g. op con, tmp -> op tmp, con
    to simplify copy detection and GVN instruction dedup

Codebase:

- split out core copy detection and constant folding (back) out into
    copy.c, fold.c respectively; gvn.c was getting monolithic
- generic support for instruction moving in ins.c - used by GCM and
    reassoc
- new reassociation pass in reassoc.c
- other minor clean-up/refactor

Changes since RFC 6:

- More ext elimination in GVN by examination of def and use bit width
- elimination of redundant and mask by bit width examination
- Incorporation of Song's patch

Changes since RFC 5:

- avoidance of "bad" candidates for GVN/GCM - trivial address offset
    calculations, and comparisons
- more copy detection mostly around boolean values
- allow elimination of unused load, alloc, trapping instructions
- detection of trivial boolean v ? 1 : 0 phi patterns
- bug fix for (removal of) "chg" optimisation in ins recreation - it
    was missing removal of unused instructions in some cases

ifelim() between GVN and GCM; deeper nopunused()
2025-03-14 09:58:37 +01:00
Roland Paterson-Jones
9e36cbe4d8 Combine fillrpo() and fillpreds() into fillcfg().
Remove edgedel() calls from fillrpo().

Call new prunephis() from fillpreds().
[Curiously this never seems to do anything even tho edgedel()
is no longer called from fillrpo()]

One remaining fillpreds() call in parse.c typecheck - seems
like it will still work the same.

defensive; fillcfg() combining fillrpo() and fillpreds() - problem after simpljmp() - think it is cos fillrpo() is still doing edgedel() which should now be covered by fillpreds()

comment out edgedel() in fillrpo() - fillcfg() no longer asserts after simpljmp() but seems like prunephis() never triggers???

static fillrpo(); remove edgedel() from fillrpo()

replace fillrpo() and/or fillpreds() with fillcfg()
2025-03-14 09:47:05 +01:00
Roland Paterson-Jones
ecfdac4f00 Simplify fillpreds()
Now that b->pred is a vector we do can remove the counting pass.
2025-03-14 09:47:05 +01:00
Roland Paterson-Jones
1c769584ac Simplify fillrpo()
Essentially use post-order as id, then reverse to rpo.
Avoids needing f->nblk initially; slightly simpler logic.
2025-03-14 09:47:05 +01:00
Roland Paterson-Jones
0ce9966c23 Re-use (vgrow) b->ins vector in backend xxx_abi() fn's.
Removes last re-allocation of b->ins.
2025-03-14 09:47:05 +01:00
Roland Paterson-Jones
434cf5fdc4 idup(Ins **, Ins *, ulong) -> idup(Blk *, Ins *, ulong)
Always used this way and factors setting b->nins.
Makes b->ins vector contract more obvious.
2025-03-14 09:47:05 +01:00