/* src/vm/jit/loop/analyze.c - bound check removal functions
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Christopher Kruegel
bounds are never violated. The function to call is
optimize_loops().
- $Id: analyze.c 4000 2005-12-22 14:05:01Z twisti $
-
*/
struct LoopElement *le;
#ifdef LOOP_DEBUG
- /* printf("insert_exception called with %d-%d and loop %d\n", ex->start->debug_nr, ex->end->debug_nr, lc->loop_head); */
+ /* printf("insert_exception called with %d-%d and loop %d\n", ex->start->nr, ex->end->nr, lc->loop_head); */
#endif
/* if child node is reached immediately insert exception into the tree */
show_tree(ld->root, 0);
printf(" --- End ---\n");
#endif
- for (len = 0; len < cd->exceptiontablelength; ++len)
- insert_exception(m, ld->root, cd->exceptiontable + len);
+ for (len = 0; len < jd->exceptiontablelength; ++len)
+ insert_exception(m, ld->root, jd->exceptiontable + len);
/* determine sequence of loops for optimization by topological sort */
}
/* check for exceptions */
- /* printf("done\n*** Analyze for EXCEPTIONS(%d) . ", cd->exceptiontablelength); */
+ /* printf("done\n*** Analyze for EXCEPTIONS(%d) . ", jd->exceptiontablelength); */
- if (!cd->exceptiontablelength) /* when there are no exceptions, exit */
+ if (!jd->exceptiontablelength) /* when there are no exceptions, exit */
return 1;
if ((ld->c_exceptionGraph = (struct depthElement **) malloc(sizeof(struct depthElement *) * m->basicblockcount)) == NULL)
/* for all nodes that start catch block check whether they are part of loop */
for (i = 0; i < ld->c_old_xtablelength; i++) {
- value = m->basicblockindex[cd->exceptiontable[i].startpc];
+ value = m->basicblockindex[jd->exceptiontable[i].startpc];
le = lc->nodes;
while (le != NULL) {
/* build a graph structure, that contains all nodes that are */
/* part of the catc block */
- dF_Exception(m, ld, -1, m->basicblockindex[cd->exceptiontable[i].handlerpc]);
+ dF_Exception(m, ld, -1, m->basicblockindex[jd->exceptiontable[i].handlerpc]);
/* if array index variables are modified there, return 0 */
- if (quick_scan(m, ld, m->basicblockindex[cd->exceptiontable[i].handlerpc]) > 0) {
+ if (quick_scan(m, ld, m->basicblockindex[jd->exceptiontable[i].handlerpc]) > 0) {
#ifdef ENABLE_STATISTICS
ld->c_stat_exception++;
#endif
case TEST_CONST_ALENGTH: /* a const is tested against array length */
/* does a test already exist for this array */
- tc = ld->c_constraints[cd->maxlocals];
+ tc = ld->c_constraints[jd->maxlocals];
while (tc != NULL) {
if ((tc->type == TEST_CONST_ALENGTH) && (tc->arrayRef == arrayRef)) {
if (constant > tc->constant)
tc->type = TEST_CONST_ALENGTH;
tc->arrayRef = arrayRef;
tc->constant = constant;
- tc->next = ld->c_constraints[cd->maxlocals];
- ld->c_constraints[cd->maxlocals] = tc;
+ tc->next = ld->c_constraints[jd->maxlocals];
+ ld->c_constraints[jd->maxlocals] = tc;
ld->c_needed_instr += 4;
/* if arrayRef is not already tested against null, insert that test */
/* checks */
/*!! varRef -> maxlocals */
/* search if test already exists */
- tc = ld->c_constraints[cd->maxlocals];
+ tc = ld->c_constraints[jd->maxlocals];
while (tc != NULL) {
if (tc->type == TEST_RS_ZERO) {
if (constant < tc->constant)
c_mem_error();
tc->type = TEST_RS_ZERO;
tc->constant = constant;
- tc->next = ld->c_constraints[cd->maxlocals];
- ld->c_constraints[cd->maxlocals] = tc;
+ tc->next = ld->c_constraints[jd->maxlocals];
+ ld->c_constraints[jd->maxlocals] = tc;
ld->c_needed_instr += (2 + ld->c_rs_needed_instr);
/* if arrayRef on right side is not already tested against null, */
/* checks */
/*!! varRef -> maxlocals */
/* search if test already exists */
- tc = ld->c_constraints[cd->maxlocals];
+ tc = ld->c_constraints[jd->maxlocals];
while (tc != NULL)
{
if ((tc->type == TEST_RS_ALENGTH) && (tc->arrayRef == arrayRef))
tc->type = TEST_RS_ALENGTH;
tc->arrayRef = arrayRef;
tc->constant = constant;
- tc->next = ld->c_constraints[cd->maxlocals];
- ld->c_constraints[cd->maxlocals] = tc;
+ tc->next = ld->c_constraints[jd->maxlocals];
+ ld->c_constraints[jd->maxlocals] = tc;
ld->c_needed_instr += (3 + ld->c_rs_needed_instr);
/* if arrayRef is not already tested against null, insert that test */
/* copy node */
new = DMNEW(basicblock, 1);
memcpy(new, bptr, sizeof(basicblock));
- new->debug_nr = m->c_debug_nr++;
+ new->nr = -1;
ld->c_last_block_copied = new;
memcpy(new, ex, sizeof(exceptiontable));
/* Increase number of exceptions */
- ++cd->exceptiontablelength;
+ ++jd->exceptiontablelength;
ex->next = new;
ex->down = new;
/* Increase number of exceptions */
- ++cd->exceptiontablelength;
+ ++jd->exceptiontablelength;
ex->next = new;
ex->down = new;
{
bptr = DMNEW(basicblock, 1);
memcpy(bptr, le->block, sizeof(basicblock));
- bptr->debug_nr = m->c_debug_nr++;
+ bptr->nr = -1;
/* determine beginning of copied loop to extend exception handler, that */
/* protect this loop */
/* copy current loop header to new basic block */
memcpy(bptr, loop_head, sizeof(basicblock));
- bptr->debug_nr = m->c_debug_nr++;
+ bptr->nr = -1;
/* insert the new basic block and move header before first loop node */
le = lc->nodes;
}
/* adjust exceptions */
- ex = cd->exceptiontable;
+ ex = jd->exceptiontable;
while (ex != NULL) {
/* if an exception covers whole loop and starts at first loop node, it */
stackdepth = loop_head->indepth;
/* step through all inserted checks and create instructions for them */
- for (i=0; i<cd->maxlocals+1; ++i)
+ for (i=0; i<jd->maxlocals+1; ++i)
{
tc1 = ld->c_constraints[i];
while (tc1 != NULL)
printf("C_ERROR: debugging error 0x03\n");
changed = 0;
- for (i=0; i<cd->maxlocals; ++i) {
+ for (i=0; i<jd->maxlocals; ++i) {
if (c1[i] == NULL) {
if (c2[i] != NULL) { /* a change in c2 is updated in c1 */
changed = 1;
changed = 0;
- for (i=0; i<cd->maxlocals; ++i) {
+ for (i=0; i<jd->maxlocals; ++i) {
if (c1[i] == NULL) {
if (c2[i] != NULL) { /* update changes in c2 in c1 */
if ((c1[i] = (struct Changes *) malloc (sizeof(struct Changes))) == NULL)
int i;
struct Changes **t;
- if ((t = (struct Changes **) malloc(cd->maxlocals * sizeof(struct Changes *))) == NULL)
+ if ((t = (struct Changes **) malloc(jd->maxlocals * sizeof(struct Changes *))) == NULL)
c_mem_error();
- for (i=0; i<cd->maxlocals; ++i) { /* for all array elements (vars) do */
+ for (i=0; i<jd->maxlocals; ++i) { /* for all array elements (vars) do */
if (c[i] == NULL)
t[i] = NULL;
else {
int i, head, node;
struct Changes **changes;
- if ((changes = (struct Changes **) malloc(cd->maxlocals * sizeof(struct Changes *))) == NULL)
+ if ((changes = (struct Changes **) malloc(jd->maxlocals * sizeof(struct Changes *))) == NULL)
c_mem_error();
head = ld->c_current_head = lc->loop_head;
ld->c_needed_instr = ld->c_rs_needed_instr = 0;
/* init array for null ptr checks */
- for (i=0; i<cd->maxlocals; ++i)
+ for (i=0; i<jd->maxlocals; ++i)
ld->c_null_check[i] = 0;
d->changes = NULL;
}
- for (i=0; i < cd->maxlocals; ++i) {
+ for (i=0; i < jd->maxlocals; ++i) {
ld->c_var_modified[i] = 0;
if (changes[i] != NULL) {
changes[i] = NULL;
}
}
- for (i=0; i < (cd->maxlocals+1); ++i) {
+ for (i=0; i < (jd->maxlocals+1); ++i) {
if (ld->c_constraints[i] != NULL) {
ld->c_constraints[i] = NULL;
}
}
-/* This function preforms necessary setup work, before the recursive function
- optimize_single loop can be called.
-*/
-void optimize_loops(methodinfo *m, codegendata *cd, loopdata *ld)
+/* optimize_loops **************************************************************
+
+ This function preforms necessary setup work, before the recursive
+ function optimize_single loop can be called.
+
+*******************************************************************************/
+
+void optimize_loops(jitdata *jd)
{
- LoopContainer *lc = ld->c_allLoops;
+ methodinfo *m;
+ codegendata *cd;
+ loopdata *ld;
+ LoopContainer *lc;
+
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ ld = jd->ld;
+
+ lc = ld->c_allLoops;
/* first, merge loops with same header node - all loops with the same */
/* header node are optimizied in one pass, because they all depend on the */
/* create array with entries for current loop */
ld->c_current_loop = DMNEW(int, m->basicblockcount);
ld->c_toVisit = DMNEW(int, m->basicblockcount);
- ld->c_var_modified = DMNEW(int, cd->maxlocals);
- ld->c_null_check = DMNEW(int, cd->maxlocals);
+ ld->c_var_modified = DMNEW(int, jd->maxlocals);
+ ld->c_null_check = DMNEW(int, jd->maxlocals);
- if ((ld->c_constraints = (struct Constraint **) malloc((cd->maxlocals+1) * sizeof(struct Constraint *))) == NULL)
+ if ((ld->c_constraints = (struct Constraint **) malloc((jd->maxlocals+1) * sizeof(struct Constraint *))) == NULL)
c_mem_error();
#ifdef ENABLE_STATISTICS
/* init vars needed by all loops */
ld->c_needs_redirection = false;
ld->c_newstart = NULL;
- ld->c_old_xtablelength = cd->exceptiontablelength;
+ ld->c_old_xtablelength = jd->exceptiontablelength;
/* loops have been topologically sorted */
lc = ld->c_allLoops;