enable-checking failure record_insns () and PARALLEL

grahams grahams@rcp.co.uk
Mon Apr 24 08:44:00 GMT 2000


jeff

The record_insns () call in question is in the routine
thread_prologue_and_epilogue_insns () function.c

here's the relevant extract from the routine

#ifdef HAVE_sibcall_epilogue
  /* Emit sibling epilogues before any sibling call sites.  */
  for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
    {
      basic_block bb = e->src;
      rtx insn = bb->end;
      rtx i;

      if (GET_CODE (insn) != CALL_INSN
          || ! SIBLING_CALL_P (insn))
        continue;

      start_sequence ();
      seq = gen_sibcall_epilogue ();
      end_sequence ();

      i = PREV_INSN (insn);
      emit_insn_before (seq, insn);

      /* Update the UID to basic block map.  */
      for (i = NEXT_INSN (i); i != insn; i = NEXT_INSN (i))
        set_block_for_insn (i, bb);

      /* Retain a map of the epilogue insns.  Used in life analysis to
         avoid getting rid of sibcall epilogue insns.  */
      record_insns (seq, &sibcall_epilogue);
    }
#endif

The important bit here is the following

      start_sequence ();
      seq = gen_sibcall_epilogue ();
      end_sequence ();

Now on the i386 gen_sibcall_epilogue () is a define_insn in
i386.md which appears in insn-emit.c as

rtx
gen_sibcall_epilogue ()
{
  rtx _val = 0;
  start_sequence ();
  {
ix86_expand_epilogue (0); DONE;
  }
  emit_insn (const1_rtx);
  _val = gen_sequence ();
  end_sequence ();
  return _val;
}

So the sequence generated by gen_sibcall_epilogue ()
will consists of whatever instructions get emitted 
by the call to ix86_expand_epilogue (0).

What I think is happening (it coresponds to what I am 
seeing) is that ix86_expand_epilogue () is emitting a 
single insn which is a PARALLEL. 

Now when gen_sequence () is called it finds that only one
insn has been emitted so it returns a single insn rather 
than a degenerate SEQUENCE of consisting of just one insn.

This is the sequence I am seeing generated by 
gen_sibcall_epilogue () and is being passed to
record_insns ().

(parallel[ 
        (set (reg:SI 7 esp)
            (plus:SI (reg:SI 7 esp)
                (const_int 12 [0xc])))
        (clobber (reg:CC 17 flags))
    ] )


which comes from the call to gen_addsi3() in 
ix86_emit_epilogue_esp_adjustment () and is the only insn emitted.

Here's a trival testcase which causes gen_sibcall_epilogue () to 
generate a sequence consisting of a single insn which is a
parallel.

Compile the following on x86 linux using "-O2 -fomit-frame-pointer"

---------------------------------------------------------
extern void exit(int);

void
fatal_io_error (name)
  const char *name;
{
  exit (0);
}
---------------------------------------------------------

Graham


More information about the Gcc-patches mailing list