OSDN Git Service

* configure.ac: Add moxie support.
[pf3gnuchains/gcc-fork.git] / gcc / tree-switch-conversion.c
index 8bcfcfd..dba0c6f 100644 (file)
@@ -296,12 +296,29 @@ check_final_bb (void)
        {
          basic_block bb = gimple_phi_arg_edge (phi, i)->src;
 
-         if ((bb == info.switch_bb
-              || (single_pred_p (bb) && single_pred (bb) == info.switch_bb))
-             && !is_gimple_min_invariant (gimple_phi_arg_def (phi, i)))
+         if (bb == info.switch_bb
+             || (single_pred_p (bb) && single_pred (bb) == info.switch_bb))
            {
-             info.reason = "   Non-invariant value from a case\n";
-             return false; /* Non-invariant argument.  */
+             tree reloc, val;
+
+             val = gimple_phi_arg_def (phi, i);
+             if (!is_gimple_ip_invariant (val))
+               {
+                 info.reason = "   Non-invariant value from a case\n";
+                 return false; /* Non-invariant argument.  */
+               }
+             reloc = initializer_constant_valid_p (val, TREE_TYPE (val));
+             if ((flag_pic && reloc != null_pointer_node)
+                 || (!flag_pic && reloc == NULL_TREE))
+               {
+                 if (reloc)
+                   info.reason
+                     = "   Value from a case would need runtime relocations\n";
+                 else
+                   info.reason
+                     = "   Value from a case is not a valid initializer\n";
+                 return false;
+               }
            }
        }
     }
@@ -423,9 +440,10 @@ build_constructors (gimple swtch)
        {
          gimple phi = gsi_stmt (gsi);
          tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
+         tree low = CASE_LOW (cs);
          pos = CASE_LOW (cs);
 
-         while (!tree_int_cst_lt (high, pos))
+         do 
            {
              constructor_elt *elt;
 
@@ -435,7 +453,7 @@ build_constructors (gimple swtch)
              elt->value = val;
 
              pos = int_const_binop (PLUS_EXPR, pos, integer_one_node, 0);
-           }
+           } while (!tree_int_cst_lt (high, pos) && tree_int_cst_lt (low, pos));
          j++;
        }
     }