Search
lxdream.org :: lxdream/src/xlat/dce.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/xlat/dce.c
changeset 1006:3a169c224c12
author nkeynes
date Tue Apr 07 10:55:03 2009 +0000 (13 years ago)
branchxlat-refactor
permissions -rw-r--r--
last change Commit current work-in-progress to xlat-refactor branch
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/xlat/dce.c Tue Apr 07 10:55:03 2009 +0000
1.3 @@ -0,0 +1,98 @@
1.4 +/**
1.5 + * $Id: dce.c 931 2008-10-31 02:57:59Z nkeynes $
1.6 + *
1.7 + * Implementation of simple dead code elimination based on a reverse pass
1.8 + * through the code.
1.9 + *
1.10 + * Copyright (c) 2009 Nathan Keynes.
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.15 + * (at your option) any later version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful,
1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.20 + * GNU General Public License for more details.
1.21 + */
1.22 +
1.23 +/**
1.24 + * Traverse the block in reverse, killing any dead instructions as we
1.25 + * go. Instructions are dead iff no values they write are read, and all
1.26 + * source registers written are overwritten before the end of the block.
1.27 + *
1.28 + * Dead instructions that may be exposed by an exception are moved to
1.29 + * the exception block rather than being unconditionally removed.
1.30 + */
1.31 +int xir_dead_code_elimination( xir_basic_block_t xbb, xir_op_t begin, xir_op_t end )
1.32 +{
1.33 + char source_regs[MAX_TEMP_REGISTER+1];
1.34 + char target_regs[MAX_TARGET_REGISTER];
1.35 + char flags_live;
1.36 +
1.37 + /* Initially all source regs are live */
1.38 + memset( source_regs, 1, sizeof(source_regs) );
1.39 + memset( target_regs, 0, sizeof(target_regs) );
1.40 + for( xir_op_t it = end; it != NULL; it = it->prev ) {
1.41 + /* Assume the instruction is dead, then check if any of the
1.42 + * output args are live */
1.43 + char is_live = 0;
1.44 +
1.45 + if( XOP_WRITES_REG1(it) ) {
1.46 + if( XOP_IS_SRCREG(it,0) ) {
1.47 + is_live = source_regs[XOP_REG1(it)];
1.48 + source_regs[XOP_REG1(it)] = 0;
1.49 + } else if( XOP_IS_TGTREG(it,0) ) {
1.50 + is_live = target_regs[XOP_REG1(it)];
1.51 + target_regs[XOP_REG1(it)] = 0;
1.52 + }
1.53 + }
1.54 + if( XOP_WRITES_REG2(it) ) {
1.55 + if( XOP_IS_SRCREG(it,1) ) {
1.56 + is_live = source_regs[XOP_REG2(it)];
1.57 + source_regs[XOP_REG2(it)] = 0;
1.58 + } else if( XOP_IS_TGTREG(it,1) ) {
1.59 + is_live = target_regs[XOP_REG2(it)];
1.60 + target_regs[XOP_REG2(it)] = 0;
1.61 + }
1.62 + }
1.63 +
1.64 + if( XOP_WRITES_FLAGS(it) ) {
1.65 + is_live ||= flags_live;
1.66 + flags_live = 0;
1.67 + }
1.68 +
1.69 + /* Exception-raising instructions can't be DCEd */
1.70 + if( XOP_HAS_EXCEPTIONS(it) || XOP_IS_TERMINATOR(it) ||
1.71 + it->opcode == OP_ENTER || it->opcode == OP_BARRIER ) {
1.72 + is_live = 1;
1.73 + }
1.74 +
1.75 + if( !is_live ) {
1.76 + /* Kill it with fire */
1.77 + xir_remove_op(it);
1.78 + } else {
1.79 + /* Propagate live reads */
1.80 + if( XOP_READS_REG1(it) ) {
1.81 + if( XOP_IS_SRCREG(it,0) ) {
1.82 + source_regs[XOP_REG1(it)] = 1;
1.83 + } else if( XOP_IS_TGTREG(it,0) ) {
1.84 + target_regs[XOP_REG1(it)] = 1;
1.85 + }
1.86 + }
1.87 + if( XOP_READS_REG2(it) ) {
1.88 + if( XOP_IS_SRCREG(it,1) ) {
1.89 + source_regs[XOP_REG2(it)] = 1;
1.90 + } else if( XOP_IS_TGTREG(it,1) ) {
1.91 + target_regs[XOP_REG2(it)] = 1;
1.92 + }
1.93 + }
1.94 +
1.95 + flags_live ||= XOP_READS_FLAGS(it);
1.96 + }
1.97 +
1.98 + if( it == begin )
1.99 + break;
1.100 + }
1.101 +}
1.102 \ No newline at end of file
.