Skip to content

Commit

Permalink
test cases for not coalescing pseudoreg/hardreg pairs that fail georg…
Browse files Browse the repository at this point in the history
…e test
  • Loading branch information
nlsandler committed Apr 9, 2024
1 parent 1ea3a8d commit 4990ade
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 1 deletion.
2 changes: 1 addition & 1 deletion expected_results.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions test_framework/regalloc.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ class CoalesceTest(NamedTuple):
"coalesce_prevents_spill.c": CoalesceTest(max_moves=18),
"briggs_coalesce_hardreg.c": CoalesceTest(),
"briggs_dont_coalesce.c": CoalesceTest(max_moves=7),
"george_dont_coalesce.c": CoalesceTest(max_moves=31),
"george_dont_coalesce_2.c": CoalesceTest(max_moves=21),
}


Expand Down
6 changes: 6 additions & 0 deletions test_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,12 @@
],
"chapter_20/int_only/with_coalescing/briggs_dont_coalesce.c": [
"chapter_20/libraries/util.c"
],
"chapter_20/int_only/with_coalescing/george_dont_coalesce.c": [
"chapter_20/libraries/util.c"
],
"chapter_20/int_only/with_coalescing/george_dont_coalesce_2.c": [
"chapter_20/libraries/util.c"
]
},
"assembly_libs": {
Expand Down
46 changes: 46 additions & 0 deletions tests/chapter_20/int_only/with_coalescing/george_dont_coalesce.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* Test that we don't coalesce a pseudo into a hardreg if they fail the George
* and Briggs tests - specifically when they're connected by a mov of the form
* movl %hardreg, %pseudo. (For the equivalent test with movl %pseudo, %hardreg,
* see george_dont_coalesce_2.c) Coalescing registers that fail the George test
* here would force us to spill; we inspect the assembly for target to make
* sure there are no spills.
* */

#include "../../libraries/util.h"

int glob = 1;

// a-f have values 1-6
int target(int a, int b, int c, int d, int e, int f) {
// a-f interfere with g-l, g-l interfere wih m-q, and m-q interfere with
// all the param-passing registers. The only way to avoid spills is to put
// at least five of a-f in non-param-passing registers, so we can put at
// least five of pseudos g-l in param-passing registers, leaving five
// non-param-passing registers available for m-q. This means we can't
// coalesce all of a-f into parameter-passing registers.

// define g-l (values 7-12)
int g = a + f; // 7
int h = b * d; // 8
int i = c * c; // 9
int j = d + f; // 10
int k = e + f; // 11
int l = f * b; // 12

// define m-q; use a-f in initializer for m to make them interfere with g-l
int m = (a + b + c + d + e + f) - 7; // 14
int n = g + h; // 15
int o = i + 7; // 16
int p = j * 2 - 3; // 17
int q = k + g; // 18
// this makes m-q conflict w/ all param-passing registers
check_12_ints(g, h, i, j, k, l, 13, m, n, o, p, q, 7);
return 0;
}

int target2(void) {
// a-e are callee-saved
// they interfere with f-k, which must therefore be caller-saved
// which interfere with l-p, which must be callee-save
// but we pass l-p as arugments
}
57 changes: 57 additions & 0 deletions tests/chapter_20/int_only/with_coalescing/george_dont_coalesce_2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Test that we don't coalesce a pseudo into a hardreg if they fail the George
* and Briggs tests - specifically, when they're connected by a mov of the form
* movl %pseudoreg, %hardreg. (See george_dont_coalesce.c for an equivalent
* test where the hardreg is the first instruction.) Coalescing registers
* that fail the George test here wOuld force us to spill, so we inspect the
* assembly for target to make sure there are no spills.
* */

#include "../../libraries/util.h"

int glob = 1;

int update_glob(void) {
glob = 0;
return 0;
}

int target(void) {
// a-e interfere with f-k, and f-k interfere with l-p. a-e must be
// callee-saved, so to avoid spills, f-k must be caller-saved, so
// at least four of l-p must be callee-saved. We pass l-p as arguments in
// parameter-passing registers, but coalescing them into those registers
// will cause a spill.

// define a-e (values 2-6)
int a = glob * 2; // 2
int b = glob * 3; // 3
int c = glob * 4; // 4
int d = glob * 5; // 5
int e = glob * 6; // 6
// force a-e to be callee-saved
update_glob();
// define f-k (values 7-12)
int f = a + d; // 7
int g = b * 3 - 1; // 8
int h = c + d; // 9;
int i = c + e; // 10
int j = d * 2 + 1; // 11
int k = e * 2; // 12
// define l using a-e, to make sure they all conflict with f-k
int l = a + b + c + d + e; // 20
int m = 3 * f; // 21
int n = g * 3 - 2; // 22
int o = h * 2 + 5; // 23
int p = i * 2 + 4; // 24

// use all of f-k here, to make them conflict with l-p
glob = glob + f + g + h + i + j + k; // 57

// now pass l-p as arguments; George test should prevent us from coalescing
// them into param-passing registers
check_5_ints(l, m, n, o, p, 20);

// and validate glob too
check_one_int(glob, 57);
return 0;
}

0 comments on commit 4990ade

Please sign in to comment.