filename | src/xlat/livevar.c |
changeset | 1006:3a169c224c12 |
author | nkeynes |
date | Sun Apr 12 07:24:45 2009 +0000 (15 years ago) |
branch | xlat-refactor |
permissions | -rw-r--r-- |
last change | Restructure operand types - rename to forms to avoid conflict for actual data types temporary operands are now a first class form remove explicit types for immediates - now implied by opcode Initial work on promote-source-reg pass |
view | annotate | diff | log | raw |
1 /**
2 * $Id: livevar.h 931 2008-10-31 02:57:59Z nkeynes $
3 *
4 * Live variable analysis
5 *
6 * Copyright (c) 2009 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include "xlat/xir.h"
20 #include "xlat/xiropt.h"
23 gboolean live_range_calculate( xir_op_t start, xir_op_t end,
24 struct live_range *live_ranges, unsigned int live_ranges_size )
25 {
26 struct live_range *current[MAX_REGISTERS];
27 struct live_range *range_next = live_ranges;
28 struct live_range *range_end = live_ranges + live_ranges_size;
29 xir_offset_t position = 0;
30 xir_offset_t last_exc = 0;
31 xir_op_t it;
33 memset( current, 0, sizeof(current) );
35 while( it != end ) {
36 int reg0 = -1;
37 int reg1 = -1;
39 if( it->exc != NULL ) {
40 // Track when the last possible exception was
41 last_exc = position;
42 }
44 if( XOP_READS_REG1(it) ) { // Update live-range for op0
45 reg0 = XOP_REG1(it);
46 if( current[reg0] == NULL ) {
47 current[reg0] = range_next++;
48 if( current[reg0] == range_end )
49 return FALSE;
50 current[reg0]->start = it;
51 current[reg0]->offset = position;
52 current[reg0]->writeback = FALSE; // register is already coherent
53 }
54 current[reg0]->end = it;
55 current[reg0]->length = position - current[reg0]->offset;
56 }
58 if( XOP_READS_REG2(it) ) {
59 reg1 = XOP_REG2(it);
60 if( current[reg1] == NULL ) {
61 current[reg1] = range_next++;
62 if( current[reg1] == range_end )
63 return FALSE;
64 current[reg1]->start = it;
65 current[reg1]->offset = position;
66 }
67 current[reg1]->end = it;
68 current[reg1]->length = position - current[reg1]->offset;
69 } // op1 is Use-only
71 if( XOP_WRITES_REG1(it) ) {
72 }
74 if( XOP_WRITES_REG2(it) ) {
75 int reg = XOP_REG2(it);
76 if( last_exc < current[reg].end ) {
77 // Value is dead and doesn't need to be spilled.
78 current[reg].writeback = FALSE;
79 }
80 // Kill last range for op1 if we're not using it. Otherwise
81 // this is just a continuation.
82 current[reg] = range_next++;
83 if( current[reg] == range_end )
84 return FALSE;
85 current[reg]->start = it;
86 current[reg]->offset = position;
87 current[reg]->end = it;
88 current[reg]->length = 0;
89 current[reg]->writeback = TRUE;
90 }
92 it = it->next;
93 position++;
94 }
95 return TRUE;
96 }
.