public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/pheeck/heads/sccp)] added alt ssa construction alg files
@ 2023-04-18 20:18 Filip Kastl
  0 siblings, 0 replies; only message in thread
From: Filip Kastl @ 2023-04-18 20:18 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d940ad33631551e801db5c9d30f05ad6d90b70fe

commit d940ad33631551e801db5c9d30f05ad6d90b70fe
Author: Filip Kastl <filip.kastl@gmail.com>
Date:   Tue Apr 18 22:18:25 2023 +0200

    added alt ssa construction alg files

Diff:
---
 gcc/insert-gimple-ssa.cc | 464 +++++++++++++++++++++++++++++++++++++++++++++++
 gcc/insert-gimple-ssa.h  | 197 ++++++++++++++++++++
 2 files changed, 661 insertions(+)

diff --git a/gcc/insert-gimple-ssa.cc b/gcc/insert-gimple-ssa.cc
new file mode 100644
index 00000000000..e4f0e3ab15e
--- /dev/null
+++ b/gcc/insert-gimple-ssa.cc
@@ -0,0 +1,464 @@
+/* TODO Popis
+   Copyright (C) 2023-2023 Free Software Foundation, Inc.
+   Contributed by Filip Kastl <filip.kastl@gmail.com>
+
+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/>.  */
+
+// Z tree-into-ssa.cc TODO Ubrat
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "rtl.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "ssa.h"
+#include "gimple-pretty-print.h"
+#include "diagnostic-core.h"
+#include "langhooks.h"
+#include "cfganal.h"
+#include "gimple-iterator.h"
+#include "tree-cfg.h"
+#include "tree-into-ssa.h"
+#include "tree-dfa.h"
+#include "tree-ssa.h"
+#include "domwalk.h"
+#include "statistics.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "asan.h"
+#include "attr-fnspec.h"
+
+#include "vec.h"
+#include "hash-map.h"
+#include "hash-set.h"
+#include "basic-block.h"
+#include "gimple-iterator.h"
+#include "tree-ssanames.h"
+#include "tree-phinodes.h"
+#include "insert-gimple-ssa.h"
+
+gimple *
+hstmt_assign::to_gimple (void)
+{
+  gcc_checking_assert (ssa != NULL_TREE);
+
+  tree op1 = op[1];
+  tree op2 = NULL_TREE;
+  tree op3 = NULL_TREE;
+
+  if (num_ops >= 2)
+    op2 = op[2];
+  if (num_ops >= 3)
+    op3 = op[3];
+
+  return gimple_build_assign (lhs, code, op1, op2, op3);
+}
+
+hack_tuple &
+hack_ssa_builder::tuple_alloc (enum tree_code code, unsigned num_ops)
+{
+  gcc_checking_assert (num_ops >= 1 && "Tuples of size <1 not allowed");
+  gcc_checking_assert (num_ops <= 3 && "Tuples of size >3 not allowed");
+
+  size_t size = sizeof (hack_tuple) +
+    (num_ops - 1) * sizeof (class hack_lvalue *);
+  hack_tuple *result = XNEWVAR (struct hack_tuple, size);
+
+  allocated_tuples.safe_push (result);
+
+  return *result;
+}
+
+void
+hack_ssa_builder::tuple_set_operand (unsigned op_num, hack_tuple &tuple,
+				     hack_lvalue &val)
+{
+  tuple.op[op_num] = &val;
+}
+
+/* 'var_tree' can be a tree representing a variable (for example a var decl) or
+   a tree representing a type. The latter results in an anonymous variable.  */
+
+hack_lvalue &
+hack_ssa_builder::new_local (tree var_tree)
+{
+  hack_lvalue *local = XNEW (class hack_lvalue);
+  local->index = next_index;
+  next_index++;
+  local->var_tree = var_tree;
+
+  allocated_locals.safe_push (local);
+
+  return *local;
+}
+
+void
+hack_ssa_builder::append_assign (basic_block bb, hack_lvalue &left,
+				 hack_tuple &right)
+{
+  hstmt *stmt;
+
+  hack_tuple_internal *val = tuple_to_internal (right);
+  stmt = tuple_lookup (bb, val);
+  if (stmt == NULL)
+    {
+      /* Assign with equivalent tuple not found. Create a new one.  */
+      hstmt_assign *stmt = XNEW (struct hstmt_assign);
+      stmt->var = &left;
+      stmt->val = val;
+
+      append_stmt (bb, stmt);
+      tuple_register (bb, stmt);
+
+      /* Update users list of appropriate stmts.  */
+      unsigned i;
+      for (i = 0; i < val->num_ops; i++)
+	{
+	  // TODO Neměl bych kontrolovat, jestli není killed?
+	  val->op[i]->uses.safe_push (stmt);
+	}
+    }
+  write_variable (bb, left, stmt);
+}
+
+edge
+hack_ssa_builder::hack_make_edge (basic_block src, basic_block dest, int flags)
+{
+  gcc_checking_assert (filled_bbs.contains (bb->index) &&
+		       "Successors can only be added to a filled BB");
+  return make_edge (src, dest, flags);
+}
+
+void
+hack_ssa_builder::seal_block (basic_block bb)
+{
+  sealed_bbs.put (bb->index);
+}
+
+void
+hack_ssa_builder::set_block_filled (basic_block bb)
+{
+  filled_bbs.put (bb->index);
+}
+
+void
+hack_ssa_builder::finalize (void)
+{
+  run_final_optimizations ();
+
+  /* Fill and seal remaining bbs.  */
+  for (basic_block bb : seen_bbs)
+    { // TODO Nechci jen checking assert?
+      if (!filled_bbs.contains (bb->index))
+	set_block_filled (bb);
+    }
+  for (basic_block bb : seen_bbs)
+    {
+      if (!sealed_bbs.contains (bb->index))
+	seal_block (bb);
+    }
+
+  /* Commit everything.  */
+  for (basic_block bb : seen_bbs)
+    {
+      hack_bb record = get_bb_record (bb);
+      for (hstmt *s : record.stmt_list)
+	{
+	  if (!s->killed)
+	    {
+	      hstmt_left *ls = dyn_cast<hstmt_left> (s);
+	      if (!ls == NULL)
+		commit_ssa_name (bb, s);
+	    }
+	}
+      for (hphi *p : record.phi_list)
+	{
+	  if (!p->killed)
+	    {
+	      commit_ssa_name (bb, p);
+	    }
+	}
+    }
+  for (basic_block bb : seen_bbs)
+    {
+      gimple_stmt_iterator gsi = gsi_start_bb (bb);
+      hack_bb record = get_bb_record (bb);
+      for (hstmt *s : record.stmt_list)
+	{
+	  if (!s->killed)
+	    {
+	      commit_stmt (&gsi, s);
+	    }
+	}
+      for (hphi *p : record.phi_list)
+	{
+	  if (!p->killed)
+	    {
+	      commit_phi (bb, p);
+	    }
+	}
+    }
+
+  /* Free memory.  */
+  for (basic_block bb : seen_bbs)
+    {
+      hack_bb record = get_bb_record (bb);
+      for (hstmt *s : record.stmt_list)
+	{
+	  hstmt_left *ls = dyn_cast<hstmt_left *> (s);
+	  if (ls != NULL)
+	    ls->uses.release ();
+	  XDELETE (s);
+	}
+      for (hphi *p : record.phi_list)
+	{
+	  XDELETEVEC (*(p->op_p)); /* Free op array. Separate from PHI.  */
+	  XDELETE (p);
+	}
+      record.stmt_list.release ();
+      record.phi_list.release ();
+      record.curr_def.release ();
+      record.tuple_provider.release ();
+      record.curr_ssa.release ();
+      XDELETE (record);
+    }
+  for (hack_lvalue l : allocated_locals)
+    XDELETE (l);
+  for (hack_tuple t : allocated_tuples)
+    XDELETE (t);
+  for (hack_tuple_internal t : allocated_internal)
+    XDELETE (t);
+  seen_bbs.release ();
+  allocated_locals.release ();
+  allocated_tuples.release ();
+  allocated_internal.release ();
+  bb_record_map.release ();
+  sealed_bbs.release ();
+  filled_bbs.release ();
+  incomplete_phis.release ();
+}
+
+tree
+hack_ssa_builder::ssa_name_from_lvalue (basic_block bb, hack_lvalue &var)
+{
+  gcc_checking_assert (finalized && "SSA builder has to be finalized");
+  hack_bb bb_record = get_bb_record (bb);
+  return *(bb_record.curr_ssa.get (&var));
+}
+
+hack_bb &
+hack_ssa_builder::get_bb_record (basic_block bb)
+{
+  seen_bbs.put (bb);
+
+  hack_bb *record = bb_record_map.get (bb->index);
+  if (record == NULL)
+    {
+      record = XNEW (struct hack_bb);
+      bb_record_map.put (bb->index, record);
+    }
+  return *record;
+}
+
+hack_tuple_internal *
+hack_ssa_builder::tuple_to_internal (basic_block bb, hack_tuple *tuple)
+{
+  gcc_checking_assert (num_ops >= 1 && "Tuples of size <1 not allowed");
+  gcc_checking_assert (num_ops <= 3 && "Tuples of size >3 not allowed");
+
+  size_t size = sizeof (hack_tuple_internal) +
+    (tuple->num_ops - 1) * sizeof (class hstmt_left *);
+  hack_tuple_internal *result = XNEWVAR (struct hack_tuple_internal, size);
+
+  unsigned i;
+  for (i = 0; i < tuple->num_ops; i++)
+    {
+      stmt_left *s = read_variable (tuple->op[i]);
+      result->op[i] = s;
+    }
+
+  allocated_internal.safe_push (result);
+
+  return result;
+}
+
+void
+hack_ssa_builder::append_stmt (basic_block bb, hstmt *stmt)
+{
+  gcc_checking_assert (!stmt->is_phi ());
+
+  hack_bb record = get_bb_record (bb);
+  record.stmt_list.safe_push (stmt);
+}
+
+hphi *
+hack_ssa_builder::add_empty_phi (basic_block bb, hack_lvalue *var);
+{
+  hphi *p = XNEW (class hphi);
+  p->var = var;
+  p->num_ops = 0;
+  p->op_p = NULL;
+
+  hack_bb record = get_bb_record (bb);
+  record.phi_list.safe_push (p);
+
+  return p;
+}
+
+void
+hack_ssa_builder::commit_ssa_name (hstmt_left *s)
+{
+  tree ssa = make_ssa_name (s->var.var_tree);
+  s->ssa = ssa;
+}
+
+void
+hack_ssa_builder::commit_phi (basic_block bb, hphi *hp)
+{
+  hack_bb *record = get_bb_record (bb);
+  gphi *gp = create_phi_node (hp->var->var_decl, bb);
+
+  gcc_checking_assert (hp.op_p != NULL && "PHI has to be completed");
+
+  unsigned i;
+  for (i = 0; i < hp->tuple->num_ops; i++)
+    {
+      hack_edge_stmt *op = *(hp->op);
+      hstmt_left *s = op[i].s;
+      edge e = op[i].e;
+      hack_lvalue *l = s->var;
+      tree t = record->curr_ssa.get (l->index); // TODO Nechci pro tohle metodu?
+      add_phi_arg (gp, t, e, UNKNOWN_LOCATION);
+    }
+}
+
+void
+hack_ssa_builder::commit_stmt (gimple_stmt_iterator *gsi, hstmt *hs)
+{
+  gimple *s = hs->to_gimple ();
+  gsi_insert_after (gsi, s, GSI_NEW_STMT);
+  get_bb_record (gsi->bb)->curr_ssa.put (hs.var, lhs);
+}
+
+void
+hack_ssa_builder::complete_phi (basic_block bb, hack_lvalue var, hphi *phi)
+{
+  gcc_checking_assert (sealed_bbs.contains (bb->index) &&
+		       "Only sealed BBs contain complete PHIs");
+
+  edge e;
+  edge_iterator ei;
+
+  /* Alloc operand array.  */
+  unsigned num_ops = EDGE_COUNT (bb->preds);
+  hack_edge_stmt *op = XNEWVEC (hack_edge_stmt, num_ops);
+  
+  /* Set operands.  */
+  unsigned i = 0;
+  for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ei_next (&ei))
+    {
+      basic_block bb_pred = e->src;
+      hstmt_left *s = read_variable (bb_pred, var);
+      op[i].e = e;
+      op[i].s = s;
+
+      /* Update users list.  */
+      s->users.safe_push (phi);
+
+      i++;
+    }
+
+  phi->num_ops = num_ops;
+  phi->op_p = &op;
+  
+  try_remove_trivial_phi (bb, *phi);
+}
+
+void
+hack_ssa_builder::try_remove_trivial_phi (basic_block bb, hphi *phi)
+{
+  // TODO Potřebuju users
+}
+
+void
+hack_ssa_builder::write_variable (basic_block bb, hack_lvalue var,
+				  hstmt_left *stmt)
+{
+  hack_bb record = get_bb_record (bb);
+  record.curr_def.put (var, stmt);
+}
+
+hstmt_left *
+hack_ssa_builder::read_variable (basic_block bb, hack_lvalue var)
+{
+  hack_bb record = get_bb_record (bb);
+  hstmt_left **stmt_p = record.curr_def.get (var);
+  if (stmt_p == NULL)
+    return read_variable_recursive (bb, var);
+  return *stmt_p;
+}
+
+hstmt_left *
+hack_ssa_builder::read_variable_recursive (basic_block bb, hack_lvalue var)
+{
+  hstmt_left *stmt;
+
+  if (!sealed_bbs.contains (bb->index))
+    {
+      hphi *phi = add_empty_phi (bb, var);
+      stmt = phi;
+      incomplete_phis.add (phi);
+    }
+  else if (single_pred_p (bb))
+    {
+      stmt = read_variable (single_pred (bb), var);
+    }
+  else if (má vůbec predecessors)
+    {
+      hphi *phi = add_empty_phi (var);
+      stmt = phi;
+      complete_phi (bb, var, phi);
+    }
+  else
+    {
+      // TODO Řeším takhle správně, že definici nenajdu? Nechci assert už tady?
+      return NULL;
+    }
+
+  write_variable (bb, var, stmt);
+  return stmt;
+}
+
+void
+hack_ssa_builder::tuple_register (basic_block bb, hstmt_left *stmt)
+{
+  hack_bb record = get_bb_record (bb);
+  record.tuple_provider.put (stmt->val, stmt);
+}
+
+hstmt_left *
+hack_ssa_builder::tuple_lookup (basic_block bb, hack_tuple_internal val)
+{
+  hack_bb record = get_bb_record (bb);
+  hstmt_left **stmt_p = record.tuple_provider.get (val);
+  if (stmt_p == NULL)
+    return NULL;
+  else
+    return *stmt_p;
+}
diff --git a/gcc/insert-gimple-ssa.h b/gcc/insert-gimple-ssa.h
new file mode 100644
index 00000000000..7025e908356
--- /dev/null
+++ b/gcc/insert-gimple-ssa.h
@@ -0,0 +1,197 @@
+/* TODO Popis
+   Copyright (C) 2023-2023 Free Software Foundation, Inc.
+   Contributed by Filip Kastl <filip.kastl@gmail.com>
+
+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/>.  */
+
+#ifndef GCC_INSERT_GIMPLE_SSA_H
+#define GCC_INSERT_GIMPLE_SSA_H
+
+// -- FORWARD DECLARATION --
+
+struct hack_edge_stmt;
+class hstmt;
+class hstmt_left;
+class hphi;
+class hstmt_nonphi;
+class hstmt_assign;
+class hack_tuple_internal;
+struct hack_bb;
+class hack_rvalue;
+class hack_tuple;
+class hack_ssa;
+class hack_lvalue;
+class hack_ssa_builder;
+
+// -- INTERNAL STRUCTS --
+
+struct hack_edge_stmt // TODO Nechci spíš pair?
+{
+  edge e;
+  hstmt *s;
+};
+
+class hstmt
+{
+  public:
+    bool killed = false; /* Stmt shouldn't be commited. Set by optimizations.  */
+
+    virtual bool is_phi (void);
+    virtual gimple *to_gimple (void);
+};
+
+class hstmt_left : public hstmt
+{
+  public:
+    hack_lvalue *var;
+    vec<hstmt *> uses; // TODO Nahradit obstack strukturou?
+};
+
+class hphi : public hstmt_left
+{
+  public:
+    hack_lvalue *var;
+    unsigned num_ops;
+    hack_edge_stmt **op_p; /* Pointer to the array of operands. NULL if PHI
+			      incomplete.  */
+
+    virtual bool is_phi (void) override
+      {
+	return true;
+      }
+
+    virtual gimple *to_gimple (void) override
+      {
+	return NULL;
+      }
+};
+
+class hstmt_nonphi : public hstmt_left
+{
+  public:
+    virtual bool is_phi (void) override
+      {
+	return false;
+      }
+};
+
+class hstmt_assign : public hstmt_nonphi
+{
+  public:
+    hack_tuple_internal *val;
+
+    virtual gimple *to_gimple (void) override;
+};
+
+class hack_tuple_internal
+{
+  public:
+    enum tree_code code;
+    unsigned num_ops;
+    hstmt_left *op[1];
+};
+
+struct hack_bb
+{
+  vec<hstmt_nonphi *> stmt_list;
+  vec<hphi *> phi_list;
+  hash_map<hack_lvalue *, hstmt_left *> curr_def;
+  hash_map<hack_tuple_internal *, hstmt_left *> tuple_provider; // TODO Jmeno
+  hash_map<hack_lvalue *, tree> curr_ssa;
+};
+
+// -- API STRUCTS --
+
+class hack_rvalue { };
+
+class hack_tuple : public hack_rvalue
+{
+  public:
+    enum tree_code code;
+    unsigned num_ops;
+    hack_rvalue *op[1];
+};
+
+class hack_ssa : public hack_rvalue
+{
+  public:
+    tree ssa_name;
+};
+
+class hack_lvalue : public hack_rvalue
+{
+  public:
+    int index;
+    tree var_tree;
+};
+
+// -- SSA BUILDER --
+
+class hack_ssa_builder
+{
+ public:
+  hack_tuple &tuple_alloc (enum tree_code code, unsigned num_ops);
+  void tuple_set_operand (unsigned op_num, hack_tuple &tuple, // SPÍŠ POINTER
+			  hack_lvalue &val);
+  hack_lvalue &new_local (tree var_tree);
+  void append_assign (basic_block bb, hack_lvalue &left, hack_tuple &right);
+  edge hack_make_edge (basic_block src, basic_block dest, int flags);
+
+  void seal_block (basic_block bb);
+  void set_block_filled (basic_block bb);
+
+  void finalize (void);
+  tree ssa_name_from_lvalue (basic_block bb, hack_lvalue &var);
+
+ private:
+  bool finalized = false;
+  unsigned next_index = 0;
+
+  hash_set<basic_block> seen_bbs;
+  vec<hack_lvalue *> allocated_locals; // NAHRADI OBSTACK
+  vec<hack_tuple *> allocated_tuples;
+  vec<hack_tuple_internal *> allocated_internal;
+
+  hash_map<int, hack_bb> bb_record_map;
+  hash_set<int> sealed_bbs;
+  hash_set<int> filled_bbs;
+  hash_set<hphi *> incomplete_phis;
+
+  hack_bb &get_bb_record (basic_block bb);
+  hack_tuple_internal *tuple_to_internal (basic_block bb, hack_tuple *tuple);
+
+  void append_stmt (basic_block bb, hstmt_nonphi *stmt);
+  hphi *add_empty_phi (basic_block bb, hack_lvalue *var);
+
+  void commit_ssa_name (hstmt_left *s);
+  void commit_phi (basic_block bb, hphi *hp);
+  void commit_stmt (gimple_stmt_iterator *gsi, hstmt_nonphi *hs);
+
+  void complete_phi (basic_block bb, hack_lvalue &var, hphi *phi);
+  void try_remove_trivial_phi (basic_block bb, hphi *phi);
+
+  void write_variable (basic_block bb, hack_lvalue &var, hstmt_left *stmt);
+  hstmt_left *read_variable (basic_block bb, hack_lvalue &var);
+  hstmt_left *read_variable_recursive (basic_block bb, hack_lvalue &var);
+
+  void tuple_register (basic_block bb, hstmt_left *stmt);
+  hstmt_left *tuple_lookup (basic_block bb, hack_tuple_internal val);
+
+  void run_final_optimizations (void);
+};
+
+#endif /* GCC_INSERT_GIMPLE_SSA_H */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-18 20:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-18 20:18 [gcc(refs/users/pheeck/heads/sccp)] added alt ssa construction alg files Filip Kastl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).