From b94fe89c9ddfcb85dcddebfd218fa7f00b8e6608 Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 26 Jun 2023 00:29:07 +0200 Subject: backend: fix mem2reg & regalloc they were broken, especially for unstructured control flow. most significant fix is to register allocator for temporaries that are used before the first definition in the source order, e.g.: @1: %x = add %y, 1 b @3 @2 %y = ... b @1 it's legal for %x to use %y there (assuming @2 dominates @1) but from the point of view of the register allocator %y is defined and freed and then used again, which broke things. the fix is to introduce phis for this situation: @1: %y.1 = phi @2 %y %x = add %y.1, 1 b @3 @2 %y = ... b @1 then regalloc phi handling code makes it work --- ir.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ir.h') diff --git a/ir.h b/ir.h index 85500d1..6507fe0 100644 --- a/ir.h +++ b/ir.h @@ -121,6 +121,7 @@ enum jumpkind { JXXX, Jb, Jret, }; struct block { int id; int npred; + int visit; union { struct block *_pred0; struct block **_pred; @@ -206,6 +207,7 @@ extern struct calltab {vec_of(struct call);} calltab; extern struct phitab {vec_of(union ref *);} phitab; extern struct dattab {vec_of(struct irdat);} dattab; extern struct addr addrht[]; +extern int visitmark; #define mkinstr(O, C, ...) ((struct instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ }) #define mkarginstr(ty, x) mkinstr(Oarg, 0, mktyperef(ty), (x)) void irinit(struct function *); @@ -240,6 +242,9 @@ void deluses(int ins); void delinstr(struct block *, int idx); void delphi(struct block *, int idx); void fillblkids(struct function *); +#define startbbvisit() (void)(++visitmark) +#define wasvisited(blk) ((blk)->visit == visitmark) +#define markvisited(blk) ((blk)->visit = visitmark) /* IR builder functions */ union ref addinstr(struct function *, struct instr); -- cgit v1.2.3