prat3492

777-arm.diff

Sep 2nd, 2015
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 4.99 KB | None | 0 0
  1. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
  2. index fa4e083..8327265 100644
  3. --- a/gcc/config/arm/arm.c
  4. +++ b/gcc/config/arm/arm.c
  5. @@ -73,6 +73,9 @@
  6.  #include "builtins.h"
  7.  #include "tm-constrs.h"
  8.  #include "rtl-iter.h"
  9. +#include "tree-pass.h"
  10. +#include "context.h"
  11. +#include <set>
  12.  
  13.  /* This file should be included last.  */
  14.  #include "target-def.h"
  15. @@ -3397,6 +3400,20 @@ arm_option_override (void)
  16.  
  17.    /* Init initial mode for testing.  */
  18.    thumb_flipper = TARGET_THUMB;
  19. +
  20. +  /* Registering the pass must be done at start up.  It's
  21. +     convenient to do it here.  */
  22. +  
  23. +  rtl_opt_pass *make_pass_rtl_remove_temps (gcc::context *);
  24. +  opt_pass *new_pass = make_pass_rtl_remove_temps (g);
  25. +  struct register_pass_info insert_pass_rtl_remove_temps =
  26. +    {
  27. +      new_pass,            /* pass */
  28. +      "combine",       /* reference_pass_name */
  29. +      1,           /* ref_pass_instance_number */
  30. +      PASS_POS_INSERT_BEFORE   /* po_op */
  31. +    };
  32. +  register_pass (&insert_pass_rtl_remove_temps);
  33.  }
  34.  
  35.  static void
  36. @@ -29781,4 +29798,181 @@ arm_sched_fusion_priority (rtx_insn *insn, int max_pri,
  37.    *pri = tmp;
  38.    return;
  39.  }
  40. +
  41. +std::set<int> seen_regs;
  42. +
  43. +static rtx_insn *
  44. +get_def_insn (rtx_insn *insn, rtx reg)
  45. +{
  46. +  df_ref use;
  47. +  struct df_link *ref_chain, *ref_link;
  48. +
  49. +  use = df_find_use (insn, reg);
  50. +  gcc_assert (use != NULL);
  51. +  ref_chain = DF_REF_CHAIN (use);
  52. +  
  53. +  // ??? Punt if a use has multiple defs
  54. +  if (ref_chain->next)
  55. +    return NULL;
  56. +
  57. +  if (ref_chain->ref == NULL || DF_REF_INSN_INFO (ref_chain->ref) == NULL)
  58. +    return NULL;
  59. +
  60. +  return DF_REF_INSN (ref_chain->ref);
  61. +}
  62. +
  63. +static bool
  64. +def_candidate_p (rtx expr)
  65. +{
  66. +  if (GET_CODE (expr) != AND)
  67. +    return false;
  68. +
  69. +  if (GET_MODE (expr) != SImode)
  70. +    return false;
  71. +
  72. +  rtx op0 = XEXP (expr, 0);
  73. +  rtx op1 = XEXP (expr, 1);
  74. +
  75. +  if (!REG_P (op0) || GET_MODE (op0) != SImode)
  76. +    return false;
  77. +
  78. +  if (GET_CODE (op1) != CONST_INT)
  79. +    return false;
  80. +
  81. +  return true;
  82. +}
  83. +
  84. +static void
  85. +do_remove_temp (rtx_insn *insn)
  86. +{
  87. +  rtx exp = PATTERN (insn);
  88. +
  89. +  if (GET_CODE (exp) != SET)
  90. +    return;
  91. +  exp = XEXP (exp, 1);
  92. +  if (GET_CODE (exp) != COMPARE)
  93. +    return;
  94. +  if (GET_MODE (exp) != CCmode)
  95. +    return;
  96. +
  97. +  rtx compare_expr = exp;
  98. +  rtx op0 = XEXP (exp, 0);
  99. +  if (!REG_P (op0))
  100. +    return;
  101. +
  102. +  if (GET_MODE (op0) != SImode)
  103. +    return;
  104. +
  105. +  rtx op1 = XEXP (exp, 1);
  106. +  if (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0)
  107. +    return;
  108. +
  109. +  rtx_insn *def_insn = get_def_insn (insn, op0);
  110. +  if (def_insn == NULL)
  111. +    return;
  112. +
  113. +  rtx pat = PATTERN (def_insn);
  114. +  if (!def_candidate_p (XEXP (pat, 1)))
  115. +    return;
  116. +
  117. +  rtx result_reg = XEXP (pat, 0);
  118. +  if (!REG_P (result_reg) || GET_MODE (result_reg) != SImode)
  119. +    return;
  120. +
  121. +  gcc_assert (REG_P (result_reg));
  122. +  std::pair< std::set<int>::iterator, bool > ret = seen_regs.insert (REGNO (result_reg));
  123. +  if (ret.second == true)
  124. +    return;
  125. +
  126. +  rtx reg = gen_reg_rtx (SImode);
  127. +  rtx_insn *x = emit_insn_before (copy_rtx (pat), insn);
  128. +  recog_memoized (x);
  129. +}
  130. +
  131. +static void
  132. +rtl_remove_temps_init()
  133. +{
  134. +  df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
  135. +  df_chain_add_problem (DF_UD_CHAIN);
  136. +  df_analyze ();
  137. +  df_set_flags (DF_DEFER_INSN_RESCAN);
  138. +}
  139. +
  140. +static unsigned int
  141. +execute_rtl_remove_temps (void)
  142. +{
  143. +
  144. +  rtx_insn *insn, *last, *first;
  145. +
  146. +  for (insn = first = get_insns (), last = get_last_insn (); insn != last; insn = NEXT_INSN (insn))
  147. +    {
  148. +      if (!INSN_P (insn))
  149. +   continue;
  150. +
  151. +      rtx pat = PATTERN (insn);
  152. +      /* ??? set and use of register cannot happen in PARALLEL */
  153. +      if (GET_CODE (pat) == PARALLEL)
  154. +   continue;
  155. +      else if (GET_CODE (pat) == SEQUENCE)
  156. +   {
  157. +     push_topmost_sequence ();
  158. +     execute_rtl_remove_temps ();
  159. +     pop_topmost_sequence ();
  160. +   }
  161. +      else
  162. +   do_remove_temp (insn);
  163. +    }
  164. +
  165. +  return 0;
  166. +}
  167. +
  168. +namespace {
  169. +
  170. +const pass_data pass_data_rtl_remove_temps =
  171. +{
  172. +  RTL_PASS, /* type */
  173. +  "remove-temps", /* name */
  174. +  OPTGROUP_NONE, /* optinfo_flags */
  175. +  TV_NONE,
  176. +  PROP_cfglayout, /* properties_required */
  177. +  0, /* properties_provided */
  178. +  0, /* properties_destroyed */
  179. +  0, /* todo_flags_start */
  180. +  TODO_df_finish, /* todo_flags_finish */
  181. +};
  182. +
  183. +class pass_rtl_remove_temps : public rtl_opt_pass
  184. +{
  185. +public:
  186. +  pass_rtl_remove_temps (gcc::context *ctxt)
  187. +    : rtl_opt_pass (pass_data_rtl_remove_temps, ctxt)
  188. +  {}
  189. +
  190. +  /* opt_pass methods: */
  191. +  virtual bool gate (function *);
  192. +  virtual unsigned int execute (function *);
  193. +
  194. +}; // class pass_rtl_remove_temps
  195. +
  196. +bool
  197. +pass_rtl_remove_temps::gate (function *)
  198. +{
  199. +  return flag_rtl_remove_temps != 0 && optimize > 0;
  200. +}
  201. +
  202. +} // anon namespace
  203. +
  204. +unsigned int
  205. +pass_rtl_remove_temps::execute (function *)
  206. +{
  207. +  rtl_remove_temps_init ();
  208. +  return execute_rtl_remove_temps ();
  209. +}
  210. +
  211. +rtl_opt_pass *
  212. +make_pass_rtl_remove_temps (gcc::context *ctxt)
  213. +{
  214. +  return new pass_rtl_remove_temps (ctxt);
  215. +}
  216. +
  217.  #include "gt-arm.h"
Advertisement
Add Comment
Please, Sign In to add comment