From 67c3f5800258cc7f24b26b3a62e43eb30eee6df4 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 3 Feb 2007 23:24:05 +0000 Subject: [PATCH 1/1] * lower-subreg.c (simple_move_operand): New static function, broken out of simple_move. Reject LABEL_REF, SYMBOL_REF, and HIGH operands. (simple_move): Call simple_move_operand. (find_decomposable_subregs): Add special handling of MEMs. (can_decompose_p): Rename from cannot_decompose_p. Reverse meaning of return value. If we see a hard register, test whether it can store a word_mode value. Change all callers. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121553 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++ gcc/lower-subreg.c | 71 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 271facbe78e..77e9964be19 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2007-02-03 Ian Lance Taylor + + * lower-subreg.c (simple_move_operand): New static function, + broken out of simple_move. Reject LABEL_REF, SYMBOL_REF, and HIGH + operands. + (simple_move): Call simple_move_operand. + (find_decomposable_subregs): Add special handling of MEMs. + (can_decompose_p): Rename from cannot_decompose_p. Reverse + meaning of return value. If we see a hard register, test whether + it can store a word_mode value. Change all callers. + 2007-02-03 John David Anglin * pa.md (addvdi3, addvsi3, subvdi3, subvsi3, negvdi2, negvsi2): New diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 104a1d98a48..62bfea0a100 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -66,6 +66,31 @@ static bitmap non_decomposable_context; copy from reg M to reg N. */ static VEC(bitmap,heap) *reg_copy_graph; +/* Return whether X is a simple object which we can take a word_mode + subreg of. */ + +static bool +simple_move_operand (rtx x) +{ + if (GET_CODE (x) == SUBREG) + x = SUBREG_REG (x); + + if (!OBJECT_P (x)) + return false; + + if (GET_CODE (x) == LABEL_REF + || GET_CODE (x) == SYMBOL_REF + || GET_CODE (x) == HIGH) + return false; + + if (MEM_P (x) + && (MEM_VOLATILE_P (x) + || mode_dependent_address_p (XEXP (x, 0)))) + return false; + + return true; +} + /* If INSN is a single set between two objects, return the single set. Such an insn can always be decomposed. INSN should have been passed to recog and extract_insn before this is called. */ @@ -87,25 +112,16 @@ simple_move (rtx insn) x = SET_DEST (set); if (x != recog_data.operand[0] && x != recog_data.operand[1]) return NULL_RTX; - if (GET_CODE (x) == SUBREG) - x = SUBREG_REG (x); - if (!OBJECT_P (x)) - return NULL_RTX; - if (MEM_P (x) - && (MEM_VOLATILE_P (x) - || mode_dependent_address_p (XEXP (x, 0)))) + if (!simple_move_operand (x)) return NULL_RTX; x = SET_SRC (set); if (x != recog_data.operand[0] && x != recog_data.operand[1]) return NULL_RTX; - if (GET_CODE (x) == SUBREG) - x = SUBREG_REG (x); - if (!OBJECT_P (x) && GET_CODE (x) != ASM_OPERANDS) - return NULL_RTX; - if (MEM_P (x) - && (MEM_VOLATILE_P (x) - || mode_dependent_address_p (XEXP (x, 0)))) + /* For the src we can handle ASM_OPERANDS, and it is beneficial for + things like x86 rdtsc which returns a DImode value. */ + if (GET_CODE (x) != ASM_OPERANDS + && !simple_move_operand (x)) return NULL_RTX; /* We try to decompose in integer modes, to avoid generating @@ -259,7 +275,7 @@ find_decomposable_subregs (rtx *px, void *data) return -1; } } - else if (GET_CODE (x) == REG) + else if (REG_P (x)) { unsigned int regno; @@ -299,6 +315,16 @@ find_decomposable_subregs (rtx *px, void *data) } } } + else if (MEM_P (x)) + { + enum classify_move_insn cmi_mem = NOT_SIMPLE_MOVE; + + /* Any registers used in a MEM do not participate in a + SIMPLE_MOVE or SIMPLE_PSEUDO_REG_MOVE. Do our own recursion + here, and return -1 to block the parent's recursion. */ + for_each_rtx (&XEXP (x, 0), find_decomposable_subregs, &cmi_mem); + return -1; + } return 0; } @@ -585,22 +611,23 @@ resolve_reg_notes (rtx insn) } } -/* Return whether X can not be decomposed into subwords. */ +/* Return whether X can be decomposed into subwords. */ static bool -cannot_decompose_p (rtx x) +can_decompose_p (rtx x) { if (REG_P (x)) { unsigned int regno = REGNO (x); if (HARD_REGISTER_NUM_P (regno)) - return !validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD); + return (validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD) + && HARD_REGNO_MODE_OK (regno, word_mode)); else - return bitmap_bit_p (non_decomposable_context, regno); + return !bitmap_bit_p (non_decomposable_context, regno); } - return false; + return true; } /* Decompose the registers used in a simple move SET within INSN. If @@ -681,7 +708,7 @@ resolve_simple_move (rtx set, rtx insn) /* If SRC is a register which we can't decompose, or has side effects, we need to move via a temporary register. */ - if (cannot_decompose_p (src) + if (!can_decompose_p (src) || side_effects_p (src) || GET_CODE (src) == ASM_OPERANDS) { @@ -701,7 +728,7 @@ resolve_simple_move (rtx set, rtx insn) dest_mode = orig_mode; pushing = push_operand (dest, dest_mode); - if (cannot_decompose_p (dest) + if (!can_decompose_p (dest) || (side_effects_p (dest) && !pushing) || (!SCALAR_INT_MODE_P (dest_mode) && !resolve_reg_p (dest) -- 2.11.0