PRE lossage

law@redhat.com law@redhat.com
Tue Oct 28 19:29:00 GMT 2003



enum tree_code
{
  ERROR_MARK,
  IDENTIFIER_NODE,
  OP_IDENTIFIER,
  TREE_LIST,
  TREE_VEC,
  BLOCK,
  VOID_TYPE,
  INTEGER_TYPE,
  REAL_TYPE,
  COMPLEX_TYPE,
  RDIV_EXPR,
  EXACT_DIV_EXPR,
};
typedef union tree_node *tree;
struct tree_common
{
  unsigned int code:8;
};
union tree_node
{
  struct tree_common common;
};
tree
foo (code, type0, code0, code1)
     enum tree_code code;
     tree type0; 
     enum tree_code code0, code1;
{
  register enum tree_code resultcode;
  int none_complex;
  code0 = ((enum tree_code) (type0)->common.code);
  switch (code)
    {
    case EXACT_DIV_EXPR:
      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
          && (code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
            resultcode = RDIV_EXPR;
    }
  if (code0 == INTEGER_TYPE || code0 == REAL_TYPE)
      bar (code0 != COMPLEX_TYPE);
}

Before PRE we have:
;; Function foo (foo)

foo (code, type0, code0, code1)
{
  tree_code T.1;
  tree_code T.2;
  unsigned char T.3;
  int T.4;
  register tree_code resultcode;
  int none_complex;
  extern  bar;

  
  # block 0 (j.c:33).  pred: -1.  succ: 1 3.
  
  #   VUSE <MT.1_3>;
  T.3_4 = type0_2->common.code;
  code0_5 = (unsigned int)T.3_4;
  switch ((unsigned int)code_6)
    {
      
      # block 1 (j.c:36).  pred: 0.  succ: 3 2.
      case 11:;
      T.1_7 = code0_5 - 7;
      if (T.1_7 <= 1)
        {
          goto <Ub9f8>;
        }
      else
        {
          goto <Ubcb0>;
        };
      
      # block 2.  pred: 1.  succ: 3.
      <Ub9f8>:;;
      T.2_9 = code1_8 - 8;
      goto <Ubcb0>;;
      (void)0;
      
      # block 3.  pred:.  succ:.
      (void)0;
      (void)0;
      (void)0;
      (void)0;
      (void)0;
      (void)0;
      (void)0;
      (void)0;
      (void)0;
    };
  
  # block 3.  pred: 2 1 0.  succ: 5 4.
  <Ubcb0>:;;
  T.1_11 = code0_5 - 7;
  if (T.1_11 <= 1)
    {
      goto <Ubb54>;
    }
  else
    {
      goto <Ubc3c>;
    };
  
  # block 4.  pred: 3.  succ: 5.
  <Ubb54>:;;
  T.4_12 = code0_5 != 9;
  
  #   MT.1_13 = VDEF <MT.1_3>;
  bar (T.4_12);
  goto <Ubc3c>;;
  (void)0;
  (void)0;
  
  # block 5.  pred: 3 4.  succ: -2.
  #   MT.1_1 = PHI <MT.1_3(3), MT.1_13(4)>;
  <Ubc3c>:;;
}


After PRE we have:

;; Function foo (foo)

foo (code, type0, code0, code1)
{
  tree_code pretmp.5;
  tree_code T.1;
  tree_code T.2;
  unsigned char T.3;
  int T.4;
  register tree_code resultcode;
  int none_complex;
  extern  bar;

  
  # block 0 (j.c:33).  pred: -1.  succ: 1 6.
  
  #   VUSE <MT.1_3>;
  T.3_4 = type0_2->common.code;
  code0_5 = (unsigned int)T.3_4;
  switch ((unsigned int)code_6)
    {
      
      # block 1.  pred: 0.  succ: 7 2.
      {
        case 11:;
        pretmp.5_16 = code0_5 - 7;
        T.1_7 = pretmp.5_16;
        if (T.1_7 <= 1)
          {
            goto <Ub9f8>;
          }
        else
          {
            goto <U570>;
          };
        
        # block 7.  pred: 1.  succ: 3.
        <U570>:;;
        goto <Ubcb0>;;
        goto <Ubcb0>;;
        
        # block 2.  pred: 1.  succ: 3.
        <Ub9f8>:;;
        T.2_9 = code1_8 - 8;
        goto <Ubcb0>;;
        (void)0;
        
        # block 6.  pred: 0.  succ: 3.
        (void)0;
        (void)0;
        (void)0;
        (void)0;
        (void)0;
        (void)0;
        (void)0;
        (void)0;
        (void)0;
        default :;
        pretmp.5_15 = code0_5 - 7;
      }
    };
  
  # block 3.  pred: 7 6 2.  succ: 5 4.
  #   pretmp.5_14 = PHI <pretmp.5_15(6), T.1_7(1), T.1_7(2)>;
  <Ubcb0>:;;
  T.1_11 = pretmp.5_14;
  if (T.1_11 <= 1)
    {
      goto <Ubb54>;
    }
  else
    {
      goto <Ubc3c>;
    };
  
  # block 4.  pred: 3.  succ: 5.
  <Ubb54>:;;
  T.4_12 = code0_5 != 9;
  
  #   MT.1_13 = VDEF <MT.1_3>;
  bar (T.4_12);
  goto <Ubc3c>;;
  (void)0;
  (void)0;
  
  # block 5.  pred: 3 4.  succ: -2.
  #   MT.1_1 = PHI <MT.1_3(3), MT.1_13(4)>;
  <Ubc3c>:;;
}

Note the bogus PHI:

 # block 3.  pred: 7 6 2.  succ: 5 4.
 #   pretmp.5_14 = PHI <pretmp.5_15(6), T.1_7(1), T.1_7(2)>;

The PHI references T.1_7 from block #1, but block #1 is not a predecessor of
block #3.  Furthermore the PHI does not have an argument for block #7.

The EPHI looks like:
#1  0x080d8d5b in code_motion (ei=0xbf1de480) at /speedy/export/virgin-tree-ssa
/gcc/tree-ssa-pre.c:2779
2779                  add_phi_arg (&newtemp, rdef, EPHI_ARG_EDGE (use, i));
(gdb) p debug_generic_stmt (use)
 EPHI (code0_5 - 7) [ class:1 downsafe stops bb:3] <
   edge 6->3 [  ]  defined by: EUSE (code0_5 - 7) [class:3 phiop:0 bb:0 ]
   edge 1->7 [  real use stops ]  defined by: EUSE (code0_5 - 7) [class:0 
phiop:0 bb:1 ]
   edge 2->3 [  real use stops ]  defined by: EUSE (code0_5 - 7) [class:0 
phiop:0 bb:1 ] >


Looks like the EPHI is bogus to me.
jeff



More information about the Gcc mailing list