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]

[new-regalloc-branch] bunch of things [10/10]


The tenth and last.  Hey I can count.

I now remember if a web crosses a call (though I don't yet use this info).

Also, in case of complicated insns, with different (set)'s make a conflict
of all undefined bits as they flowed into the insn, even if that insn
partly defines also those bits.  So remember the original use->undefined
over all defs in an insn, accumulate the change to that elsewhere, and
update it only after all defs are processed.

Also dump some info on insn constraints as a start to my final goal:  Get
rid of reload ;-)

Btw. my current plan on the last one is:
1) make all insns structurally correct (still working on pseudos)
   By this I mean, e.g. make all "must-match" constraints be fullfilled
   Where a (mem) is, although not allowed, fix this by attaching
   appropriate copy insns.  Make insns basically recognizable by e.g.
   fiddling/reloading some operands.
   Evtl. make addresses in (mem) structurally valid.
   And similar stuff.
   I.e. this would be something like reload on pseudos.  All under the
   assumption that those pseudos will later get the correct hardregs
   to really make the insns valid.  I.e. the goal is, that each insn after
   this is strictly recognizable with the difference, that pseudos are
   allowed, where (any) hardregs, or a stackslot are.
1.5) This can either happen in 1) or 2) or on it's own.
   resolve conflicting constraints.
   If a pseudo is used in places where nonintersecting reg-classes are
   required (or the intersection is too small), fix this by splitting that
   pseudo into two, using one only in one part of all uses, the other in
   the rest (of course may be iterativly splitting one into even more
   pseudos).  The connection between the two is by copy insns at strategic
   places, may be going through an intermediate stack-slot.  Those
   copy-insns are potentially removed by coalescing (if the initial
   splitting was based not on non-intersection, but on resulting in a too
   small class).
   Note, that we still have only pseudos.
2) go through all uses of pseudos, noting all constraints restricting its
   usabe_regs set (either by explicit insn constraints, or by their us in
   address expression or similar stuff)
   This can now be colored normally and would ensure valid insns are
   produced.
Also register elimination needs to be done first, and because insns are
added/removed, some local info updating is required of course.

The above thing I'll implement slowly amongst the other things (some of
them being low hanging fruits, so I defer them to a time where I need some
relaxing ;) in ra.c over the next months.  Discussion to this should
either be taken on gcc@, or include me in CC:, because I'm not subscribed
to gcc-patches@ .  Remove the patch if you do this ;)

I'll now committ the diffs.


Ciao,
Michael.

2001-07-13  Michael Matz <matzmich@cs.tu-berlin.de>

	crosses_call new member
	preliminar dump_constraints()
	don't dump all RTL at each regalloc pass
	restore use->undefined for each DEF in one INSN (in case of a multi-set
	insn)

	* ra.c : (struct web_part): New member crosses_call.
	(struct web): Dito.
	(union_web_parts): Merge it.
	(live_out_1): Set it.
	(parts_to_webs): Copy it.
	Restore use-undefined for each DEF on one insn,
	and only update it after all the effects of it have been seen.
	(init_web_parts): Don't initialize web_part.sub_conflicts member.
	(dump_constraints): New.
	(reg_alloc): Call it.
	Don't dump complete RTL for each pass.

-- 
*** ra.c	2001/07/17 09:26:32	1.20
--- ra.c	2001/07/17 11:39:48	1.22
*************** struct web_part
*** 121,126 ****
--- 121,127 ----
    /* The IDs of conflicting root's of other web(part)s.  Only valid,
       if !uplink (part is root).  */
    struct tagged_conflict *sub_conflicts;
+   unsigned int crosses_call : 1;
  };

  /* Web structure used to store info about connected live ranges.  */
*************** struct web
*** 161,166 ****
--- 162,168 ----
  		     rtx doesn't show up in the program.  For such things
  		     an "artificial" subweb is built, and this flag is true
  		     for them.  */
+   int crosses_call;
    int num_conflicts;  /* Number of conflicts currently */
    int num_uses; /* Number of uses this web spans */
    int num_defs; /* Number of defs this web spans. */
*************** static void select_spill PARAMS ((void))
*** 338,349 ****
--- 340,357 ----
  static int get_free_reg PARAMS ((HARD_REG_SET, HARD_REG_SET,
  				 enum machine_mode));
  static int count_long_blocks PARAMS ((HARD_REG_SET, int));
+ static char * hardregset_to_string PARAMS ((HARD_REG_SET));
  static void colorize_one_web PARAMS ((struct web *, int));
  static void assign_colors PARAMS ((void));
+ static void spill_coalescing PARAMS ((sbitmap, sbitmap));
  static void allocate_spill_web PARAMS ((struct web *));
  static void rewrite_program PARAMS ((void));
+ static void actual_spill PARAMS ((void));
  static void emit_colors PARAMS ((struct df *));
+ static void delete_insn_bb PARAMS ((rtx));
+ static void delete_moves PARAMS ((void));
  static int one_pass PARAMS ((struct df *));
+ static void dump_constraints PARAMS ((void));
  static void dump_ra PARAMS ((struct df *));
  static void init_ra PARAMS ((void));
  void reg_alloc PARAMS ((void));
*************** copy_insn_p (insn, source, target)
*** 460,466 ****
       rtx *target;
  {
    rtx d, s;
-   int subreg_seen = 0;
    int uid = INSN_UID (insn);

    if (copy_cache[uid].seen)
--- 468,473 ----
*************** union_web_part_roots (r1, r2)
*** 704,709 ****
--- 711,717 ----
  	    }
  	}
        r2->sub_conflicts = NULL;
+       r1->crosses_call |= r2->crosses_call;
      }
    return r1;
  }
*************** live_out_1 (df, use, insn)
*** 866,871 ****
--- 874,881 ----
        struct df_link *link;
        unsigned int source_regno = ~0;
        unsigned int regno = use->regno;
+       unsigned HOST_WIDE_INT orig_undef = use->undefined;
+       unsigned HOST_WIDE_INT final_undef = use->undefined;
        rtx s = NULL, t;
        wp = find_web_part (wp);
        wp->spanned_insns++;
*************** live_out_1 (df, use, insn)
*** 892,901 ****
--- 902,914 ----
  	  source_regno = REGNO (GET_CODE (s) == SUBREG ? SUBREG_REG (s) : s);
  	  remember_move (insn);
  	}
+       if (GET_CODE (insn) == CALL_INSN)
+ 	wp->crosses_call = 1;
        for (link = DF_INSN_DEFS (df, insn); link; link = link->next)
          if (link->ref)
  	  {
  	    int lap;
+ 	    use->undefined = orig_undef;
  	    if ((lap = defuse_overlap_p (DF_REF_REG (link->ref), use)) != 0)
  	      {
  		if (lap == -1)
*************** live_out_1 (df, use, insn)
*** 917,923 ****
  		else
  		  /* We have a partial overlap.  */
  		  {
! 		    if (use->undefined == 0)
  		      /* Now the USE is completely defined, which means, that
  			 we can stop looking for former DEFs.  */
  		      defined = 1;
--- 930,937 ----
  		else
  		  /* We have a partial overlap.  */
  		  {
! 		    final_undef &= use->undefined;
! 		    if (final_undef == 0)
  		      /* Now the USE is completely defined, which means, that
  			 we can stop looking for former DEFs.  */
  		      defined = 1;
*************** live_out_1 (df, use, insn)
*** 925,931 ****
  		       in USE undefined, we normally would need to create
  		       conflicts between that undefined part and the part of
  		       this DEF which overlapped with some of the formerly
! 		       undfined bits.  We don't need to do this, because both
  		       parts of this DEF (that which overlaps, and that which
  		       doesn't) are written together in this one DEF, and can
  		       not be colored in a way which would conflict with
--- 939,945 ----
  		       in USE undefined, we normally would need to create
  		       conflicts between that undefined part and the part of
  		       this DEF which overlapped with some of the formerly
! 		       undefined bits.  We don't need to do this, because both
  		       parts of this DEF (that which overlaps, and that which
  		       doesn't) are written together in this one DEF, and can
  		       not be colored in a way which would conflict with
*************** live_out_1 (df, use, insn)
*** 983,988 ****
--- 997,1006 ----
  		  }
  	      }
  	  }
+       if (defined)
+ 	use->undefined = 0;
+       else
+ 	use->undefined = final_undef;
      }

    return !defined;
*************** init_web_parts (df)
*** 1548,1559 ****
    for (no = 0; no < df->def_id; no++)
      {
        web_parts[no].ref = df->defs[no];
-       web_parts[no].sub_conflicts = NULL;
      }
    for (no = 0; no < df->use_id; no++)
      {
        web_parts[no + df->def_id].ref = df->uses[no];
-       web_parts[no + df->def_id].sub_conflicts = NULL;
      }
    num_webs = df->def_id + df->use_id;

--- 1566,1575 ----
*************** parts_to_webs (df, part2web)
*** 1787,1792 ****
--- 1803,1809 ----
  	  init_one_web (web, GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
  	  web->id = webnum;
  	  web->span_insns = wp->spanned_insns;
+ 	  web->crosses_call = wp->crosses_call;
  	  id2web[webnum] = web;
  	  webnum++;
  	  if (web->regno < FIRST_PSEUDO_REGISTER)
*************** parts_to_webs (df, part2web)
*** 1849,1855 ****
       XXX we need to merge this loop with the one above, which means, we need
       a way to later override the artificiality.  Beware: currently
       add_subweb_2() relies on the existence of normal subwebs for deducing
!      sane mode to use for the artificial subwebs.  */
    for (i = 0; i < df->def_id + df->use_id; i++)
      {
        struct web_part *wp = &web_parts[i];
--- 1866,1872 ----
       XXX we need to merge this loop with the one above, which means, we need
       a way to later override the artificiality.  Beware: currently
       add_subweb_2() relies on the existence of normal subwebs for deducing
!      a sane mode to use for the artificial subwebs.  */
    for (i = 0; i < df->def_id + df->use_id; i++)
      {
        struct web_part *wp = &web_parts[i];
*************** colorize_one_web (web, hard)
*** 3183,3189 ****
       int hard;
  {
    struct conflict_link *wl;
-   int i;
    HARD_REG_SET colors, conflict_colors;
    int c = -1;
    int bestc = -1;
--- 3200,3205 ----
*************** static void
*** 3665,3671 ****
  actual_spill (void)
  {
    sbitmap spilled;
-   struct web *web;
    struct dlist *d;
    spilled = sbitmap_alloc (num_webs);
    sbitmap_zero (spilled);
--- 3681,3686 ----
*************** one_pass (df)
*** 3883,3888 ****
--- 3898,3935 ----
    return 0;
  }

+ static void
+ dump_constraints (void)
+ {
+   rtx insn;
+   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+     if (INSN_P (insn))
+       {
+ 	int code;
+ 	int uid = INSN_UID (insn);
+ 	int o;
+ 	/* Don't simply force rerecognition, as combine might left us
+ 	   with some unrecongnizable ones, which later leads to aborts
+ 	   in regclass, if we now destroy the remembered INSN_CODE().  */
+ 	/*INSN_CODE (insn) = -1;*/
+ 	code = recog_memoized (insn);
+ 	if (code < 0)
+ 	  {
+ 	    debug_msg (0, "%d: asm insn or not recognizable.\n", uid);
+ 	    continue;
+ 	  }
+ 	debug_msg (0, "%d: code %d {%s}, %d operands, constraints: ",
+ 		   uid, code, insn_data[code].name, recog_data.n_operands);
+         extract_insn (insn);
+ 	/*preprocess_constraints ();*/
+ 	for (o = 0; o < recog_data.n_operands; o++)
+ 	  {
+ 	    debug_msg (0, "%d:%s ", o, recog_data.constraints[o]);
+ 	  }
+ 	debug_msg (0, "\n");
+       }
+ }
+
  /* Dump debugging info for the register allocator.  */
  static void
  dump_ra (df)
*************** reg_alloc (void)
*** 4020,4036 ****
  	{
            emit_colors (df);
  	  delete_moves ();
  	}
        dump_ra (df);
        if (changed && rtl_dump_file)
! 	print_rtl_with_bb (rtl_dump_file, get_insns ());
        free_all_lists ();
        free_mem (df);
        df_finish (df);
      }
    while (changed);
!   if (rtl_dump_file)
!     print_rtl_with_bb (rtl_dump_file, get_insns ());

    no_new_pseudos = 1;
    compute_bb_for_insn (get_max_uid ());
--- 4067,4086 ----
  	{
            emit_colors (df);
  	  delete_moves ();
+ 	  dump_constraints ();
  	}
        dump_ra (df);
        if (changed && rtl_dump_file)
! 	{
! 	  /*print_rtl_with_bb (rtl_dump_file, get_insns ());*/
! 	}
        free_all_lists ();
        free_mem (df);
        df_finish (df);
      }
    while (changed);
!   /*if (rtl_dump_file)
!     print_rtl_with_bb (rtl_dump_file, get_insns ());*/

    no_new_pseudos = 1;
    compute_bb_for_insn (get_max_uid ());


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