This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
optimization/1945 fix
- To: gcc-patches at gcc dot gnu dot org
- Subject: optimization/1945 fix
- From: Shane Nay <shane at agendacomputing dot com>
- Date: Thu, 15 Feb 2001 05:07:19 -0800
- Organization: Agenda Computing
- Reply-To: shane at agendacomputing dot com
This is a fix for optimization related bug #1945. It fixes
mips_expand_prologue generation of un-necessary instructions. (And
subsequent abort() at flow.c:3790) In order to be compatible with the mips
compiler, the compiler shifts small structures passed by value into the
high portion of the register. However in that code it did no checks for
relevancy of the instructions it was emmitting.
2001-02-15 Shane Nay <shane@agendacomputing.com>
* mips.c (mips_expand_prologue) Fix un-necessary emission of
instructions for passing of small structures by value.
Broken test case:
struct small_struct {
char achar;
};
void do_error_pass_by_value(struct small_struct t) {
}
int main() {
struct small_struct onest;
onest.achar='a';
do_error_pass_by_value(onest);
}
Index: mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.107
diff -c -3 -p -r1.107 mips.c
*** mips.c 2001/02/05 16:34:40 1.107
--- mips.c 2001/02/15 14:00:51
*************** mips_expand_prologue ()
*** 7115,7125 ****
--- 7115,7164 ----
for (i = 0; i < num; i++)
{
+ rtx insn;
rtx pattern = RTVEC_ELT (adjust, i);
+ int save_reg=0;
if (GET_CODE (pattern) != SET
|| GET_CODE (SET_SRC (pattern)) != ASHIFT)
abort_with_insn (pattern, "Insn is not a shift");
+ /* We need to check to make sure that we should be
+ emitting shift code, because if the argument isn't
+ getting used, it is considered a bug to emit
+ preparation code for it in mips_expand_prologue.
+ */
+ for(insn = seq_stack->next->first;insn != NULL_RTX; insn = NEXT_INSN (insn))
+ {
+ rtx set,src,dest;
+ if (GET_CODE (insn) == CODE_LABEL
+ || GET_CODE (insn) == JUMP_INSN
+ || GET_CODE (insn) == CALL_INSN)
+ break;
+ if (GET_CODE (insn) != INSN)
+ continue;
+ set = PATTERN (insn);
+ if (GET_CODE (set) != SET)
+ continue;
+ src = SET_SRC (set);
+ dest = SET_DEST (set);
+ if (!((GET_CODE (src) == REG
+ || GET_CODE (src) == MEM)
+ &&
+ (GET_CODE (dest) == REG
+ || GET_CODE (src) == MEM)
+ ))
+ continue;
+ if(REGNO (src) == REGNO (XEXP (pattern,0))) {
+ save_reg=1;
+ break;
+ }
+ if(REGNO (dest) == REGNO (XEXP (pattern,0)))
+ break;
+ }
+ if (save_reg == 0)
+ continue;
+
+
PUT_CODE (SET_SRC (pattern), ASHIFTRT);
emit_insn (pattern);
}