Intel® oneAPI DPC++/C++ Compiler
Talk to fellow users of Intel® oneAPI DPC++/C++ Compiler and companion tools like Intel® oneAPI DPC++ Library, Intel® DPC++ Compatibility Tool, and Intel® Distribution for GDB*
801 Discussions

Compiler hanging in loop with recursive templates

CoderJoe
Beginner
325 Views

I wonder if this could be a bug with the compiler?

In the following function, adding a dummy call to my template allows the compiler to complete its process. If I remove the lines with the "empty" BoardState, the compiler hangs (process clang-cl).

template <int depth, bool side, bool wKMoved, bool bKMoved, Piece piece>
ForceInline void makeMoves(U64& nodes, U64 attacks, int from, BoardState& board, int kES) {
    int to;
    U64 moves = attacks & ~board.occE;
    Bitloop(moves) {
        to = SquareOf(moves);

        BoardState newBoard = board.make<piece, side, false>(from, to, board, kES);
        if constexpr (piece == Piece::King) {
            if constexpr (side == white)    nodes += PerftGenerator<depth - 1, !side, true, bKMoved>::generateMoves(newBoard);
            else                            nodes += PerftGenerator<depth - 1, !side, wKMoved, true>::generateMoves(newBoard);
        }
        else {
            nodes += PerftGenerator<depth - 1, !side, wKMoved, bKMoved>::generateMoves(newBoard);

            BoardState empty = BoardState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
            PerftGenerator<depth - 1, !side, wKMoved, bKMoved>::generateMoves(empty);
        }
    }

    moves = attacks & board.occE;
    Bitloop(moves) {
        to = SquareOf(moves);

        BoardState newBoard = board.make<piece, side, true>(from, to, board, kES);
        if constexpr (piece == Piece::King) {
            if constexpr (side == white)    nodes += PerftGenerator<depth - 1, !side, true, bKMoved>::generateMoves(newBoard);
            else                            nodes += PerftGenerator<depth - 1, !side, wKMoved, true>::generateMoves(newBoard);
        }
        else {
            nodes += PerftGenerator<depth - 1, !side, wKMoved, bKMoved>::generateMoves(newBoard);

            BoardState empty = BoardState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
            PerftGenerator<depth - 1, !side, wKMoved, bKMoved>::generateMoves(empty);
        }
    }
}

Another funny thing is that with my "King", it still compiles, so I didn't have to add the dummy call, but for all other pieces it doesn't. However, the same template/code is executed. I tried to only keep the code that the King executes to test, but it was hanging nonetheless.

 

 Please do not suggest to remove the forced inlining, my only goal is to make the fastest code possible. It compiles without "__forceinline" but performance takes a huge hit, and it's not the question anyway.

0 Kudos
0 Replies
Reply