This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] S/390: Enable literal pool handling to deal with hot/cold sections


Hi Uli,

I've applied the attached including your proposed changes after
re-testing on s390 and s390x.

Bye,

-Andreas-

2008-02-13  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (struct constant_pool): New field
	emit_pool_after added.
	(s390_mainpool_start): Set the emit_pool_after flag according
	to the section switch notes.
	(s390_mainpool_finish): Consider emit_pool_after when emitting
	the literal pool at the end of the function.
	(s390_chunkify_start): Force literal pool splits at section
	switch notes.

Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2008-02-13 10:08:54.000000000 +0100
--- gcc/config/s390/s390.c	2008-02-13 16:55:36.000000000 +0100
*************** struct constant_pool
*** 5325,5330 ****
--- 5325,5331 ----
    rtx first_insn;
    rtx pool_insn;
    bitmap insns;
+   rtx emit_pool_after;
  
    struct constant *constants[NR_C_MODES];
    struct constant *execute;
*************** s390_alloc_pool (void)
*** 5351,5356 ****
--- 5352,5358 ----
    pool->pool_insn = NULL_RTX;
    pool->insns = BITMAP_ALLOC (NULL);
    pool->size = 0;
+   pool->emit_pool_after = NULL_RTX;
  
    return pool;
  }
*************** s390_mainpool_start (void)
*** 5681,5686 ****
--- 5683,5689 ----
  {
    struct constant_pool *pool;
    rtx insn;
+   bool in_pool_section_p = false;
  
    pool = s390_alloc_pool ();
  
*************** s390_mainpool_start (void)
*** 5693,5698 ****
--- 5696,5702 ----
  	{
  	  gcc_assert (!pool->pool_insn);
  	  pool->pool_insn = insn;
+ 	  in_pool_section_p = true;
  	}
  
        if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
*************** s390_mainpool_start (void)
*** 5710,5715 ****
--- 5714,5733 ----
  	      s390_add_constant (pool, constant, mode);
  	    }
  	}
+ 
+       /* If hot/cold partitioning is enabled we have to make sure that
+ 	 the literal pool is emitted in the same section where the
+ 	 initialization of the literal pool base pointer takes place.
+ 	 emit_pool_after is only used in the non-overflow case on non
+ 	 Z cpus where we can emit the literal pool at the end of the
+ 	 function body within the text section.  */
+       if (NOTE_P (insn)
+ 	  && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+ 	{
+ 	  if (in_pool_section_p)
+ 	    pool->emit_pool_after = PREV_INSN (insn);
+ 	  in_pool_section_p = !in_pool_section_p;
+ 	}
      }
  
    gcc_assert (pool->pool_insn || pool->size == 0);
*************** s390_mainpool_start (void)
*** 5724,5729 ****
--- 5742,5752 ----
        pool = NULL;
      }
  
+   /* If the functions ends with the section where the literal pool
+      should be emitted set the marker to its end.  */
+   if (pool && in_pool_section_p)
+     pool->emit_pool_after = get_last_insn ();
+ 
    return pool;
  }
  
*************** s390_mainpool_finish (struct constant_po
*** 5771,5777 ****
    /* On S/390, if the total size of the function's code plus literal pool
       does not exceed 4096 bytes, we use BASR to set up a function base
       pointer, and emit the literal pool at the end of the function.  */
!   else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
  	   + pool->size + 8 /* alignment slop */ < 4096)
      {
        insn = gen_main_base_31_small (base_reg, pool->label);
--- 5794,5800 ----
    /* On S/390, if the total size of the function's code plus literal pool
       does not exceed 4096 bytes, we use BASR to set up a function base
       pointer, and emit the literal pool at the end of the function.  */
!   else if (INSN_ADDRESSES (INSN_UID (pool->emit_pool_after))
  	   + pool->size + 8 /* alignment slop */ < 4096)
      {
        insn = gen_main_base_31_small (base_reg, pool->label);
*************** s390_mainpool_finish (struct constant_po
*** 5782,5788 ****
        insn = emit_label_after (pool->label, insn);
        INSN_ADDRESSES_NEW (insn, -1);
  
!       insn = get_last_insn ();
        pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
        INSN_ADDRESSES_NEW (pool->pool_insn, -1);
  
--- 5805,5815 ----
        insn = emit_label_after (pool->label, insn);
        INSN_ADDRESSES_NEW (insn, -1);
  
!       /* emit_pool_after will be set by s390_mainpool_start to the
! 	 last insn of the section where the literal pool should be
! 	 emitted.  */
!       insn = pool->emit_pool_after;
! 
        pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
        INSN_ADDRESSES_NEW (pool->pool_insn, -1);
  
*************** s390_chunkify_start (void)
*** 5881,5886 ****
--- 5908,5915 ----
  
    for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
      {
+       bool section_switch_p = false;
+ 
        /* Check for pending LTREL_BASE.  */
        if (INSN_P (insn))
  	{
*************** s390_chunkify_start (void)
*** 5935,5940 ****
--- 5964,5972 ----
  	  gcc_assert (!pending_ltrel);
  	}
  
+       if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+ 	section_switch_p = true;
+ 
        if (!curr_pool
  	  || INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
            || INSN_ADDRESSES (INSN_UID (insn)) == -1)
*************** s390_chunkify_start (void)
*** 5962,5968 ****
  	    extra_size += 6;
  
  	  if (chunk_size < S390_POOL_CHUNK_MIN
! 	      && curr_pool->size < S390_POOL_CHUNK_MIN)
  	    continue;
  
  	  /* Pool chunks can only be inserted after BARRIERs ...  */
--- 5994,6001 ----
  	    extra_size += 6;
  
  	  if (chunk_size < S390_POOL_CHUNK_MIN
! 	      && curr_pool->size < S390_POOL_CHUNK_MIN
! 	      && !section_switch_p)
  	    continue;
  
  	  /* Pool chunks can only be inserted after BARRIERs ...  */
*************** s390_chunkify_start (void)
*** 5974,5994 ****
  	    }
  
  	  /* ... so if we don't find one in time, create one.  */
!           else if ((chunk_size > S390_POOL_CHUNK_MAX
! 	           || curr_pool->size > S390_POOL_CHUNK_MAX))
  	    {
                rtx label, jump, barrier;
  
! 	      /* We can insert the barrier only after a 'real' insn.  */
! 	      if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
! 		continue;
! 	      if (get_attr_length (insn) == 0)
! 		continue;
! 
! 	      /* Don't separate LTREL_BASE from the corresponding
  		 LTREL_OFFSET load.  */
! 	      if (pending_ltrel)
! 		continue;
  
  	      label = gen_label_rtx ();
  	      jump = emit_jump_insn_after (gen_jump (label), insn);
--- 6007,6039 ----
  	    }
  
  	  /* ... so if we don't find one in time, create one.  */
!           else if (chunk_size > S390_POOL_CHUNK_MAX
! 	           || curr_pool->size > S390_POOL_CHUNK_MAX
! 		   || section_switch_p)
  	    {
                rtx label, jump, barrier;
  
! 	      if (!section_switch_p)
! 		{
! 		  /* We can insert the barrier only after a 'real' insn.  */
! 		  if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
! 		    continue;
! 		  if (get_attr_length (insn) == 0)
! 		    continue;
! 		  /* Don't separate LTREL_BASE from the corresponding
  		 LTREL_OFFSET load.  */
! 		  if (pending_ltrel)
! 		    continue;
! 		}
! 	      else
! 		{
! 		  gcc_assert (!pending_ltrel);
! 
! 		  /* The old pool has to end before the section switch
! 		     note in order to make it part of the current
! 		     section.  */
! 		  insn = PREV_INSN (insn);
! 		}
  
  	      label = gen_label_rtx ();
  	      jump = emit_jump_insn_after (gen_jump (label), insn);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]