This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
More PRE problems
- From: law at redhat dot com
- To: dberlin at dberlin dot org
- Cc: gcc at gcc dot gnu dot org
- Date: Fri, 14 Nov 2003 12:38:32 -0700
- Subject: More PRE problems
- Reply-to: law at redhat dot com
I don't even know where to start with this one.
Here's the code before PRE:
# BLOCK 0
# PRED: ENTRY (fallthru,exec)
switch ((unsigned int)type_14)
{
case 0: goto <Ub414>
case 7: goto <Uea6c>
default : goto <Ued98>
}
# SUCC: 12 (exec) 10 (exec) 1 (exec)
# BLOCK 1
# PRED: 0 (exec)
<Ub414>:;
T.104_19 = regno_18 / 32;
# VUSE <reload_reg_used_in_input_addr_21>;
T.105_22 = reload_reg_used_in_input_addr[i_20][T.104_19];
T.106_23 = regno_18 % 32;
T.107_24 = (int)T.106_23;
T.108_25 = T.105_22 >> T.107_24;
T.109_26 = (int)T.108_25;
T.110_27 = T.109_26 & 1;
if (T.110_27 != 0) goto <Ub4fc>; else goto <Ueef4>;
# SUCC: 2 (false,exec) 4 (true,exec)
# BLOCK 2
# PRED: 1 (false,exec)
<Ueef4>:;
# VUSE <reload_reg_used_in_inpaddr_addr_29>;
T.111_30 = reload_reg_used_in_inpaddr_addr[i_20][T.104_19];
T.112_33 = T.111_30 >> T.107_24;
T.113_34 = (int)T.112_33;
T.114_35 = T.113_34 & 1;
if (T.114_35 != 0) goto <Ub4fc>; else goto <Uef68>;
# SUCC: 3 (false,exec) 4 (true,exec)
# BLOCK 3
# PRED: 2 (false,exec)
<Uef68>:;
# VUSE <reload_reg_used_in_input_37>;
T.115_38 = reload_reg_used_in_input[i_20][T.104_19];
T.116_41 = T.115_38 >> T.107_24;
T.117_42 = (int)T.116_41;
T.118_43 = T.117_42 & 1;
if (T.118_43 != 0) goto <Ub4fc>; else goto <Uea6c>;
# SUCC: 10 (false,exec) 4 (true,exec)
# BLOCK 4
# PRED: 3 (true,exec) 2 (true,exec) 1 (true,exec)
<Ub4fc>:;
return 0;
# SUCC: EXIT
# BLOCK 5
# PRED: 10 (true,exec)
<Ue074>:;
T.104_48 = regno_18 / 32;
# VUSE <reload_reg_used_in_output_addr_49>;
T.120_50 = reload_reg_used_in_output_addr[i_5][T.104_48];
T.106_51 = regno_18 % 32;
T.107_52 = (int)T.106_51;
T.121_53 = T.120_50 >> T.107_52;
T.122_54 = (int)T.121_53;
T.123_55 = T.122_54 & 1;
if (T.123_55 != 0) goto <Ue244>; else goto <Uf000>;
# SUCC: 6 (false,exec) 8 (true,exec)
# BLOCK 6
# PRED: 5 (false,exec)
<Uf000>:;
# VUSE <reload_reg_used_in_outaddr_addr_57>;
T.124_58 = reload_reg_used_in_outaddr_addr[i_5][T.104_48];
T.125_61 = T.124_58 >> T.107_52;
T.126_62 = (int)T.125_61;
T.127_63 = T.126_62 & 1;
if (T.127_63 != 0) goto <Ue244>; else goto <Uf0e8>;
# SUCC: 7 (false,exec) 8 (true,exec)
# BLOCK 7
# PRED: 6 (false,exec)
<Uf0e8>:;
# VUSE <reload_reg_used_in_output_65>;
T.128_66 = reload_reg_used_in_output[i_5][T.104_48];
T.129_69 = T.128_66 >> T.107_52;
T.130_70 = (int)T.129_69;
T.131_71 = T.130_70 & 1;
if (T.131_71 != 0) goto <Ue244>; else goto <Ue2b8>;
# SUCC: 9 (false,exec) 8 (true,exec)
# BLOCK 8
# PRED: 7 (true,exec) 6 (true,exec) 5 (true,exec)
<Ue244>:;
return 0;
# SUCC: EXIT
# BLOCK 9
# PRED: 7 (false,exec)
<Ue2b8>:;
i_72 = i_5 + 1;
# SUCC: 10 (fallthru,exec)
# BLOCK 10
# PRED: 3 (false,exec) 0 (exec) 9 (fallthru,exec)
# i_5 = PHI <0(3), i_72(9), 0(0)>;
<Uea6c>:;
# VUSE <reload_n_operands_46>;
reload_n_operands.119_47 = reload_n_operands;
if (i_5 < reload_n_operands.119_47) goto <Ue074>; else goto <Uf15c>;
# SUCC: 11 (false,exec) 5 (true,exec)
# BLOCK 11
# PRED: 10 (false,exec)
<Uf15c>:;
<Ubf68>:;
T.104_74 = regno_18 / 32;
# VUSE <reload_reg_used_75>;
T.132_76 = reload_reg_used[T.104_74];
T.106_77 = regno_18 % 32;
T.107_78 = (int)T.106_77;
T.133_79 = T.132_76 >> T.107_78;
T.134_80 = (int)T.133_79;
T.135_81 = T.134_80 & 1;
return T.135_81 == 0;
# SUCC: EXIT
# BLOCK 12
# PRED: 0 (exec)
<Ued98>:;
# SUCC: EXIT (fallthru)
}
Here's what we've got immediately after PRE:
# BLOCK 0
# PRED: ENTRY (fallthru,exec)
switch ((unsigned int)type_14)
{
case 0: goto <Ub414>
case 7: goto <U6488>
default : goto <Ued98>
}
# SUCC: 12 (exec) 13 (exec) 1 (exec)
# BLOCK 1
# PRED: 0 (exec)
<Ub414>:;
pretmp.137_93 = regno_18 / 32;
T.104_19 = pretmp.137_93;
# VUSE <reload_reg_used_in_input_addr_21>;
T.105_22 = reload_reg_used_in_input_addr[i_20][T.104_19];
pretmp.138_96 = regno_18 % 32;
T.106_23 = pretmp.138_96;
T.107_24 = (int)T.106_23;
T.108_25 = T.105_22 >> T.107_24;
T.109_26 = (int)T.108_25;
T.110_27 = T.109_26 & 1;
if (T.110_27 != 0) goto <U64fc>; else goto <Ueef4>;
# SUCC: 2 (false,exec) 14 (true,exec)
# BLOCK 2
# PRED: 1 (false,exec)
<Ueef4>:;
# VUSE <reload_reg_used_in_inpaddr_addr_29>;
T.111_30 = reload_reg_used_in_inpaddr_addr[i_20][T.104_19];
T.112_33 = T.111_30 >> T.107_24;
T.113_34 = (int)T.112_33;
T.114_35 = T.113_34 & 1;
if (T.114_35 != 0) goto <U65e4>; else goto <Uef68>;
# SUCC: 3 (false,exec) 15 (true,exec)
# BLOCK 3
# PRED: 2 (false,exec)
<Uef68>:;
# VUSE <reload_reg_used_in_input_37>;
T.115_38 = reload_reg_used_in_input[i_20][T.104_19];
T.116_41 = T.115_38 >> T.107_24;
T.117_42 = (int)T.116_41;
T.118_43 = T.117_42 & 1;
if (T.118_43 != 0) goto <U66cc>; else goto <U6658>;
# SUCC: 16 (false,exec) 17 (true,exec)
# BLOCK 14
# PRED: 1 (true,exec)
<U64fc>:;
critedgetmp.136_84 = 0;
goto <Ub4fc>;
# SUCC: 4
# BLOCK 15
# PRED: 2 (true,exec)
<U65e4>:;
critedgetmp.136_85 = 0;
goto <Ub4fc>;
# SUCC: 4
# BLOCK 17
# PRED: 3 (true,exec)
<U66cc>:;
critedgetmp.136_87 = 0;
goto <Ub4fc>;
# SUCC: 4
# BLOCK 4
# PRED: 17 15 14
<Ub4fc>:;
return 0;
# SUCC: EXIT
# BLOCK 5
# PRED: 10 (true,exec)
<Ue074>:;
T.104_48 = pretmp.137_91;
# VUSE <reload_reg_used_in_output_addr_49>;
T.120_50 = reload_reg_used_in_output_addr[i_5][T.104_48];
T.106_51 = pretmp.138_94;
T.107_52 = (int)T.106_51;
T.121_53 = T.120_50 >> T.107_52;
T.122_54 = (int)T.121_53;
T.123_55 = T.122_54 & 1;
if (T.123_55 != 0) goto <U689c>; else goto <Uf000>;
# SUCC: 6 (false,exec) 18 (true,exec)
# BLOCK 6
# PRED: 5 (false,exec)
<Uf000>:;
# VUSE <reload_reg_used_in_outaddr_addr_57>;
T.124_58 = reload_reg_used_in_outaddr_addr[i_5][T.104_48];
T.125_61 = T.124_58 >> T.107_52;
T.126_62 = (int)T.125_61;
T.127_63 = T.126_62 & 1;
if (T.127_63 != 0) goto <U6910>; else goto <Uf0e8>;
# SUCC: 7 (false,exec) 19 (true,exec)
# BLOCK 7
# PRED: 6 (false,exec)
<Uf0e8>:;
# VUSE <reload_reg_used_in_output_65>;
T.128_66 = reload_reg_used_in_output[i_5][T.104_48];
T.129_69 = T.128_66 >> T.107_52;
T.130_70 = (int)T.129_69;
T.131_71 = T.130_70 & 1;
if (T.131_71 != 0) goto <U6ae0>; else goto <Ue2b8>;
# SUCC: 9 (false,exec) 20 (true,exec)
# BLOCK 18
# PRED: 5 (true,exec)
<U689c>:;
critedgetmp.136_88 = 0;
goto <Ue244>;
# SUCC: 8
# BLOCK 19
# PRED: 6 (true,exec)
<U6910>:;
critedgetmp.136_89 = 0;
goto <Ue244>;
# SUCC: 8
# BLOCK 20
# PRED: 7 (true,exec)
<U6ae0>:;
critedgetmp.136_90 = 0;
goto <Ue244>;
# SUCC: 8
# BLOCK 8
# PRED: 20 19 18
<Ue244>:;
return 0;
# SUCC: EXIT
# BLOCK 9
# PRED: 7 (false,exec)
<Ue2b8>:;
i_72 = i_5 + 1;
# SUCC: 10 (fallthru,exec)
# BLOCK 10
# PRED: 16 13 9 (fallthru,exec)
# i_5 = PHI <0(16), i_72(9), 0(13)>;
# pretmp.137_91 = PHI <T.104_74(9), pretmp.137_92(13), T.104_19(16)>;
# pretmp.138_94 = PHI <T.106_77(9), pretmp.138_95(13), T.106_23(16)>;
<Uea6c>:;
# VUSE <reload_n_operands_46>;
reload_n_operands.119_47 = reload_n_operands;
if (i_5 < reload_n_operands.119_47) goto <Ue074>; else goto <Uf15c>;
# SUCC: 11 (false,exec) 5 (true,exec)
# BLOCK 11
# PRED: 10 (false,exec)
<Uf15c>:;
<Ubf68>:;
T.104_74 = pretmp.137_91;
# VUSE <reload_reg_used_75>;
T.132_76 = reload_reg_used[T.104_74];
T.106_77 = pretmp.138_94;
T.107_78 = (int)T.106_77;
T.133_79 = T.132_76 >> T.107_78;
T.134_80 = (int)T.133_79;
T.135_81 = T.134_80 & 1;
return T.135_81 == 0;
# SUCC: EXIT
# BLOCK 12
# PRED: 0 (exec)
<Ued98>:;
return;
# SUCC: EXIT
# BLOCK 13
# PRED: 0 (exec)
<U6488>:;
critedgetmp.136_83 = 0;
pretmp.137_92 = regno_18 / 32;
pretmp.138_95 = regno_18 % 32;
goto <Uea6c>;
# SUCC: 10
# BLOCK 16
# PRED: 3 (false,exec)
<U6658>:;
critedgetmp.136_86 = 0;
goto <Uea6c>;
# SUCC: 10
}
What's critical here is the PHI node in block 10 for pretmp.137_91 and the use
of T.104_74 in that PHI node:
# BLOCK 10
# PRED: 16 13 9 (fallthru,exec)
# i_5 = PHI <0(16), i_72(9), 0(13)>;
# pretmp.137_91 = PHI <T.104_74(9), pretmp.137_92(13), T.104_19(16)>;
T.104_74 is defined in block 11 and there is no path from block 11 to
the use in block 10. This is definitely not good as we have a violation
of the basic concepts of the SSA form.
Here's the testcase:
typedef unsigned long HARD_REG_ELT_TYPE;
typedef HARD_REG_ELT_TYPE HARD_REG_SET[((53 + (8 * 4) - 1) / (8 * 4))];
enum reload_type
{
RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN,
RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_INPADDR_ADDRESS,
RELOAD_FOR_OUTPUT_ADDRESS, RELOAD_FOR_OUTADDR_ADDRESS,
RELOAD_FOR_OPERAND_ADDRESS, RELOAD_FOR_OPADDR_ADDR,
RELOAD_OTHER, RELOAD_FOR_OTHER_ADDRESS
};
extern int reload_n_operands;
static HARD_REG_SET reload_reg_used;
static HARD_REG_SET reload_reg_used_in_input_addr[30];
static HARD_REG_SET reload_reg_used_in_inpaddr_addr[30];
static HARD_REG_SET reload_reg_used_in_output_addr[30];
static HARD_REG_SET reload_reg_used_in_outaddr_addr[30];
static HARD_REG_SET reload_reg_used_in_input[30];
static HARD_REG_SET reload_reg_used_in_output[30];
int
reload_reg_reaches_end_p (unsigned int regno, int opnum,
enum reload_type type)
{
int i;
switch (type)
{
case RELOAD_FOR_INPUT:
if ((!!
((reload_reg_used_in_input_addr[i])
[(regno) /
((unsigned) (32))] & (((HARD_REG_ELT_TYPE) (1)) << ((regno)
%
((unsigned
) (32)))))) || (!!((reload_reg_used_in_inpaddr_addr[i])[(regno) / ((unsigned)
(3
2))] & (((HARD_REG_ELT_TYPE) (1)) << ((regno) % ((unsigned) (32)))))) ||
(!!((re
load_reg_used_in_input[i])[(regno) / ((unsigned) (32))] &
(((HARD_REG_ELT_TYPE)
(1)) << ((regno) % ((unsigned) (32)))))))
return 0;
case RELOAD_FOR_OPERAND_ADDRESS:
for (i = 0; i < reload_n_operands; i++)
if ((!!
((reload_reg_used_in_output_addr[i])
[(regno) /
((unsigned) (32))] & (((HARD_REG_ELT_TYPE) (1)) << ((regno)
%
((unsigned
) (32)))))) || (!!((reload_reg_used_in_outaddr_addr[i])[(regno) / ((unsigned)
(3
2))] & (((HARD_REG_ELT_TYPE) (1)) << ((regno) % ((unsigned) (32)))))) ||
(!!((re
load_reg_used_in_output[i])[(regno) / ((unsigned) (32))] &
(((HARD_REG_ELT_TYPE)
(1)) << ((regno) % ((unsigned) (32)))))))
return 0;
return (!
(!!
((reload_reg_used)[(regno) / ((unsigned) (32))] &
(((HARD_REG_ELT_TYPE) (1)) <<
((regno) % ((unsigned) (32)))))));
}
}