From: Kushal Pal <kushalpal...@gmail.com>

gcc/rust/ChangeLog:

        * checks/errors/borrowck/rust-bir-dump.cc (renumber_places):
        Use value of PlaceId as index.
        (Dump::visit_place): Likewise.
        (Dump::visit_scope): Likewise.
        (Dump::go): Refill `place_map` with for loop instead of
        using std::iota().
        * checks/errors/borrowck/rust-bir-fact-collector.h (points): Use
        value as index.
        * checks/errors/borrowck/rust-bir-place.h (struct PlaceId):
        PlaceId is now a class holding a uint32_t value. Overloaded
        comparision operators for easier comparision.

Signed-off-by: Kushal Pal <kushalpal...@gmail.com>
---
 .../checks/errors/borrowck/rust-bir-dump.cc   | 25 ++++--
 .../errors/borrowck/rust-bir-fact-collector.h | 61 +++++++------
 .../checks/errors/borrowck/rust-bir-place.h   | 88 +++++++++++--------
 3 files changed, 103 insertions(+), 71 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index a35f47b86d6..924c7d9a6e8 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -53,16 +53,20 @@ renumber_places (const Function &func, std::vector<PlaceId> 
&place_map)
 {
   // Renumbering places to avoid gaps in the place id space.
   // This is needed to match MIR's shape.
-  size_t next_out_id = 0;
+  PlaceId next_out_id = INVALID_PLACE;
 
-  for (size_t in_id = FIRST_VARIABLE_PLACE; in_id < func.place_db.size ();
-       ++in_id)
+  for (PlaceId in_id = FIRST_VARIABLE_PLACE;
+       in_id.value < func.place_db.size (); ++in_id.value)
     {
       const Place &place = func.place_db[in_id];
       if (place.kind == Place::VARIABLE || place.kind == Place::TEMPORARY)
-       place_map[in_id] = next_out_id++;
+       {
+         place_map[in_id.value] = next_out_id;
+         ++next_out_id.value;
+       }
+
       else
-       place_map[in_id] = INVALID_PLACE;
+       place_map[in_id.value] = INVALID_PLACE;
     }
 }
 
@@ -110,7 +114,10 @@ Dump::go (bool enable_simplify_cfg)
   // To avoid mutation of the BIR, we use indirection through bb_fold_map.
   std::iota (bb_fold_map.begin (), bb_fold_map.end (), 0);
 
-  std::iota (place_map.begin (), place_map.end (), 0);
+  for (size_t i = 0; i < place_map.size (); ++i)
+    {
+      place_map[i] = {i};
+    }
 
   if (enable_simplify_cfg)
     simplify_cfg (func, bb_fold_map);
@@ -119,7 +126,7 @@ Dump::go (bool enable_simplify_cfg)
 
   stream << "fn " << name << "(";
   print_comma_separated (stream, func.arguments, [this] (PlaceId place_id) {
-    stream << "_" << place_map[place_id] << ": "
+    stream << "_" << place_map[place_id.value].value << ": "
           << get_tyty_name (func.place_db[place_id].tyty);
   });
   stream << ") -> " << get_tyty_name (func.place_db[RETURN_VALUE_PLACE].tyty);
@@ -228,7 +235,7 @@ Dump::visit_place (PlaceId place_id)
     {
     case Place::TEMPORARY:
     case Place::VARIABLE:
-      stream << "_" << place_map[place_id];
+      stream << "_" << place_map[place_id.value].value;
       break;
     case Place::DEREF:
       stream << "(";
@@ -365,7 +372,7 @@ Dump::visit_scope (ScopeId id, size_t depth)
   for (auto &local : scope.locals)
     {
       indent (depth + 1) << "let _";
-      stream << place_map[local] << ": "
+      stream << place_map[local.value].value << ": "
             << get_tyty_name (func.place_db[local].tyty);
       stream << ";\t";
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
index 9999bddaf59..fa7cbb38eef 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -88,8 +88,9 @@ public:
 protected: // Constructor and destructor.
   explicit FactCollector (Function &func)
     : place_db (func.place_db), basic_blocks (func.basic_blocks),
-      first_local (func.arguments.empty () ? FIRST_VARIABLE_PLACE
-                                          : *func.arguments.rbegin () + 1),
+      first_local (func.arguments.empty ()
+                    ? FIRST_VARIABLE_PLACE
+                    : PlaceId{func.arguments.rbegin ()->value + 1}),
       location (func.location), tyctx (*Resolver::TypeCheckContext::get ()),
       next_fresh_region (place_db.peek_next_free_region ())
   {}
@@ -118,7 +119,8 @@ protected: // Main collection entry points (for different 
categories).
 
   void visit_places (const std::vector<PlaceId> &args)
   {
-    for (PlaceId place_id = 0; place_id < place_db.size (); ++place_id)
+    for (PlaceId place_id = INVALID_PLACE; place_id.value < place_db.size ();
+        ++place_id.value)
       {
        auto &place = place_db[place_id];
 
@@ -126,24 +128,28 @@ protected: // Main collection entry points (for different 
categories).
          {
          case Place::VARIABLE:
          case Place::TEMPORARY:
-           facts.path_is_var.emplace_back (place_id, place_id);
+           facts.path_is_var.emplace_back (place_id.value, place_id.value);
            for (auto &region : place.regions)
-             facts.use_of_var_derefs_origin.emplace_back (place_id, region);
+             facts.use_of_var_derefs_origin.emplace_back (place_id.value,
+                                                          region);
 
            // TODO: drop_of_var_derefs_origin
            break;
          case Place::FIELD:
            sanizite_field (place_id);
-           facts.child_path.emplace_back (place_id, place.path.parent);
+           facts.child_path.emplace_back (place_id.value,
+                                          place.path.parent.value);
            break;
          case Place::INDEX:
            push_subset_all (place.tyty, place.regions,
                             place_db[place.path.parent].regions);
-           facts.child_path.emplace_back (place_id, place.path.parent);
+           facts.child_path.emplace_back (place_id.value,
+                                          place.path.parent.value);
            break;
          case Place::DEREF:
            sanitize_deref (place_id);
-           facts.child_path.emplace_back (place_id, place.path.parent);
+           facts.child_path.emplace_back (place_id.value,
+                                          place.path.parent.value);
            break;
          case Place::CONSTANT:
          case Place::INVALID:
@@ -151,15 +157,17 @@ protected: // Main collection entry points (for different 
categories).
          }
       }
 
-    for (PlaceId arg = FIRST_VARIABLE_PLACE + 1; arg < first_local; ++arg)
+    for (PlaceId arg = PlaceId{FIRST_VARIABLE_PLACE.value + 1};
+        arg < first_local; ++arg.value)
       facts.path_assigned_at_base.emplace_back (
-       arg, get_point (0, 0, PointPosition::START));
+       arg.value, get_point (0, 0, PointPosition::START));
 
-    for (PlaceId place = first_local; place < place_db.size (); ++place)
+    for (PlaceId place = first_local; place.value < place_db.size ();
+        ++place.value)
       {
        if (place_db[place].is_var ())
          facts.path_moved_at_base.emplace_back (
-           place, get_point (0, 0, PointPosition::START));
+           place.value, get_point (0, 0, PointPosition::START));
       }
   }
 
@@ -242,9 +250,9 @@ protected: // Main collection entry points (for different 
categories).
          break;
        }
        case Statement::Kind::STORAGE_DEAD: {
-         facts.path_moved_at_base.emplace_back (stmt.get_place (),
+         facts.path_moved_at_base.emplace_back (stmt.get_place ().value,
                                                 get_current_point_mid ());
-         facts.var_defined_at.emplace_back (stmt.get_place (),
+         facts.var_defined_at.emplace_back (stmt.get_place ().value,
                                             get_current_point_mid ());
          break;
        }
@@ -293,7 +301,8 @@ protected: // Main collection entry points (for different 
categories).
 
   void visit (const BorrowExpr &expr) override
   {
-    rust_debug ("\t_%u = BorrowExpr(_%u)", lhs - 1, expr.get_place () - 1);
+    rust_debug ("\t_%u = BorrowExpr(_%u)", lhs.value - 1,
+               expr.get_place ().value - 1);
 
     auto loan = place_db.get_loans ()[expr.get_loan ()];
 
@@ -330,8 +339,8 @@ protected: // Main collection entry points (for different 
categories).
 
   void visit (const Assignment &expr) override
   {
-    rust_debug ("\t_%u = Assignment(_%u) at %u:%u", lhs - 1,
-               expr.get_rhs () - 1, current_bb, current_stmt);
+    rust_debug ("\t_%u = Assignment(_%u) at %u:%u", lhs.value - 1,
+               expr.get_rhs ().value - 1, current_bb, current_stmt);
 
     issue_read_move (expr.get_rhs ());
     push_place_subset (lhs, expr.get_rhs ());
@@ -339,7 +348,8 @@ protected: // Main collection entry points (for different 
categories).
 
   void visit (const CallExpr &expr) override
   {
-    rust_debug ("\t_%u = CallExpr(_%u)", lhs - 1, expr.get_callable () - 1);
+    rust_debug ("\t_%u = CallExpr(_%u)", lhs.value - 1,
+               expr.get_callable ().value - 1);
 
     auto &return_place = place_db[lhs];
     auto &callable_place = place_db[expr.get_callable ()];
@@ -434,14 +444,14 @@ protected: // Generic BIR operations.
       return;
 
     if (place_id != RETURN_VALUE_PLACE)
-      facts.path_accessed_at_base.emplace_back (place_id,
+      facts.path_accessed_at_base.emplace_back (place_id.value,
                                                get_current_point_mid ());
 
     if (place.is_var ())
-      facts.var_used_at.emplace_back (place_id, get_current_point_mid ());
+      facts.var_used_at.emplace_back (place_id.value, get_current_point_mid 
());
     else if (place.is_path ())
       {
-       facts.var_used_at.emplace_back (place_db.get_var (place_id),
+       facts.var_used_at.emplace_back (place_db.get_var (place_id).value,
                                        get_current_point_mid ());
       }
   }
@@ -468,11 +478,12 @@ protected: // Generic BIR operations.
     rust_assert (place.is_lvalue () || place.is_rvalue ());
 
     if (place.is_var ())
-      facts.var_defined_at.emplace_back (place_id, get_current_point_mid ());
+      facts.var_defined_at.emplace_back (place_id.value,
+                                        get_current_point_mid ());
 
     if (!is_init)
       {
-       facts.path_assigned_at_base.emplace_back (place_id,
+       facts.path_assigned_at_base.emplace_back (place_id.value,
                                                  get_current_point_mid ());
        check_write_for_conflict (place_id);
        kill_borrows_for_place (place_id);
@@ -485,8 +496,8 @@ protected: // Generic BIR operations.
       return;
 
     facts.path_moved_at_base.emplace_back (
-      place_id, initial ? get_point (0, 0, PointPosition::START)
-                       : get_current_point_mid ());
+      place_id.value, initial ? get_point (0, 0, PointPosition::START)
+                             : get_current_point_mid ());
 
     check_move_behind_reference (place_id);
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index 66da3dab380..1a7a1428df9 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -32,10 +32,20 @@ namespace Rust {
 namespace BIR {
 
 /** A unique identifier for a place in the BIR. */
-using PlaceId = uint32_t;
+struct PlaceId
+{
+  uint32_t value;
+  // some overloads for comparision
+  bool operator== (const PlaceId &rhs) const { return value == rhs.value; }
+  bool operator!= (const PlaceId &rhs) const { return !(operator== (rhs)); }
+  bool operator< (const PlaceId &rhs) const { return value < rhs.value; }
+  bool operator> (const PlaceId &rhs) const { return value > rhs.value; }
+  bool operator<= (const PlaceId &rhs) const { return !(operator> (rhs)); }
+  bool operator>= (const PlaceId &rhs) const { return !(operator< (rhs)); }
+};
 
-static constexpr PlaceId INVALID_PLACE = 0;
-static constexpr PlaceId RETURN_VALUE_PLACE = 1;
+static constexpr PlaceId INVALID_PLACE = {0};
+static constexpr PlaceId RETURN_VALUE_PLACE = {1};
 static constexpr PlaceId FIRST_VARIABLE_PLACE = RETURN_VALUE_PLACE;
 
 using Variance = TyTy::VarianceAnalysis::Variance;
@@ -188,8 +198,8 @@ public:
     scopes.emplace_back (); // Root scope.
   }
 
-  Place &operator[] (PlaceId id) { return places.at (id); }
-  const Place &operator[] (PlaceId id) const { return places.at (id); }
+  Place &operator[] (PlaceId id) { return places.at (id.value); }
+  const Place &operator[] (PlaceId id) const { return places.at (id.value); }
 
   decltype (places)::const_iterator begin () const { return places.begin (); }
   decltype (places)::const_iterator end () const { return places.end (); }
@@ -228,15 +238,15 @@ public:
     return current_scope;
   }
 
-  PlaceId add_place (Place &&place, PlaceId last_sibling = 0)
+  PlaceId add_place (Place &&place, PlaceId last_sibling = INVALID_PLACE)
   {
     places.emplace_back (std::forward<Place &&> (place));
-    PlaceId new_place = places.size () - 1;
-    Place &new_place_ref = places[new_place]; // Intentional shadowing.
-    if (last_sibling == 0)
-      places[new_place_ref.path.parent].path.first_child = new_place;
+    PlaceId new_place = {places.size () - 1};
+    Place &new_place_ref = places[new_place.value]; // Intentional shadowing.
+    if (last_sibling == INVALID_PLACE)
+      places[new_place_ref.path.parent.value].path.first_child = new_place;
     else
-      places[last_sibling].path.next_sibling = new_place;
+      places[last_sibling.value].path.next_sibling = new_place;
 
     if (new_place_ref.kind == Place::VARIABLE
        || new_place_ref.kind == Place::TEMPORARY)
@@ -256,36 +266,39 @@ public:
 
   PlaceId add_variable (NodeId id, TyTy::BaseType *tyty)
   {
-    return add_place ({Place::VARIABLE, id, {}, is_type_copy (tyty), tyty}, 0);
+    return add_place ({Place::VARIABLE, id, {}, is_type_copy (tyty), tyty},
+                     INVALID_PLACE);
   }
 
   WARN_UNUSED_RESULT PlaceId lookup_or_add_path (Place::Kind kind,
                                                 TyTy::BaseType *tyty,
                                                 PlaceId parent, size_t id = 0)
   {
-    PlaceId current = 0;
-    if (parent < places.size ())
+    PlaceId current = INVALID_PLACE;
+    if (parent.value < places.size ())
       {
-       current = places[parent].path.first_child;
-       while (current != 0)
+       current = places[parent.value].path.first_child;
+       while (current != INVALID_PLACE)
          {
-           if (places[current].kind == kind
-               && places[current].variable_or_field_index == id)
+           if (places[current.value].kind == kind
+               && places[current.value].variable_or_field_index == id)
              {
-               rust_assert (places[current].tyty->is_equal (*tyty));
+               rust_assert (places[current.value].tyty->is_equal (*tyty));
                return current;
              }
-           current = places[current].path.next_sibling;
+           current = places[current.value].path.next_sibling;
          }
       }
-    return add_place ({kind, (uint32_t) id, Place::Path{parent, 0, 0},
+    return add_place ({kind, (uint32_t) id,
+                      Place::Path{parent, INVALID_PLACE, INVALID_PLACE},
                       is_type_copy (tyty), tyty},
                      current);
   }
 
   PlaceId add_temporary (TyTy::BaseType *tyty)
   {
-    return add_place ({Place::TEMPORARY, 0, {}, is_type_copy (tyty), tyty}, 0);
+    return add_place ({Place::TEMPORARY, 0, {}, is_type_copy (tyty), tyty},
+                     INVALID_PLACE);
   }
 
   PlaceId get_constant (TyTy::BaseType *tyty)
@@ -300,12 +313,12 @@ public:
   {
     PlaceId current = FIRST_VARIABLE_PLACE;
 
-    while (current != places.size ())
+    while (current.value != places.size ())
       {
-       if (places[current].kind == Place::VARIABLE
-           && places[current].variable_or_field_index == id)
+       if (places[current.value].kind == Place::VARIABLE
+           && places[current.value].variable_or_field_index == id)
          return current;
-       current++;
+       ++current.value;
       }
     return INVALID_PLACE;
   }
@@ -315,23 +328,24 @@ public:
     LoanId id = loans.size ();
     loans.push_back (std::forward<Loan &&> (loan));
     PlaceId borrowed_place = loans.rbegin ()->place;
-    places[loans.rbegin ()->place].borrowed_by.push_back (id);
-    if (places[borrowed_place].kind == Place::DEREF)
+    places[loans.rbegin ()->place.value].borrowed_by.push_back (id);
+    if (places[borrowed_place.value].kind == Place::DEREF)
       {
-       places[places[borrowed_place].path.parent].borrowed_by.push_back (id);
+       places[places[borrowed_place.value].path.parent.value]
+         .borrowed_by.push_back (id);
       }
     return id;
   }
 
   PlaceId get_var (PlaceId id) const
   {
-    if (places[id].is_var ())
+    if (places[id.value].is_var ())
       return id;
-    rust_assert (places[id].is_path ());
+    rust_assert (places[id.value].is_path ());
     PlaceId current = id;
-    while (!places[current].is_var ())
+    while (!places[current.value].is_var ())
       {
-       current = places[current].path.parent;
+       current = places[current.value].path.parent;
       }
     return current;
   }
@@ -348,18 +362,18 @@ public:
       return lookup;
 
     add_place ({Place::VARIABLE, id, {}, is_type_copy (tyty), tyty});
-    return places.size () - 1;
+    return {places.size () - 1};
   };
 
   template <typename FN> void for_each_path_from_root (PlaceId var, FN fn) 
const
   {
     PlaceId current = var;
-    current = places[current].path.first_child;
+    current = places[current.value].path.first_child;
     while (current != INVALID_PLACE)
       {
        fn (current);
        for_each_path_from_root (current, fn);
-       current = places[current].path.next_sibling;
+       current = places[current.value].path.next_sibling;
       }
   }
 
@@ -370,7 +384,7 @@ public:
     while (current != INVALID_PLACE)
       {
        fn (current);
-       current = places[current].path.parent;
+       current = places[current.value].path.parent;
       }
   }
 
-- 
2.45.2

Reply via email to