[COMMITTED 068/144] gccrs: Strong type BasicBlockId

arthur.cohen@embecosm.com arthur.cohen@embecosm.com
Wed Mar 19 14:43:49 GMT 2025


From: Kushal Pal <kushalpal109@gmail.com>

gcc/rust/ChangeLog:

	* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit):
	Use value of BasicBlockId as index.
	* checks/errors/borrowck/rust-bir-builder-internal.h (struct BuilderContext):
	Likewise.
	* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
	Initialize with ENTRY_BASIC_BLOCK.
	* checks/errors/borrowck/rust-bir-dump.cc (simplify_cfg):
	Use value of BasicBlockId as index.
	(Dump::go): Likewise.
	(Dump::visit): Likewise.
	* checks/errors/borrowck/rust-bir-fact-collector.h (class FactCollector):
	Initialize with ENTRY_BASIC_BLOCK.
	(points): Use value of BasicBlockId as index.
	* checks/errors/borrowck/rust-bir.h (struct BasicBlockId):
	BasicBlockId is a struct now.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 .../borrowck/rust-bir-builder-expr-stmt.cc    |  6 +-
 .../borrowck/rust-bir-builder-internal.h      |  8 +--
 .../borrowck/rust-bir-builder-lazyboolexpr.h  |  3 +-
 .../checks/errors/borrowck/rust-bir-dump.cc   | 56 ++++++++++++-------
 .../errors/borrowck/rust-bir-fact-collector.h | 28 ++++++----
 gcc/rust/checks/errors/borrowck/rust-bir.h    | 18 +++++-
 6 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 1713bf6fcf8..0d034dc22e8 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -565,7 +565,7 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
   add_jump (if_block, then_start_block);
   add_jump (if_block, final_block);
 
-  auto &then_end_bb = ctx.basic_blocks[then_end_block];
+  auto &then_end_bb = ctx.basic_blocks[then_end_block.value];
   if (then_end_bb.is_goto_terminated () && then_end_bb.successors.empty ())
     add_jump (then_end_block, final_block);
 }
@@ -602,11 +602,11 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
   add_jump (if_end_bb, then_start_bb);
   add_jump (if_end_bb, else_start_bb);
 
-  auto &then_bb = ctx.basic_blocks[then_end_bb];
+  auto &then_bb = ctx.basic_blocks[then_end_bb.value];
   if (then_bb.is_goto_terminated () && then_bb.successors.empty ())
     add_jump (then_end_bb, final_start_bb);
 
-  auto &else_bb = ctx.basic_blocks[else_end_bb];
+  auto &else_bb = ctx.basic_blocks[else_end_bb.value];
   if (else_bb.is_goto_terminated () && else_bb.successors.empty ())
     add_jump (else_end_bb, final_start_bb);
 }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index e0d8bb3d2fc..144d5bbde77 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -77,7 +77,7 @@ struct BuilderContext
 
   // BIR output
   std::vector<BasicBlock> basic_blocks;
-  size_t current_bb = 0;
+  BasicBlockId current_bb = ENTRY_BASIC_BLOCK;
 
   /**
    * Allocation and lookup of places (variables, temporaries, paths, and
@@ -107,7 +107,7 @@ public:
     basic_blocks.emplace_back (); // StartBB
   }
 
-  BasicBlock &get_current_bb () { return basic_blocks[current_bb]; }
+  BasicBlock &get_current_bb () { return basic_blocks[current_bb.value]; }
 
   const LoopAndLabelCtx &lookup_label (NodeId label)
   {
@@ -358,7 +358,7 @@ protected: // CFG helpers
   BasicBlockId new_bb ()
   {
     ctx.basic_blocks.emplace_back ();
-    return ctx.basic_blocks.size () - 1;
+    return {ctx.basic_blocks.size () - 1};
   }
 
   BasicBlockId start_new_consecutive_bb ()
@@ -378,7 +378,7 @@ protected: // CFG helpers
 
   void add_jump (BasicBlockId from, BasicBlockId to)
   {
-    ctx.basic_blocks[from].successors.emplace_back (to);
+    ctx.basic_blocks[from.value].successors.emplace_back (to);
   }
 
   void add_jump_to (BasicBlockId bb) { add_jump (ctx.current_bb, bb); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index 8c1cd449aba..f4995327d87 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -37,7 +37,8 @@ class LazyBooleanExprBuilder : public AbstractExprBuilder
 public:
   explicit LazyBooleanExprBuilder (BuilderContext &ctx,
 				   PlaceId expr_return_place = INVALID_PLACE)
-    : AbstractExprBuilder (ctx, expr_return_place), short_circuit_bb (0)
+    : AbstractExprBuilder (ctx, expr_return_place),
+      short_circuit_bb (ENTRY_BASIC_BLOCK)
   {}
 
   PlaceId build (HIR::LazyBooleanExpr &expr)
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index 0c0e55567b5..3564707925f 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -82,13 +82,13 @@ simplify_cfg (Function &func, std::vector<BasicBlockId> &bb_fold_map)
     {
       stabilized = true;
       // BB0 cannot be folded as it is an entry block.
-      for (size_t i = 1; i < func.basic_blocks.size (); ++i)
+      for (BasicBlockId i = {1}; i.value < func.basic_blocks.size (); ++i.value)
 	{
-	  const BasicBlock &bb = func.basic_blocks[bb_fold_map[i]];
+	  const BasicBlock &bb = func.basic_blocks[bb_fold_map[i.value].value];
 	  if (bb.statements.empty () && bb.is_goto_terminated ())
 	    {
 	      auto dst = bb.successors.at (0);
-	      if (bb_fold_map[dst] != dst)
+	      if (bb_fold_map[dst.value] != dst)
 		{
 		  rust_error_at (
 		    UNKNOWN_LOCATION,
@@ -97,11 +97,15 @@ simplify_cfg (Function &func, std::vector<BasicBlockId> &bb_fold_map)
 		  rust_inform (UNKNOWN_LOCATION,
 			       "Continuing with an unfolded CFG.");
 		  // Reverting the fold map to the original state.
-		  std::iota (bb_fold_map.begin (), bb_fold_map.end (), 0);
+		  for (BasicBlockId i = ENTRY_BASIC_BLOCK;
+		       i.value < bb_fold_map.size (); ++i.value)
+		    {
+		      bb_fold_map[i.value] = i;
+		    }
 		  stabilized = true;
 		  break;
 		}
-	      bb_fold_map[i] = dst;
+	      bb_fold_map[i.value] = dst;
 	      stabilized = false;
 	    }
 	}
@@ -112,8 +116,11 @@ void
 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);
-
+  for (BasicBlockId i = ENTRY_BASIC_BLOCK; i.value < bb_fold_map.size ();
+       ++i.value)
+    {
+      bb_fold_map[i.value] = i;
+    }
   for (size_t i = 0; i < place_map.size (); ++i)
     {
       place_map[i] = {i};
@@ -136,21 +143,22 @@ Dump::go (bool enable_simplify_cfg)
   visit_scope (ROOT_SCOPE);
 
   // Print BBs.
-  for (statement_bb = 0; statement_bb < func.basic_blocks.size ();
-       ++statement_bb)
+  for (statement_bb = ENTRY_BASIC_BLOCK;
+       statement_bb.value < func.basic_blocks.size (); ++statement_bb.value)
     {
-      if (bb_fold_map[statement_bb] != statement_bb)
+      if (bb_fold_map[statement_bb.value] != statement_bb)
 	continue; // This BB was folded.
 
-      if (func.basic_blocks[statement_bb].statements.empty ()
-	  && func.basic_blocks[statement_bb].successors.empty ())
+      if (func.basic_blocks[statement_bb.value].statements.empty ()
+	  && func.basic_blocks[statement_bb.value].successors.empty ())
 	continue;
 
       bb_terminated = false;
 
-      BasicBlock &bb = func.basic_blocks[statement_bb];
+      BasicBlock &bb = func.basic_blocks[statement_bb.value];
       stream << "\n";
-      stream << indentation << "bb" << bb_fold_map[statement_bb] << ": {\n";
+      stream << indentation << "bb" << bb_fold_map[statement_bb.value].value
+	     << ": {\n";
       size_t i = 0;
       for (auto &stmt : bb.statements)
 	{
@@ -160,7 +168,8 @@ Dump::go (bool enable_simplify_cfg)
 	}
       if (!bb_terminated)
 	stream << indentation << indentation << "goto -> bb"
-	       << bb_fold_map[bb.successors.at (0)] << ";\t\t" << i++ << "\n";
+	       << bb_fold_map[bb.successors.at (0).value].value << ";\t\t"
+	       << i++ << "\n";
 
       stream << indentation << "}\n";
     }
@@ -183,9 +192,10 @@ Dump::visit (const Statement &stmt)
       stream << "switchInt(";
       visit_move_place (stmt.get_place ());
       stream << ") -> [";
-      print_comma_separated (stream, func.basic_blocks[statement_bb].successors,
+      print_comma_separated (stream,
+			     func.basic_blocks[statement_bb.value].successors,
 			     [this] (BasicBlockId succ) {
-			       stream << "bb" << bb_fold_map[succ];
+			       stream << "bb" << bb_fold_map[succ.value].value;
 			     });
       stream << "]";
       bb_terminated = true;
@@ -195,8 +205,11 @@ Dump::visit (const Statement &stmt)
       bb_terminated = true;
       break;
     case Statement::Kind::GOTO:
-      stream << "goto -> bb"
-	     << bb_fold_map[func.basic_blocks[statement_bb].successors.at (0)];
+      stream
+	<< "goto -> bb"
+	<< bb_fold_map
+	     [func.basic_blocks[statement_bb.value].successors.at (0).value]
+	       .value;
       bb_terminated = true;
       break;
     case Statement::Kind::STORAGE_DEAD:
@@ -316,9 +329,10 @@ Dump::visit (const CallExpr &expr)
 			   visit_move_place (place_id);
 			 });
   stream << ") -> [";
-  print_comma_separated (stream, func.basic_blocks[statement_bb].successors,
+  print_comma_separated (stream,
+			 func.basic_blocks[statement_bb.value].successors,
 			 [this] (BasicBlockId succ) {
-			   stream << "bb" << bb_fold_map[succ];
+			   stream << "bb" << bb_fold_map[succ.value].value;
 			 });
   stream << "]";
   bb_terminated = true;
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 774f2b9e298..2e4a90a7b1c 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -47,7 +47,7 @@ class FactCollector : public Visitor
   Resolver::TypeCheckContext &tyctx;
 
   // Collector state.
-  BasicBlockId current_bb = 0;
+  BasicBlockId current_bb = ENTRY_BASIC_BLOCK;
   uint32_t current_stmt = 0;
   PlaceId lhs = INVALID_PLACE;
 
@@ -161,14 +161,15 @@ protected: // Main collection entry points (for different categories).
     for (PlaceId arg = PlaceId{FIRST_VARIABLE_PLACE.value + 1};
 	 arg < first_local; ++arg.value)
       facts.path_assigned_at_base.emplace_back (
-	arg.value, get_point (0, 0, PointPosition::START));
+	arg.value, get_point (ENTRY_BASIC_BLOCK, 0, PointPosition::START));
 
     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.value, get_point (0, 0, PointPosition::START));
+	    place.value,
+	    get_point (ENTRY_BASIC_BLOCK, 0, PointPosition::START));
       }
   }
 
@@ -208,9 +209,10 @@ protected: // Main collection entry points (for different categories).
   {
     rust_debug ("visit_statemensts");
 
-    for (current_bb = 0; current_bb < basic_blocks.size (); ++current_bb)
+    for (current_bb = ENTRY_BASIC_BLOCK;
+	 current_bb.value < basic_blocks.size (); ++current_bb.value)
       {
-	auto &bb = basic_blocks[current_bb];
+	auto &bb = basic_blocks[current_bb.value];
 	for (current_stmt = 0; current_stmt < bb.statements.size ();
 	     ++current_stmt)
 	  {
@@ -222,7 +224,7 @@ protected: // Main collection entry points (for different categories).
 	    visit (bb.statements[current_stmt]);
 	  }
       }
-    current_bb = 0;
+    current_bb = ENTRY_BASIC_BLOCK;
     current_stmt = 0;
   }
 
@@ -341,7 +343,7 @@ protected: // Main collection entry points (for different categories).
   void visit (const Assignment &expr) override
   {
     rust_debug ("\t_%u = Assignment(_%u) at %u:%u", lhs.value - 1,
-		expr.get_rhs ().value - 1, current_bb, current_stmt);
+		expr.get_rhs ().value - 1, current_bb.value, current_stmt);
 
     issue_read_move (expr.get_rhs ());
     push_place_subset (lhs, expr.get_rhs ());
@@ -391,14 +393,14 @@ protected: // Main collection entry points (for different categories).
 protected: // Statement visitor helpers
   WARN_UNUSED_RESULT const BasicBlock &get_current_bb () const
   {
-    return basic_blocks[current_bb];
+    return basic_blocks[current_bb.value];
   }
 
   WARN_UNUSED_RESULT static Polonius::Point
   get_point (BasicBlockId bb, uint32_t stmt, PointPosition pos)
   {
     Polonius::Point point = 0;
-    point |= (bb << 16);
+    point |= (bb.value << 16);
     point |= (stmt << 1);
     point |= (static_cast<uint8_t> (pos) & 1);
     return point;
@@ -496,9 +498,11 @@ protected: // Generic BIR operations.
     if (!place_db[place_id].should_be_moved ())
       return;
 
-    facts.path_moved_at_base.emplace_back (
-      place_id.value, initial ? get_point (0, 0, PointPosition::START)
-			      : get_current_point_mid ());
+    facts.path_moved_at_base.emplace_back (place_id.value,
+					   initial
+					     ? get_point (ENTRY_BASIC_BLOCK, 0,
+							  PointPosition::START)
+					     : get_current_point_mid ());
 
     check_move_behind_reference (place_id);
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir.h b/gcc/rust/checks/errors/borrowck/rust-bir.h
index 192e4452551..d45270413ce 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir.h
@@ -131,10 +131,24 @@ public:
 };
 
 /** Unique identifier for a basic block in the BIR. */
-using BasicBlockId = uint32_t;
+struct BasicBlockId
+{
+  uint32_t value;
+  // some overloads for comparision
+  bool operator== (const BasicBlockId &rhs) const { return value == rhs.value; }
+  bool operator!= (const BasicBlockId &rhs) const
+  {
+    return !(operator== (rhs));
+  }
+  bool operator< (const BasicBlockId &rhs) const { return value < rhs.value; }
+  bool operator> (const BasicBlockId &rhs) const { return value > rhs.value; }
+  bool operator<= (const BasicBlockId &rhs) const { return !(operator> (rhs)); }
+  bool operator>= (const BasicBlockId &rhs) const { return !(operator< (rhs)); }
+};
 
 static constexpr BasicBlockId INVALID_BB
-  = std::numeric_limits<BasicBlockId>::max ();
+  = {std::numeric_limits<uint32_t>::max ()};
+static constexpr BasicBlockId ENTRY_BASIC_BLOCK = {0};
 
 struct BasicBlock
 {
-- 
2.45.2



More information about the Gcc-rust mailing list