On Sun, Jul 8, 2012 at 2:23 PM, Alan Lehotsky <[email protected]> wrote:
> When a peephole is recognized, the first insn in the group is replaced by a
> pseudo insn that contains all the referenced operands in the TEMPLATE and
> sets an INSN_CODE to indicate which peephole matched.
>
> This is all well and good, except that if the peephole involves a CALL_INSN,
> final_scan_insn() will invoke call_from_call_insn() to try and get the call
> RTL. But if the peephole is in fact some kind of a tail call, we no longer
> have a call expression to be found and end up asserting in
> call_from_call_insn().
Simple answer don't use peephole optimization to perform the tail call
optimization. There are better ways of performing that optimization.
Thanks,
Andrew
>
> I think I can work around this by switching to a define_peephole2 converting
> the call & return into an unspec, or maybe by doing a match tthat grabs the
> whole call as an operand instead of just the function address.
>
> I'm not sure if the correct fix to this involves changing the way genpeep.c
> works or changing call_from_call_insn to be more forgiving - either one seems
> really difficult unless there's existing code that transmutes top-level RTL
> among CALL_INSN, JUMP_INSN, etc already...
>
>
> Just in case I'm doing something stupid, here's my peephole
>
> (define_peephole
> [
> (parallel [(set (reg:SI RV_REGNUM)
> (call (match_operand:SI 0 "memory_operand" "")
> (match_operand 1 "" "")))
> (clobber (reg:SI LR_REGNUM))])
> (parallel [(use (match_operand 2 "ieu_operand" "rm"))
> (return)])
> ]
> "!final_sequence"
>
> {
> if (CONSTANT_P (operands[0]))
> return "jmp\t%0\; mov\tr0,%2";
> else
> return "ret\t%0\; mov\tr0,%2";
> }
>
> [(set_attr "type" "call")]
> )
>