]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Retire now obsoleted do_sp_search() trampoline code
[stockfish] / src / search.cpp
index 64b8dd0e10cd33c1ea9acf50e7e859040b8b00f8..b8c6c952eaac5ca3e7e0176b41231e45312a4ea2 100644 (file)
@@ -295,9 +295,6 @@ namespace {
   template <NodeType PvNode>
   Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
 
-  template <NodeType PvNode>
-  void do_sp_search(SplitPoint* sp, int threadID);
-
   template <NodeType PvNode>
   Depth extension(const Position& pos, Move m, bool captureOrPromotion, bool moveIsCheck, bool singleEvasion, bool mateThreat, bool* dangerous);
 
@@ -717,7 +714,7 @@ namespace {
     int64_t nodes;
     Move move;
     Depth depth, ext, newDepth;
-    Value value, evalMargin, alpha, beta;
+    Value value, alpha, beta;
     bool isCheck, moveIsCheck, captureOrPromotion, dangerous;
     int researchCountFH, researchCountFL;
 
@@ -736,7 +733,8 @@ namespace {
 
     // Step 5. Evaluate the position statically
     // At root we do this only to get reference value for child nodes
-    ss->eval = isCheck ? VALUE_NONE : evaluate(pos, evalMargin);
+    ss->evalMargin = VALUE_NONE;
+    ss->eval = isCheck ? VALUE_NONE : evaluate(pos, ss->evalMargin);
 
     // Step 6. Razoring (omitted at root)
     // Step 7. Static null move pruning (omitted at root)
@@ -960,7 +958,12 @@ namespace {
   }
 
 
-  // search<>() is the main search function for both PV and non-PV nodes
+  // search<>() is the main search function for both PV and non-PV nodes and for
+  // normal and SplitPoint nodes. When called just after a split point the search
+  // is simpler because we have already probed the hash table, done a null move
+  // search, and searched the first move before splitting, we don't have to repeat
+  // all this work again. We also don't need to store anything to the hash table
+  // here: This is taken care of after we return from the split point.
 
   template <NodeType PvNode, bool SplitPoint>
   Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
@@ -977,7 +980,7 @@ namespace {
     Key posKey;
     Move ttMove, move, excludedMove, threatMove;
     Depth ext, newDepth;
-    Value bestValue, value, evalMargin, oldAlpha;
+    Value bestValue, value, oldAlpha;
     Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific
     bool isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous;
     bool mateThreat = false;
@@ -993,7 +996,7 @@ namespace {
         ttMove = excludedMove = MOVE_NONE;
         threatMove = ss->sp->threatMove;
         mateThreat = ss->sp->mateThreat;
-        goto split_start;
+        goto split_point_start;
     }
 
     // Step 1. Initialize node and poll. Polling can abort search
@@ -1050,19 +1053,19 @@ namespace {
     // Step 5. Evaluate the position statically and
     // update gain statistics of parent move.
     if (isCheck)
-        ss->eval = evalMargin = VALUE_NONE;
+        ss->eval = ss->evalMargin = VALUE_NONE;
     else if (tte)
     {
         assert(tte->static_value() != VALUE_NONE);
 
         ss->eval = tte->static_value();
-        evalMargin = tte->static_value_margin();
+        ss->evalMargin = tte->static_value_margin();
         refinedValue = refine_eval(tte, ss->eval, ply);
     }
     else
     {
-        refinedValue = ss->eval = evaluate(pos, evalMargin);
-        TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, evalMargin);
+        refinedValue = ss->eval = evaluate(pos, ss->evalMargin);
+        TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, ss->evalMargin);
     }
 
     // Save gain for the parent non-capture move
@@ -1179,7 +1182,7 @@ namespace {
     if (PvNode)
         mateThreat = pos.has_mate_threat();
 
-split_start:
+split_point_start: // At split points actual search starts from here
 
     // Initialize a MovePicker object for the current position
     // FIXME currently MovePicker() c'tor is needless called also in SplitPoint
@@ -1187,8 +1190,8 @@ split_start:
     MovePicker& mp = SplitPoint ? *ss->sp->mp : mpBase;
     CheckInfo ci(pos);
     ss->bestMove = MOVE_NONE;
-    singleEvasion = SplitPoint ? false : isCheck && mp.number_of_evasions() == 1;
-    futilityBase = SplitPoint ? ss->eval : ss->eval + evalMargin;
+    singleEvasion = !SplitPoint && isCheck && mp.number_of_evasions() == 1;
+    futilityBase = ss->eval + ss->evalMargin;
     singularExtensionNode =  !SplitPoint
                            && depth >= SingularExtensionDepth[PvNode]
                            && tte
@@ -1429,7 +1432,7 @@ split_start:
 
     ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT);
     move = (bestValue <= oldAlpha ? MOVE_NONE : ss->bestMove);
-    TT.store(posKey, value_to_tt(bestValue, ply), vt, depth, move, ss->eval, evalMargin);
+    TT.store(posKey, value_to_tt(bestValue, ply), vt, depth, move, ss->eval, ss->evalMargin);
 
     // Update killers and history only for non capture moves that fails high
     if (    bestValue >= beta
@@ -1615,28 +1618,6 @@ split_start:
   }
 
 
-  // sp_search() is used to search from a split point.  This function is called
-  // by each thread working at the split point.  It is similar to the normal
-  // search() function, but simpler.  Because we have already probed the hash
-  // table, done a null move search, and searched the first move before
-  // splitting, we don't have to repeat all this work in sp_search().  We
-  // also don't need to store anything to the hash table here:  This is taken
-  // care of after we return from the split point.
-
-  template <NodeType PvNode>
-  void do_sp_search(SplitPoint* sp, int threadID) {
-
-    assert(threadID >= 0 && threadID < ThreadsMgr.active_threads());
-    assert(ThreadsMgr.active_threads() > 1);
-
-    Position pos(*sp->pos, threadID);
-    SearchStack* ss = sp->sstack[threadID] + 1;
-    ss->sp = sp;
-
-    search<PvNode, true>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->ply);
-  }
-
-
   // connected_moves() tests whether two moves are 'connected' in the sense
   // that the first move somehow made the second move possible (for instance
   // if the moving piece is the same in both moves). The first move is assumed
@@ -2286,10 +2267,16 @@ split_start:
 
             threads[threadID].state = THREAD_SEARCHING;
 
-            if (threads[threadID].splitPoint->pvNode)
-                do_sp_search<PV>(threads[threadID].splitPoint, threadID);
+            // Here we call search() with SplitPoint template parameter set to true
+            SplitPoint* sp = threads[threadID].splitPoint;
+            Position pos(*sp->pos, threadID);
+            SearchStack* ss = sp->sstack[threadID] + 1;
+            ss->sp = sp;
+
+            if (sp->pvNode)
+                search<PV, true>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->ply);
             else
-                do_sp_search<NonPV>(threads[threadID].splitPoint, threadID);
+                search<NonPV, true>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->ply);
 
             assert(threads[threadID].state == THREAD_SEARCHING);
 
@@ -2635,7 +2622,7 @@ split_start:
 
     // Initialize search stack
     init_ss_array(ss, PLY_MAX_PLUS_2);
-    ss[0].eval = VALUE_NONE;
+    ss[0].eval = ss[0].evalMargin = VALUE_NONE;
     count = 0;
 
     // Generate all legal moves