From 91b4415af4fafcd53f44b671003e917dd7ec0cfd Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Thu, 9 Feb 2006 19:17:09 +0000 Subject: re PR inline-asm/16194 (global register with inline-asm and clobered) PR inline-asm/16194 gcc: * tree.h (decl_overlaps_hard_reg_set_p) Don't declare. (tree_overlaps_hard_reg_set): Declare. * stmt.c (decl_overlaps_hard_reg_set_p): Now static. Change return type and signature to match function type expected by walk_tree. (tree_overlaps_hard_reg_set): New function. (decl_conflicts_with_clobbers_p): Rename to: (tree_conflicts_with_clobbers_p). Take HARD_REG_SET * argument. Use tree_overlaps_hard_reg_set. Changed caller. * doc/tm.texi (TARGET_MD_ASM_CLOBBERS): Replace decl_overlaps_hard_reg_set_p with tree_overlaps_hard_reg_set. * cris.c (cris_md_asm_clobbers): Likewise. gcc/testsuite: * gcc.dg/pr16194.c: New test. From-SVN: r110810 --- gcc/stmt.c | 73 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 28 deletions(-) (limited to 'gcc/stmt.c') diff --git a/gcc/stmt.c b/gcc/stmt.c index da2f750..3bb4f42 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -105,7 +105,7 @@ static int cost_table_initialized; #define COST_TABLE(I) cost_table_[(unsigned HOST_WIDE_INT) ((I) + 1)] static int n_occurrences (int, const char *); -static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET); +static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *); static void expand_nl_goto_receiver (void); static bool check_operand_nalternatives (tree, tree); static bool check_unique_operand_names (tree, tree); @@ -558,49 +558,66 @@ parse_input_constraint (const char **constraint_p, int input_num, return true; } -/* Return true iff there's an overlap between REGS and DECL, where DECL - can be an asm-declared register. */ +/* Return DECL iff there's an overlap between *REGS and DECL, where DECL + can be an asm-declared register. Called via walk_tree. */ -bool -decl_overlaps_hard_reg_set_p (tree decl, const HARD_REG_SET regs) +static tree +decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data) { - if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) - && DECL_REGISTER (decl) - && REG_P (DECL_RTL (decl)) - && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER) + tree decl = *declp; + const HARD_REG_SET *regs = data; + + if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) { - rtx reg = DECL_RTL (decl); - unsigned int regno; - - for (regno = REGNO (reg); - regno < (REGNO (reg) - + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]); - regno++) - if (TEST_HARD_REG_BIT (regs, regno)) - return true; + if (DECL_REGISTER (decl) + && REG_P (DECL_RTL (decl)) + && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER) + { + rtx reg = DECL_RTL (decl); + unsigned int regno; + + for (regno = REGNO (reg); + regno < (REGNO (reg) + + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]); + regno++) + if (TEST_HARD_REG_BIT (*regs, regno)) + return decl; + } + walk_subtrees = 0; } - - return false; + else if (TYPE_P (decl)) + walk_subtrees = 0; + return NULL_TREE; } +/* If there is an overlap between *REGS and DECL, return the first overlap + found. */ +tree +tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs) +{ + return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL); +} /* Check for overlap between registers marked in CLOBBERED_REGS and - anything inappropriate in DECL. Emit error and return TRUE for error, - FALSE for ok. */ + anything inappropriate in T. Emit error and return the register + variable definition for error, NULL_TREE for ok. */ static bool -decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs) +tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs) { /* Conflicts between asm-declared register variables and the clobber list are not allowed. */ - if (decl_overlaps_hard_reg_set_p (decl, clobbered_regs)) + tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs); + + if (overlap) { error ("asm-specifier for variable %qs conflicts with asm clobber list", - IDENTIFIER_POINTER (DECL_NAME (decl))); + IDENTIFIER_POINTER (DECL_NAME (overlap))); /* Reset registerness to stop multiple errors emitted for a single variable. */ - DECL_REGISTER (decl) = 0; + DECL_REGISTER (overlap) = 0; return true; } @@ -827,7 +844,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs, inout_opnum[ninout++] = i; } - if (decl_conflicts_with_clobbers_p (val, clobbered_regs)) + if (tree_conflicts_with_clobbers_p (val, &clobbered_regs)) clobber_conflict_found = 1; } @@ -923,7 +940,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs, = gen_rtx_ASM_INPUT (TYPE_MODE (type), ggc_strdup (constraints[i + noutputs])); - if (decl_conflicts_with_clobbers_p (val, clobbered_regs)) + if (tree_conflicts_with_clobbers_p (val, &clobbered_regs)) clobber_conflict_found = 1; } -- cgit v1.1