grunwald@FOOBAR.COLORADO.EDU (Dirk Grunwald) (12/13/89)
Do any of the machine descriptions actually use the delayed branch code? I looked for HAVE_DELAYED_BRANCH in the config directory, but didn't see anything. If not, does anyone know if it still works?
meissner@DG-RTP.DG.COM (Michael Meissner) (12/14/89)
> From: grunwald@FOOBAR.COLORADO.EDU (Dirk Grunwald) > Newsgroups: gnu.gcc.bug > Date: 13 Dec 89 00:01:07 GMT > Reply-To: grunwald@foobar.colorado.edu > Distribution: gnu > Organization: GNUs Not Usenet > > > Do any of the machine descriptions actually use the delayed branch > code? I looked for HAVE_DELAYED_BRANCH in the config directory, but > didn't see anything. > > If not, does anyone know if it still works? I have started using it with the 88k stuff (which is not yet merged with the FSF sources). After fixing the major bug, and the two minor ones, it seems to work well, and allowed me to remove some 10 peepholes, which we were using to fill delay slots before. The bugs that I remember are: 1) The delayed branch code would sometimes move a store, after a load, which causes problems if the store and load are to the same memory location. I changed it to consider any store which preceedes loads from memory is considered ineligible due to aliases, and the optimizer not catching all redunant loads, it is better to be safe and a little slower, than fast and produce the wrong answer. The case (from genrecog.c) that produced this check was: p->pi = q->pi; if (*p->pi == 0) p->pi = 0; 2) The file dbranch.c is not included in the list of objects comprising the compiler. This is fairly trivial to do. 3) If you build dbranch.c for a target which does not have delayed branching, you will get undefined errors. I fixed this by enclosing everything after the include files with an appropriate #ifdef. Note, if you want to reply to me personally, you probably should use the email address: meissner@osf.org. If you want to talk about 88k specific stuff, you probably should use: wood@dg-rtp.dg.com. We have put a revmarked version of our changes to 1.36 on our anonymous FTP server (dg-rtp.dg.com), as Tom has mentioned in an other article. This version does include direct support for delayed branching. Here are the patches for fixing the delayed branch code: *** dbranch.c.orig Thu Oct 26 11:17:52 1989 --- dbranch.c Thu Oct 26 13:10:20 1989 *************** *** 99,104 **** --- 99,106 ---- FILE *dbr_dump_file; + #ifdef HAVE_DELAYED_BRANCH + /* The number of unfilled delay slots in the current sequence. */ static int slots_avail; *************** *** 107,112 **** --- 109,119 ---- static int memw; + /* A flag, nonzero indicating that some insn that could not + go in a slot reads from memory. */ + + static int memr; + /* A flag, nonzero indicating that the condition code is written by some insn that couldn't go in a delay slot. */ *************** *** 175,181 **** init_flags () { CLEAR_HARD_REG_SET (regw); ! memw = ccw = 0; note_stores (PATTERN (dinsn), pnote); if (LOG_LINKS (dinsn)) dep_insn_list = copy_rtx (LOG_LINKS (dinsn)); --- 182,188 ---- init_flags () { CLEAR_HARD_REG_SET (regw); ! memw = memr = ccw = 0; note_stores (PATTERN (dinsn), pnote); if (LOG_LINKS (dinsn)) dep_insn_list = copy_rtx (LOG_LINKS (dinsn)); *************** *** 188,213 **** /* Called through note_stores on possibly eligible insn patterns. Checks to see if a register written by the pattern is needed by an already ineligible insn. Sets the global EFLAG nonzero if a dependency ! is found. */ static void ! enote (x, p) ! rtx x; rtx p; { if (eflag == 0) { ! if (GET_CODE (x) == REG) { ! if (reg_used_between_p (x, insn, dinsn)) goto lose; ! if ((!FUNCTION_VALUE_REGNO_P (REGNO (x)) || GET_CODE (dinsn) != CALL_INSN) && ! reg_mentioned_p (x, (PATTERN (dinsn)))) goto lose; } ! else if (x == cc0_rtx && ! reg_used_between_p (x, insn, NEXT_INSN (dinsn))) goto lose; return; lose: --- 195,244 ---- /* Called through note_stores on possibly eligible insn patterns. Checks to see if a register written by the pattern is needed by an already ineligible insn. Sets the global EFLAG nonzero if a dependency ! is found. ! ! Any store which preceedes loads from memory is considered ineligible due ! to aliases, and the optimizer not catching all redunant loads, it is ! better to be safe and a little slower, than fast and produce the wrong ! answer. The case (from genrecog.c) that produced this check was: ! ! p->pi = q->pi; ! if (*p->pi == 0) ! p->pi = 0; */ static void ! enote (dest, p) ! rtx dest; rtx p; { + rtx src = SET_SRC (p); + while (GET_CODE (src) == SUBREG + || GET_CODE (src) == ZERO_EXTRACT + || GET_CODE (src) == SIGN_EXTRACT + || GET_CODE (src) == STRICT_LOW_PART) + src = XEXP (src, 0); + + if (GET_CODE (src) == MEM) + memr = TRUE; + + if (GET_CODE (dest) == MEM) + memw = TRUE; + if (eflag == 0) { ! if (GET_CODE (dest) == MEM && memr) ! goto lose; ! else if (GET_CODE (dest) == REG) { ! if (reg_used_between_p (dest, insn, dinsn)) goto lose; ! if ((!FUNCTION_VALUE_REGNO_P (REGNO (dest)) || GET_CODE (dinsn) != CALL_INSN) && ! reg_mentioned_p (dest, (PATTERN (dinsn)))) goto lose; } ! else if (dest == cc0_rtx && ! reg_used_between_p (dest, insn, NEXT_INSN (dinsn))) goto lose; return; lose: *************** *** 233,239 **** - is in the dependency list of an ineligible insn. - writes a hard register needed by an ineligible insn. - reads a register written by an ineligible insn. ! - refers to memory. - sets the condition code. - violates a machine-dependent constraint. */ --- 264,270 ---- - is in the dependency list of an ineligible insn. - writes a hard register needed by an ineligible insn. - reads a register written by an ineligible insn. ! - refers to volatile memory. - sets the condition code. - violates a machine-dependent constraint. */ *************** *** 244,253 **** rtx pat = PATTERN (insn); int i,s; - /* See if there are any explicit dependencies on this insn. */ - if (in_dep_list_p (insn)) - return 0; - /* Check for implicit dependencies by calling enote on each store rtx. ENOTE makes sure that no ineligible instruction refers to a register in a way that flow analysis --- 275,280 ---- *************** *** 257,269 **** if (eflag) return 0; ! /* Check for volatile memory refs if any already ineligible. */ ! ! if (memw && volatile_refs_p (pat)) ! { ! memw = TRUE; ! return 0; ! } /* See if it refers to any regs that are clobbered by ineligibles. */ --- 284,297 ---- if (eflag) return 0; ! /* See if there are any explicit dependencies on this insn. */ ! if (in_dep_list_p (insn)) ! return 0; ! ! /* Check for volatile memory refs if any other memory ref has ! been made. */ ! if ((memw | memr) && volatile_refs_p (pat)) ! return 0; /* See if it refers to any regs that are clobbered by ineligibles. */ *************** *** 447,449 **** --- 475,479 ---- first = NEXT_INSN (insn); } } + + #endif /* ifdef HAVE_DELAYED_BRANCH */ -- Michael Meissner, Data General. Until 12/15: meissner@dg-rtp.DG.COM After 12/15: meissner@osf.org