public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, ARM] Fix length attributes for sync.md patterns
@ 2012-07-16 13:46 Ulrich Weigand
  2012-07-17 15:01 ` Richard Earnshaw
  0 siblings, 1 reply; 9+ messages in thread
From: Ulrich Weigand @ 2012-07-16 13:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: patches, ramana.radhakrishnan

Hello,

when testing an out-of-tree patch I ran into a latent bug.
The symptom is error messages along the lines of
/tmp/cc6q0E3x.s:38: Error: co-processor offset out of range
caused by an out-of-range reference to a literal pool constant.
This happens only with -O0.

This turns out to caused by insn_and_split patterns in sync.md
used to represent atomic instructions.  Those will (must) always
be split (usually into some form of compare-and-swap loop).  If
optimization is on, this split happens shortly after reload,
before literal pool placement is finalized.

However, when building with -O0, this split is done very late;
in fact it happens *after* the machine-dependent reorg pass
where literal pools are handled.  This means that this pass
sees the atomic patterns as single insns, and unfortunately,
since they have no length attribute, they are handled as if
they had a default length of 4 bytes.

But since those patterns in the end will expand to at least
5-9 actual machine instructions, this default drastically
underestimates the code size, causing the out of range
references.

The patch below adds length attributes giving conservative
estimates of the final resulting code sizes.  (They could
probably be made more specific, but since this is relevant
only for -O0, that's probably not worth the effort.)

This fixes the problems I was seeing.

Tested on arm-linux-gnueabi with no regressions.

OK for mainline?

Bye,
Ulrich


ChangeLog:

	* config/arm/sync.md (cas_length): New mode attribute.
	(atomic_op_length, atomic_nand_length): Likewise.
	("atomic_compare_and_swap<mode>_1"): Add length attribute.
	("atomic_exchange<mode>"): Likewise.
	("atomic_<sync_optab><mode>"): Likewise.
	("atomic_nand<mode>"): Likewise.
	("atomic_fetch_<sync_optab><mode>"): Likewise.
	("atomic_fetch_nand<mode>"): Likewise.
	("atomic_<sync_optab>_fetch<mode>"): Likewise.
	("atomic_nand_fetch<mode>"): Likewise.

Index: gcc/config/arm/sync.md
===================================================================
*** gcc/config/arm/sync.md	(revision 189459)
--- gcc/config/arm/sync.md	(working copy)
***************
*** 127,138 ****
    {
      arm_split_compare_and_swap (operands);
      DONE;
!   })
  
  (define_mode_attr cas_cmp_operand
    [(SI "arm_add_operand") (DI "cmpdi_operand")])
  (define_mode_attr cas_cmp_str
    [(SI "rIL") (DI "rDi")])
  
  (define_insn_and_split "atomic_compare_and_swap<mode>_1"
    [(set (reg:CC_Z CC_REGNUM)					;; bool out
--- 127,141 ----
    {
      arm_split_compare_and_swap (operands);
      DONE;
!   }
!   [(set_attr "length" "32")])
  
  (define_mode_attr cas_cmp_operand
    [(SI "arm_add_operand") (DI "cmpdi_operand")])
  (define_mode_attr cas_cmp_str
    [(SI "rIL") (DI "rDi")])
+ (define_mode_attr cas_length
+   [(SI "32") (DI "44")])
  
  (define_insn_and_split "atomic_compare_and_swap<mode>_1"
    [(set (reg:CC_Z CC_REGNUM)					;; bool out
***************
*** 155,161 ****
    {
      arm_split_compare_and_swap (operands);
      DONE;
!   })
  
  (define_insn_and_split "atomic_exchange<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")	;; output
--- 158,165 ----
    {
      arm_split_compare_and_swap (operands);
      DONE;
!   }
!   [(set_attr "length" "<cas_length>")])
  
  (define_insn_and_split "atomic_exchange<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")	;; output
***************
*** 175,181 ****
      arm_split_atomic_op (SET, operands[0], NULL, operands[1],
  			 operands[2], operands[3], operands[4]);
      DONE;
!   })
  
  (define_mode_attr atomic_op_operand
    [(QI "reg_or_int_operand")
--- 179,186 ----
      arm_split_atomic_op (SET, operands[0], NULL, operands[1],
  			 operands[2], operands[3], operands[4]);
      DONE;
!   }
!   [(set_attr "length" "20")])
  
  (define_mode_attr atomic_op_operand
    [(QI "reg_or_int_operand")
***************
*** 186,191 ****
--- 191,199 ----
  (define_mode_attr atomic_op_str
    [(QI "rn") (HI "rn") (SI "rn") (DI "r")])
  
+ (define_mode_attr atomic_op_length
+   [(QI "24") (HI "24") (SI "24") (DI "28")])
+ 
  (define_insn_and_split "atomic_<sync_optab><mode>"
    [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua")
  	(unspec_volatile:QHSD
***************
*** 204,210 ****
      arm_split_atomic_op (<CODE>, NULL, operands[3], operands[0],
  			 operands[1], operands[2], operands[4]);
      DONE;
!   })
  
  (define_insn_and_split "atomic_nand<mode>"
    [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua")
--- 212,222 ----
      arm_split_atomic_op (<CODE>, NULL, operands[3], operands[0],
  			 operands[1], operands[2], operands[4]);
      DONE;
!   }
!   [(set_attr "length" "<atomic_op_length>")])
! 
! (define_mode_attr atomic_nand_length
!   [(QI "28") (HI "28") (SI "28") (DI "32")])
  
  (define_insn_and_split "atomic_nand<mode>"
    [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua")
***************
*** 225,231 ****
      arm_split_atomic_op (NOT, NULL, operands[3], operands[0],
  			 operands[1], operands[2], operands[4]);
      DONE;
!   })
  
  (define_insn_and_split "atomic_fetch_<sync_optab><mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
--- 237,244 ----
      arm_split_atomic_op (NOT, NULL, operands[3], operands[0],
  			 operands[1], operands[2], operands[4]);
      DONE;
!   }
!   [(set_attr "length" "<atomic_nand_length>")])
  
  (define_insn_and_split "atomic_fetch_<sync_optab><mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
***************
*** 247,253 ****
      arm_split_atomic_op (<CODE>, operands[0], operands[4], operands[1],
  			 operands[2], operands[3], operands[5]);
      DONE;
!   })
  
  (define_insn_and_split "atomic_fetch_nand<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
--- 260,267 ----
      arm_split_atomic_op (<CODE>, operands[0], operands[4], operands[1],
  			 operands[2], operands[3], operands[5]);
      DONE;
!   }
!   [(set_attr "length" "<atomic_op_length>")])
  
  (define_insn_and_split "atomic_fetch_nand<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
***************
*** 270,276 ****
      arm_split_atomic_op (NOT, operands[0], operands[4], operands[1],
  			 operands[2], operands[3], operands[5]);
      DONE;
!   })
  
  (define_insn_and_split "atomic_<sync_optab>_fetch<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
--- 284,291 ----
      arm_split_atomic_op (NOT, operands[0], operands[4], operands[1],
  			 operands[2], operands[3], operands[5]);
      DONE;
!   }
!   [(set_attr "length" "<atomic_nand_length>")])
  
  (define_insn_and_split "atomic_<sync_optab>_fetch<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
***************
*** 292,298 ****
      arm_split_atomic_op (<CODE>, NULL, operands[0], operands[1],
  			 operands[2], operands[3], operands[4]);
      DONE;
!   })
  
  (define_insn_and_split "atomic_nand_fetch<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
--- 307,314 ----
      arm_split_atomic_op (<CODE>, NULL, operands[0], operands[1],
  			 operands[2], operands[3], operands[4]);
      DONE;
!   }
!   [(set_attr "length" "<atomic_op_length>")])
  
  (define_insn_and_split "atomic_nand_fetch<mode>"
    [(set (match_operand:QHSD 0 "s_register_operand" "=&r")
***************
*** 315,321 ****
      arm_split_atomic_op (NOT, NULL, operands[0], operands[1],
  			 operands[2], operands[3], operands[4]);
      DONE;
!   })
  
  (define_insn "arm_load_exclusive<mode>"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
--- 331,338 ----
      arm_split_atomic_op (NOT, NULL, operands[0], operands[1],
  			 operands[2], operands[3], operands[4]);
      DONE;
!   }
!   [(set_attr "length" "<atomic_nand_length>")])
  
  (define_insn "arm_load_exclusive<mode>"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-07-23 17:59 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-16 13:46 [PATCH, ARM] Fix length attributes for sync.md patterns Ulrich Weigand
2012-07-17 15:01 ` Richard Earnshaw
2012-07-17 15:17   ` Ulrich Weigand
2012-07-17 16:13     ` Richard Earnshaw
2012-07-17 16:33       ` Ulrich Weigand
2012-07-23 13:58       ` [PATCH, ARM] Split all insns before pool placement (Re: [PATCH, ARM] Fix length attributes for sync.md patterns) Ulrich Weigand
2012-07-23 17:07         ` Richard Earnshaw
2012-07-23 17:30           ` [PATCH, ARM] Split all insns before pool placement Ulrich Weigand
2012-07-23 17:59             ` Richard Earnshaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).