diff options
Diffstat (limited to 'gcc/emit-rtl.c')
| -rw-r--r-- | gcc/emit-rtl.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 4564a0b..46fefda 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -2138,6 +2138,65 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset) return new_rtx; } +/* A fake decl that is used as the MEM_EXPR of spill slots. */ +static GTY(()) tree spill_slot_decl; + +static tree +get_spill_slot_decl (void) +{ + tree d = spill_slot_decl; + rtx rd; + + if (d) + return d; + + d = build_decl (VAR_DECL, get_identifier ("%sfp"), void_type_node); + DECL_ARTIFICIAL (d) = 1; + DECL_IGNORED_P (d) = 1; + TREE_USED (d) = 1; + TREE_THIS_NOTRAP (d) = 1; + spill_slot_decl = d; + + rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx); + MEM_NOTRAP_P (rd) = 1; + MEM_ATTRS (rd) = get_mem_attrs (new_alias_set (), d, const0_rtx, + NULL_RTX, 0, BLKmode); + SET_DECL_RTL (d, rd); + + return d; +} + +/* Given MEM, a result from assign_stack_local, fill in the memory + attributes as appropriate for a register allocator spill slot. + These slots are not aliasable by other memory. We arrange for + them all to use a single MEM_EXPR, so that the aliasing code can + work properly in the case of shared spill slots. */ + +void +set_mem_attrs_for_spill (rtx mem) +{ + alias_set_type alias; + rtx addr, offset; + tree expr; + + expr = get_spill_slot_decl (); + alias = MEM_ALIAS_SET (DECL_RTL (expr)); + + /* We expect the incoming memory to be of the form: + (mem:MODE (plus (reg sfp) (const_int offset))) + with perhaps the plus missing for offset = 0. */ + addr = XEXP (mem, 0); + offset = const0_rtx; + if (GET_CODE (addr) == PLUS + && GET_CODE (XEXP (addr, 1)) == CONST_INT) + offset = XEXP (addr, 1); + + MEM_ATTRS (mem) = get_mem_attrs (alias, expr, offset, + MEM_SIZE (mem), MEM_ALIGN (mem), + GET_MODE (mem)); + MEM_NOTRAP_P (mem) = 1; +} + /* Return a newly created CODE_LABEL rtx with a unique label number. */ rtx |
