-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test cases for not coalescing pseudoreg/hardreg pairs that fail georg…
…e test
- Loading branch information
Showing
5 changed files
with
112 additions
and
1 deletion.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
tests/chapter_20/int_only/with_coalescing/george_dont_coalesce.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
57
tests/chapter_20/int_only/with_coalescing/george_dont_coalesce_2.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |