Templetize sliding attacks
authorMarco Costalba <mcostalba@gmail.com>
Sun, 12 Feb 2012 15:02:13 +0000 (16:02 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 13 Feb 2012 08:15:55 +0000 (09:15 +0100)
No functional change and no speed regression, it seems
to be even a bit faster on MSVC and gcc.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/bitboard.cpp
src/bitboard.h
src/evaluate.cpp
src/position.cpp
src/position.h

index c67c01a..bdde916 100644 (file)
@@ -64,7 +64,7 @@ namespace {
   typedef unsigned (Fn)(Square, Bitboard);
 
   void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[],
-                   Bitboard masks[], unsigned shifts[], Square deltas[], Fn get_index);
+                   Bitboard masks[], unsigned shifts[], Square deltas[], Fn index);
 }
 
 
@@ -219,13 +219,13 @@ void bitboards_init() {
   Square RDeltas[] = { DELTA_N,  DELTA_E,  DELTA_S,  DELTA_W  };
   Square BDeltas[] = { DELTA_NE, DELTA_SE, DELTA_SW, DELTA_NW };
 
-  init_magics(RTable, RAttacks, RMagics, RMasks, RShifts, RDeltas, r_index);
-  init_magics(BTable, BAttacks, BMagics, BMasks, BShifts, BDeltas, b_index);
+  init_magics(RTable, RAttacks, RMagics, RMasks, RShifts, RDeltas, magic_index<ROOK>);
+  init_magics(BTable, BAttacks, BMagics, BMasks, BShifts, BDeltas, magic_index<BISHOP>);
 
   for (Square s = SQ_A1; s <= SQ_H8; s++)
   {
-      PseudoAttacks[BISHOP][s] = bishop_attacks_bb(s, 0);
-      PseudoAttacks[ROOK][s]   = rook_attacks_bb(s, 0);
+      PseudoAttacks[BISHOP][s] = attacks_bb<BISHOP>(s, 0);
+      PseudoAttacks[ROOK][s]   = attacks_bb<ROOK>(s, 0);
       PseudoAttacks[QUEEN][s]  = PseudoAttacks[BISHOP][s] | PseudoAttacks[ROOK][s];
   }
 
@@ -290,7 +290,7 @@ namespace {
   // use the so called "fancy" approach.
 
   void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[],
-                   Bitboard masks[], unsigned shifts[], Square deltas[], Fn get_index) {
+                   Bitboard masks[], unsigned shifts[], Square deltas[], Fn index) {
 
     int MagicBoosters[][8] = { { 3191, 2184, 1310, 3618, 2091, 1308, 2452, 3996 },
                                { 1059, 3608,  605, 3234, 3326,   38, 2029, 3043 } };
@@ -342,7 +342,7 @@ namespace {
             // effect of verifying the magic.
             for (i = 0; i < size; i++)
             {
-                Bitboard& attack = attacks[s][get_index(s, occupancy[i])];
+                Bitboard& attack = attacks[s][index(s, occupancy[i])];
 
                 if (attack && attack != reference[i])
                     break;
index 24ae794..7a39a50 100644 (file)
@@ -116,43 +116,28 @@ inline Bitboard in_front_bb(Color c, Square s) {
 }
 
 
-/// Functions for computing sliding attack bitboards. rook_attacks_bb(),
-/// bishop_attacks_bb() and queen_attacks_bb() all take a square and a
-/// bitboard of occupied squares as input, and return a bitboard representing
-/// all squares attacked by a rook, bishop or queen on the given square.
+/// Functions for computing sliding attack bitboards. Function attacks_bb() takes
+/// a square and a bitboard of occupied squares as input, and returns a bitboard
+/// representing all squares attacked by Pt (bishop or rook) on the given square.
+template<PieceType Pt>
+FORCE_INLINE unsigned magic_index(Square s, Bitboard occ) {
 
-#if defined(IS_64BIT)
+  Bitboard* const Masks  = Pt == ROOK ? RMasks  : BMasks;
+  Bitboard* const Magics = Pt == ROOK ? RMagics : BMagics;
+  unsigned* const Shifts = Pt == ROOK ? RShifts : BShifts;
 
-FORCE_INLINE unsigned r_index(Square s, Bitboard occ) {
-  return unsigned(((occ & RMasks[s]) * RMagics[s]) >> RShifts[s]);
-}
-
-FORCE_INLINE unsigned b_index(Square s, Bitboard occ) {
-  return unsigned(((occ & BMasks[s]) * BMagics[s]) >> BShifts[s]);
-}
-
-#else // if !defined(IS_64BIT)
-
-FORCE_INLINE unsigned r_index(Square s, Bitboard occ) {
-  unsigned lo = unsigned(occ) & unsigned(RMasks[s]);
-  unsigned hi = unsigned(occ >> 32) & unsigned(RMasks[s] >> 32);
-  return (lo * unsigned(RMagics[s]) ^ hi * unsigned(RMagics[s] >> 32)) >> RShifts[s];
-}
-
-FORCE_INLINE unsigned b_index(Square s, Bitboard occ) {
-  unsigned lo = unsigned(occ) & unsigned(BMasks[s]);
-  unsigned hi = unsigned(occ >> 32) & unsigned(BMasks[s] >> 32);
-  return (lo * unsigned(BMagics[s]) ^ hi * unsigned(BMagics[s] >> 32)) >> BShifts[s];
-}
-
-#endif
+  if (Is64Bit)
+      return unsigned(((occ & Masks[s]) * Magics[s]) >> Shifts[s]);
 
-inline Bitboard rook_attacks_bb(Square s, Bitboard occ) {
-  return RAttacks[s][r_index(s, occ)];
+  unsigned lo = unsigned(occ) & unsigned(Masks[s]);
+  unsigned hi = unsigned(occ >> 32) & unsigned(Masks[s] >> 32);
+  return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s];
 }
 
-inline Bitboard bishop_attacks_bb(Square s, Bitboard occ) {
-  return BAttacks[s][b_index(s, occ)];
+template<PieceType Pt>
+inline Bitboard attacks_bb(Square s, Bitboard occ) {
+  Bitboard** const Attacks = Pt == ROOK ? RAttacks : BAttacks;
+  return Attacks[s][magic_index<Pt>(s, occ)];
 }
 
 
index 745d1a3..e2d8ac3 100644 (file)
@@ -487,9 +487,9 @@ namespace {
         if (Piece == KNIGHT || Piece == QUEEN)
             b = pos.attacks_from<Piece>(s);
         else if (Piece == BISHOP)
-            b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
+            b = attacks_bb<BISHOP>(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
         else if (Piece == ROOK)
-            b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
+            b = attacks_bb<ROOK>(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
         else
             assert(false);
 
index f50677b..9fa7c72 100644 (file)
@@ -386,8 +386,8 @@ Bitboard Position::attackers_to(Square s, Bitboard occ) const {
   return  (attacks_from<PAWN>(s, BLACK) & pieces(PAWN, WHITE))
         | (attacks_from<PAWN>(s, WHITE) & pieces(PAWN, BLACK))
         | (attacks_from<KNIGHT>(s)      & pieces(KNIGHT))
-        | (rook_attacks_bb(s, occ)      & pieces(ROOK, QUEEN))
-        | (bishop_attacks_bb(s, occ)    & pieces(BISHOP, QUEEN))
+        | (attacks_bb<ROOK>(s, occ)     & pieces(ROOK, QUEEN))
+        | (attacks_bb<BISHOP>(s, occ)   & pieces(BISHOP, QUEEN))
         | (attacks_from<KING>(s)        & pieces(KING));
 }
 
@@ -401,9 +401,9 @@ Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) {
 
   switch (type_of(p))
   {
-  case BISHOP: return bishop_attacks_bb(s, occ);
-  case ROOK  : return rook_attacks_bb(s, occ);
-  case QUEEN : return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ);
+  case BISHOP: return attacks_bb<BISHOP>(s, occ);
+  case ROOK  : return attacks_bb<ROOK>(s, occ);
+  case QUEEN : return attacks_bb<BISHOP>(s, occ) | attacks_bb<ROOK>(s, occ);
   default    : return StepAttacksBB[p][s];
   }
 }
@@ -434,8 +434,8 @@ bool Position::move_attacks_square(Move m, Square s) const {
       return true;
 
   // Scan for possible X-ray attackers behind the moved piece
-  xray = (rook_attacks_bb(s, occ)   & pieces(ROOK, QUEEN, color_of(piece)))
-        |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN, color_of(piece)));
+  xray = (attacks_bb<ROOK>(s, occ)   & pieces(ROOK, QUEEN, color_of(piece)))
+        |(attacks_bb<BISHOP>(s, occ) & pieces(BISHOP, QUEEN, color_of(piece)));
 
   // Verify attackers are triggered by our move and not already existing
   return xray && (xray ^ (xray & attacks_from<QUEEN>(s)));
@@ -475,8 +475,8 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
       b ^= capsq;
       b |= to;
 
-      return   !(rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, them))
-            && !(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, them));
+      return   !(attacks_bb<ROOK>(ksq, b) & pieces(ROOK, QUEEN, them))
+            && !(attacks_bb<BISHOP>(ksq, b) & pieces(BISHOP, QUEEN, them));
   }
 
   // If the moving piece is a king, check whether the destination
@@ -684,8 +684,8 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
       b ^= from;
       b ^= capsq;
       b |= to;
-      return  (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us))
-            ||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us));
+      return  (attacks_bb<ROOK>(ksq, b) & pieces(ROOK, QUEEN, us))
+            ||(attacks_bb<BISHOP>(ksq, b) & pieces(BISHOP, QUEEN, us));
   }
 
   // Castling with check ?
@@ -707,7 +707,7 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
       b ^= rfrom;
       b |= rto;
       b |= kto;
-      return rook_attacks_bb(rto, b) & ksq;
+      return attacks_bb<ROOK>(rto, b) & ksq;
   }
 
   return false;
@@ -1301,8 +1301,8 @@ int Position::see(Move m) const {
       // and scan for new X-ray attacks behind the attacker.
       b = stmAttackers & pieces(pt);
       occ ^= (b & (~b + 1));
-      attackers |=  (rook_attacks_bb(to, occ)   & pieces(ROOK, QUEEN))
-                  | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN));
+      attackers |=  (attacks_bb<ROOK>(to, occ)   & pieces(ROOK, QUEEN))
+                  | (attacks_bb<BISHOP>(to, occ) & pieces(BISHOP, QUEEN));
 
       attackers &= occ; // Cut out pieces we've already done
 
index 8229e71..e471bae 100644 (file)
@@ -345,10 +345,9 @@ inline Square Position::castle_rook_square(CastleRight f) const {
 
 template<PieceType Pt>
 inline Bitboard Position::attacks_from(Square s) const {
-  return  Pt == BISHOP ? bishop_attacks_bb(s, occupied_squares())
-        : Pt == ROOK   ? rook_attacks_bb(s, occupied_squares())
+  return  Pt == BISHOP || Pt == ROOK ? attacks_bb<Pt>(s, occupied_squares())
         : Pt == QUEEN  ? attacks_from<ROOK>(s) | attacks_from<BISHOP>(s)
-                       : StepAttacksBB[Pt][s];
+        : StepAttacksBB[Pt][s];
 }
 
 template<>