From c56ab728446a7138574310d7e2512197aa0abef1 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 11 Apr 2017 16:12:08 -0400
Subject: [PATCH 01/10] FIXME: initial WIP

---
 gcc/Makefile.in                          |  1 +
 gcc/heap-optimizations.c                 | 68 ++++++++++++++++++++++++++++++++
 gcc/passes.def                           |  1 +
 gcc/testsuite/gcc.dg/heap-optimization.c | 53 +++++++++++++++++++++++++
 gcc/timevar.def                          |  1 +
 gcc/tree-pass.h                          |  1 +
 6 files changed, 125 insertions(+)
 create mode 100644 gcc/heap-optimizations.c
 create mode 100644 gcc/testsuite/gcc.dg/heap-optimization.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 50d84bf..0a0de4e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1328,6 +1328,7 @@ OBJS = \
 	haifa-sched.o \
 	hash-map-tests.o \
 	hash-set-tests.o \
+	heap-optimizations.o \
 	hsa-common.o \
 	hsa-gen.o \
 	hsa-regalloc.o \
diff --git a/gcc/heap-optimizations.c b/gcc/heap-optimizations.c
new file mode 100644
index 0000000..a33bb36
--- /dev/null
+++ b/gcc/heap-optimizations.c
@@ -0,0 +1,68 @@
+/* Heap optimizations.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostic-core.h"
+#include "function.h"
+#include "tree-pass.h"
+
+namespace {
+
+const pass_data pass_data_heap_optimizations =
+{
+  GIMPLE_PASS, /* type */
+  "heap", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_HEAP_OPTIMIZATIONS, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_heap_optimizations : public gimple_opt_pass
+{
+public:
+  pass_heap_optimizations (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_heap_optimizations, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual unsigned int execute (function *);
+
+}; // class pass_heap_optimizations
+
+unsigned int
+pass_heap_optimizations::execute (function *fun)
+{
+  warning_at (fun->function_start_locus, 0,
+	      "pass_heap_optimizations::execute");
+  return 0; // FIXME
+}
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_heap_optimizations (gcc::context *ctxt)
+{
+  return new pass_heap_optimizations (ctxt);
+}
diff --git a/gcc/passes.def b/gcc/passes.def
index 6b0f05b..f666689 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_rebuild_cgraph_edges);
       NEXT_PASS (pass_inline_parameters);
       NEXT_PASS (pass_early_inline);
+      NEXT_PASS (pass_heap_optimizations); /* FIXME: arbitrary place for this.  */
       NEXT_PASS (pass_all_early_optimizations);
       PUSH_INSERT_PASSES_WITHIN (pass_all_early_optimizations)
 	  NEXT_PASS (pass_remove_cgraph_callee_edges);
diff --git a/gcc/testsuite/gcc.dg/heap-optimization.c b/gcc/testsuite/gcc.dg/heap-optimization.c
new file mode 100644
index 0000000..7be1f59
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/heap-optimization.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dog-options "-fheap-optimizations" }  */
+
+#include <stdlib.h>
+
+typedef unsigned int edit_distance_t;
+
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+
+edit_distance_t
+levenshtein_distance (const char *s, int len_s,
+		      const char *t, int len_t)
+{
+  edit_distance_t *v0, *v1;
+  edit_distance_t result;
+  int i;
+  int j;
+
+  if (len_s == 0)
+    return len_t;
+  if (len_t == 0)
+    return len_s;
+
+  v0 = malloc(sizeof (edit_distance_t) * (len_s + 1));
+  v1 = malloc(sizeof (edit_distance_t) * (len_s + 1));
+
+  for (i = 0; i < len_s + 1; i++)
+    v0[i] = i;
+
+  for (i = 0; i < len_t; i++)
+    {
+      v1[0] = i + 1;
+
+      for (j = 0; j < len_s; j++)
+	{
+	  edit_distance_t cost = (s[j] == t[i] ? 0 : 1);
+	  edit_distance_t deletion     = v1[j] + 1;
+	  edit_distance_t insertion    = v0[j + 1] + 1;
+	  edit_distance_t substitution = v0[j] + cost;
+	  edit_distance_t cheapest = MIN (deletion, insertion);
+	  cheapest = MIN (cheapest, substitution);
+	  v1[j + 1] = cheapest;
+	}
+
+      for (j = 0; j < len_s + 1; j++)
+	v0[j] = v1[j];
+    }
+
+  result = v1[len_s];
+  free(v0);
+  free(v1);
+  return result;
+}
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 51ec035..72d7e9c 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -141,6 +141,7 @@ DEFTIMEVAR (TV_CONSTRAINT_SAT        , "constraint satisfaction")
 DEFTIMEVAR (TV_CONSTRAINT_SUB        , "constraint subsumption")
 DEFTIMEVAR (TV_FLATTEN_INLINING      , "flatten inlining")
 DEFTIMEVAR (TV_EARLY_INLINING        , "early inlining heuristics")
+DEFTIMEVAR (TV_HEAP_OPTIMIZATIONS    , "heap optimizations")
 DEFTIMEVAR (TV_INLINE_PARAMETERS     , "inline parameters")
 DEFTIMEVAR (TV_INTEGRATION           , "integration")
 DEFTIMEVAR (TV_TREE_GIMPLIFY	     , "tree gimplify")
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 85bfba7..e4e8d53 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -618,6 +618,7 @@ extern rtl_opt_pass *make_pass_final (gcc::context *ctxt);
 extern rtl_opt_pass *make_pass_rtl_seqabstr (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_release_ssa_names (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_early_inline (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_heap_optimizations (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_inline_parameters (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_update_address_taken (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_convert_switch (gcc::context *ctxt);
-- 
1.8.5.3

