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: [RFA] The Integrated Register Allocator


I've briefly played with the IRA patch. Below is a patch necessary to make it work with the Blackfin port.

I've not made any measurements yet, but visually inspecting the results reveals at least one code generation regression which shows up fairly often. In case you want to investigate, I'm providing some details.

To reproduce, compile the attached testcase (a3.i) with a bfin-elf compiler:
./cc1 a3.i -O2 -fomit-frame-pointer -o a3.1.s
./cc1 a3.i -O2 -fira -fomit-frame-pointer -o a3.2.s

The difference is as follows:

P2.H = _reg_known_value_size; | P2 = [P5+4];
P2.L = _reg_known_value_size; | P1.H = _reg_known_value_size;
P1 = [P5+4]; | P1.L = _reg_known_value_size;
P2 = [P2]; | R0 = [P1];
cc =P1<P2 (iu); | R1 = P2;


> cc =R1<R0 (iu);

One extra register move is generated in reload, because IRA produces an insn whose register class requirements aren't met.

In RTL, we have, from the regmove dump:

(insn 21 20 22 4 a3.i:132 (set (reg/v:SI 55 [ regno ])
(mem/s:SI (plus:SI (reg/v/f:SI 56 [ reg ])
(const_int 4 [0x4])) [0 <variable>.rtuint+0 S4 A32])) 14 {*movsi_insn} (nil))


(insn 22 21 23 4 a3.i:133 (set (reg/f:SI 62)
(symbol_ref:SI ("reg_known_value_size") <var_decl 0xb7e672c0 reg_known_value_size>)) 14 {*movsi_insn} (nil))


(insn 23 22 24 4 a3.i:133 (set (reg:SI 63 [ reg_known_value_size ])
(mem/c/i:SI (reg/f:SI 62) [6 reg_known_value_size+0 S4 A32])) 14 {*movsi_insn} (expr_list:REG_DEAD (reg/f:SI 62)
(expr_list:REG_EQUAL (mem/c/i:SI (symbol_ref:SI ("reg_known_value_size") <var_decl 0xb7e672c0 reg_known_value_size>) [6 reg_known_value_size+0 S4 A32])
(nil))))


(insn 24 23 25 4 a3.i:133 (set (reg:BI 34 CC)
(ltu:BI (reg/v:SI 55 [ regno ])
(reg:SI 63 [ reg_known_value_size ]))) 115 {compare_ltu} (expr_list:REG_DEAD (reg:SI 63 [ reg_known_value_size ])
(nil)))


(jump_insn 25 24 26 4 a3.i:133 (set (pc)
        (if_then_else (eq:BI (reg:BI 34 CC)
                (const_int 0 [0x0]))
            (label_ref:SI 40)
            (pc))) 117 {cbranchbi4} (expr_list:REG_DEAD (reg:BI 34 CC)
        (expr_list:REG_BR_PROB (const_int 3900 [0xf3c])
            (nil))))

and in the IRA dump:
Pass 1 for finding allocno costs
[...]
    a6 (r63,l0) best DPREGS, cover MOST_REGS
[...]
    a4 (r55,l0) best PREGS, cover MOST_REGS

Since r55 allows only PREGS, and insn 24 requires its operands to be in the same register class (either both PREGS or both DREGS), it's a poor choice to allocate r63 from DREGS. Hence the best class for it should be PREGS as well. The old allocator appears to be able to get this more consistently right.


Bernd -- This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: config/bfin/bfin.h
===================================================================
--- config/bfin/bfin.h	(revision 133832)
+++ config/bfin/bfin.h	(working copy)
@@ -743,6 +743,11 @@ enum reg_class
  : (REGNO) >= REG_RETS ? PROLOGUE_REGS			\
  : NO_REGS)
 
+#define IRA_COVER_CLASSES				\
+{							\
+    MOST_REGS, AREGS, CCREGS, LIM_REG_CLASSES		\
+}
+
 /* When defined, the compiler allows registers explicitly used in the
    rtl to be used as spill registers but prevents the compiler from
    extending the lifetime of these registers. */
enum rtx_code {
UNKNOWN ,
NIL ,
INCLUDE ,
EXPR_LIST ,
INSN_LIST ,
MATCH_OPERAND ,
MATCH_SCRATCH ,
MATCH_DUP ,
MATCH_OPERATOR ,
MATCH_PARALLEL ,
MATCH_OP_DUP ,
MATCH_PAR_DUP ,
MATCH_INSN ,
DEFINE_INSN ,
DEFINE_PEEPHOLE ,
DEFINE_SPLIT ,
DEFINE_INSN_AND_SPLIT ,
DEFINE_PEEPHOLE2 ,
DEFINE_COMBINE ,
DEFINE_EXPAND ,
DEFINE_DELAY ,
DEFINE_FUNCTION_UNIT ,
DEFINE_ASM_ATTRIBUTES ,
DEFINE_COND_EXEC ,
SEQUENCE ,
ADDRESS ,
DEFINE_CPU_UNIT ,
DEFINE_QUERY_CPU_UNIT ,
EXCLUSION_SET ,
PRESENCE_SET ,
ABSENCE_SET ,
DEFINE_BYPASS ,
DEFINE_AUTOMATON ,
AUTOMATA_OPTION ,
DEFINE_RESERVATION ,
DEFINE_INSN_RESERVATION ,
DEFINE_ATTR ,
ATTR ,
SET_ATTR ,
SET_ATTR_ALTERNATIVE ,
EQ_ATTR ,
ATTR_FLAG ,
INSN ,
JUMP_INSN ,
CALL_INSN ,
BARRIER ,
CODE_LABEL ,
NOTE ,
COND_EXEC ,
PARALLEL ,
ASM_INPUT ,
ASM_OPERANDS ,
UNSPEC ,
UNSPEC_VOLATILE ,
ADDR_VEC ,
ADDR_DIFF_VEC ,
PREFETCH ,
SET ,
USE ,
CLOBBER ,
CALL ,
RETURN ,
TRAP_IF ,
RESX ,
CONST_INT ,
CONST_DOUBLE ,
CONST_VECTOR ,
CONST_STRING ,
CONST ,
PC ,
VALUE ,
REG ,
  LAST_AND_UNUSED_RTX_CODE};
struct rtx_def;
typedef struct rtx_def *rtx;
struct rtvec_def;
typedef struct rtvec_def *rtvec;
typedef struct mem_attrs
{
  int alias;
  rtx offset;
  rtx size;
  unsigned int align;
} mem_attrs;
union rtunion_def
{
  int rtwint;
  int rtint;
  unsigned int rtuint;
  const char *rtstr;
  rtx rtx;
  rtvec rtvec;
  struct basic_block_def *bb;
  mem_attrs *rtmem;
};

enum machine_mode {
VOIDmode, SImode
};
typedef union rtunion_def rtunion;
struct rtx_def
{
  enum rtx_code code: 16;
  enum machine_mode mode : 8;
  unsigned int jump : 1;
  unsigned int call : 1;
  unsigned int unchanging : 1;
  unsigned int volatil : 1;
  unsigned int in_struct : 1;
  unsigned int used : 1;
  unsigned integrated : 1;
  unsigned frame_related : 1;
  rtunion fld[1];
};
rtx *reg_base_value;
rtx *new_reg_base_value;
unsigned int reg_base_value_size;
static rtx static_reg_base_value[35];
static rtx *alias_invariant;
rtx *reg_known_value;
unsigned int reg_known_value_size;

void
clear_reg_alias_info (reg)
     rtx reg;
{
  rtx const _rtx = (reg);
  const int _n = (0);
  if (((enum rtx_code) (_rtx)->code) != (REG))
    rtl_check_failed_code1 (_rtx, (REG), "../../binutils/gcc/alias.c", 1055, __FUNCTION__);
  unsigned int regno = _rtx->fld[_n].rtuint;
  if (regno < reg_known_value_size && regno >= 35)
    reg_known_value[regno] = reg;
}

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