mirror of
git://c9x.me/qbe.git
synced 2026-04-05 09:59:47 +00:00
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()
98 lines
2.5 KiB
Makefile
98 lines
2.5 KiB
Makefile
.POSIX:
|
|
.SUFFIXES: .o .c
|
|
|
|
PREFIX = /usr/local
|
|
BINDIR = $(PREFIX)/bin
|
|
|
|
COMMOBJ = main.o util.o parse.o abi.o cfg.o mem.o ssa.o alias.o load.o \
|
|
copy.o fold.o gvn.o gcm.o ins.o simpl.o live.o \
|
|
spill.o rega.o emit.o
|
|
AMD64OBJ = amd64/targ.o amd64/sysv.o amd64/isel.o amd64/emit.o
|
|
ARM64OBJ = arm64/targ.o arm64/abi.o arm64/isel.o arm64/emit.o
|
|
RV64OBJ = rv64/targ.o rv64/abi.o rv64/isel.o rv64/emit.o
|
|
OBJ = $(COMMOBJ) $(AMD64OBJ) $(ARM64OBJ) $(RV64OBJ)
|
|
|
|
SRCALL = $(OBJ:.o=.c)
|
|
|
|
CC = cc
|
|
CFLAGS = -std=c99 -g -Wall -Wextra -Wpedantic
|
|
|
|
qbe: $(OBJ)
|
|
$(CC) $(LDFLAGS) $(OBJ) -o $@
|
|
|
|
.c.o:
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
$(OBJ): all.h ops.h
|
|
$(AMD64OBJ): amd64/all.h
|
|
$(ARM64OBJ): arm64/all.h
|
|
$(RV64OBJ): rv64/all.h
|
|
main.o: config.h
|
|
|
|
config.h:
|
|
@case `uname` in \
|
|
*Darwin*) \
|
|
case `uname -m` in \
|
|
*arm64*) \
|
|
echo "#define Deftgt T_arm64_apple";\
|
|
;; \
|
|
*) \
|
|
echo "#define Deftgt T_amd64_apple";\
|
|
;; \
|
|
esac \
|
|
;; \
|
|
*) \
|
|
case `uname -m` in \
|
|
*aarch64*|*arm64*) \
|
|
echo "#define Deftgt T_arm64"; \
|
|
;; \
|
|
*riscv64*) \
|
|
echo "#define Deftgt T_rv64"; \
|
|
;; \
|
|
*) \
|
|
echo "#define Deftgt T_amd64_sysv";\
|
|
;; \
|
|
esac \
|
|
;; \
|
|
esac > $@
|
|
|
|
install: qbe
|
|
mkdir -p "$(DESTDIR)$(BINDIR)"
|
|
install -m755 qbe "$(DESTDIR)$(BINDIR)/qbe"
|
|
|
|
uninstall:
|
|
rm -f "$(DESTDIR)$(BINDIR)/qbe"
|
|
|
|
clean:
|
|
rm -f *.o */*.o qbe
|
|
|
|
clean-gen: clean
|
|
rm -f config.h
|
|
|
|
check: qbe
|
|
tools/test.sh all
|
|
|
|
check-arm64: qbe
|
|
TARGET=arm64 tools/test.sh all
|
|
|
|
check-rv64: qbe
|
|
TARGET=rv64 tools/test.sh all
|
|
|
|
src:
|
|
@echo $(SRCALL)
|
|
|
|
80:
|
|
@for F in $(SRCALL); \
|
|
do \
|
|
awk "{ \
|
|
gsub(/\\t/, \" \"); \
|
|
if (length(\$$0) > $@) \
|
|
printf(\"$$F:%d: %s\\n\", NR, \$$0); \
|
|
}" < $$F; \
|
|
done
|
|
|
|
wc:
|
|
@wc -l $(SRCALL)
|
|
|
|
.PHONY: clean clean-gen check check-arm64 check-rv64 src 80 wc install uninstall
|