From: David Given Date: Tue, 15 Nov 2016 20:55:10 +0000 (+0100) Subject: Reenable eviction of corrupted registers, which had been broken by a previous X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=581fa4a457639b1941c87c737cfa1ce368b2cd59;p=ack.git Reenable eviction of corrupted registers, which had been broken by a previous change. Change the register move code to get swaps right, or at least righter. --- diff --git a/mach/proto/mcg/pass_registerallocator.c b/mach/proto/mcg/pass_registerallocator.c index a064adb8e..3e0c9b43b 100644 --- a/mach/proto/mcg/pass_registerallocator.c +++ b/mach/proto/mcg/pass_registerallocator.c @@ -347,13 +347,11 @@ static void add_through_register(struct vreg* vreg, struct hreg* hreg) if (hreg) { - bool unusedin = allocatable_stackable_input(hreg, vreg); - bool unusedout = allocatable_stackable_output(hreg, vreg); + bool unused = allocatable_through(hreg, vreg); struct vreg* inuse = pmap_findleft(current_ins, hreg); struct vreg* outuse = pmap_findleft(current_outs, hreg); - if ((unusedin || (inuse == vreg)) && - (unusedout || (outuse == vreg))) + if (unused || ((inuse == vreg) && (outuse == vreg))) { /* Input and output are either free or already assigned to this * vreg. */ @@ -594,15 +592,14 @@ static int insert_moves(struct basicblock* bb, int index, struct hreg* src = pmap_findright(srcregs, vreg); assert(src != NULL); - if (src != dest) - pmap_add(&copies, src, dest); + pmap_add(&copies, src, dest); } while (copies.count > 0) { struct hreg* src; struct hreg* dest; - struct hreg* temp; + struct hreg* other; struct hop* hop; /* Try and find a destination which isn't a source. */ @@ -627,14 +624,38 @@ static int insert_moves(struct basicblock* bb, int index, } else { - /* There's nowhere to copy to --- the copies that are left form a cycle. - * So we need to swap instead. */ + /* Okay, so there's nowhere to free to move src to. This could be + * because it's already in the right place. */ src = copies.item[0].left; dest = pmap_findleft(&copies, src); - hop = platform_swap(bb, src, dest); - pmap_remove(&copies, src, dest); - pmap_remove(&copies, dest, src); + + if (src == dest) + { + /* This register is already in the right place! */ + + pmap_remove(&copies, src, dest); + continue; + } + else + { + /* It's not in the right place. That means we have a cycle, and need to do + * a swap. */ + + /* (src->dest, other->src) */ + hop = platform_swap(bb, src, dest); + pmap_remove(&copies, src, dest); + + /* Now src and dest are swapped. We know that the old src is in the right place + * and now contains dest. Any copies from the old dest (now containing src) must + * be patched to point at the old src. */ + + for (i=0; ihops, hop, index + inserted);