/* IELR's inadequacy annotation list.

   Copyright (C) 2009-2012 Free Software Foundation, Inc.

   This file is part of Bison, the GNU Compiler Compiler.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>
#include "system.h"

#include "AnnotationList.h"
#include "lalr.h"
#include "ielr.h"

/**
 * \pre
 *   - <tt>annotations_obstackp != NULL</tt>.
 * \post
 *   - \c result is a new \c AnnotationList with one node whose:
 *     - \c inadequacyNode member is \c NULL.
 *     - \c contributions member is allocated with \c contribution_count
 *       uninitialized elements.
 *   - All memory was allocated on \c annotations_obstackp.
 */
static AnnotationList*
AnnotationList__alloc_on_obstack (ContributionIndex contribution_count,
                                  struct obstack *annotations_obstackp)
{
  AnnotationList *result;
  size_t contributions_size =
    contribution_count * sizeof result->contributions[0];
  result = obstack_alloc (annotations_obstackp,
                          offsetof (AnnotationList, contributions)
                          + contributions_size);
  result->next = NULL;
  result->inadequacyNode = NULL;
  return result;
}

/**
 * \pre
 *   - <tt>self != NULL</tt>.
 *   - <tt>0 <= ci < self->inadequacyNode->contributionCount</tt>.
 * \post
 *   - \c result = true iff contribution \c ci in \c self represents an
 *     "always" contribution.
 */
static bool
AnnotationList__isContributionAlways (AnnotationList const *self,
                                      ContributionIndex ci)
{
  aver (0 <= ci && ci < self->inadequacyNode->contributionCount);
  return self->contributions[ci] == NULL;
}

/**
 * \pre
 *   - \c self is a single node.
 *   - \c self annotates the same state as every other node in \c list, and
 *     that state has \c nitems kernel items.
 * \post
 *   - If the list \c list already contains an identical annotation to \c self,
 *     \c self was discarded, \c result is false, and the caller is responsible
 *     for the memory of \c self.
 *   - Otherwise, \c list now contains the node \c self, \c result is true, and
 *     \c list assumes responsibility for the memory of \c self.
 *   - The sort in \c list is:
 *     - Sort in reverse order on the unique ID of the associated
 *       inadequacy node.  Because these IDs are assigned in ascending
 *       order, this should mean that the insertion position within an
 *       annotation list is usually near the beginning with other
 *       annotations associated with the same inadequacy.
 *     - Next, sort on the first contribution that is different as follows:
 *       - Sort an always-contribution before a never-contribution before a
 *         potential-contribution.
 *       - Two always-contributions are identical.
 *       - Two never-contributions are identical.
 *       - For two potential-contributions, sort on the contributions' kernel
 *         item bitsets interpreted as binary numbers.
 *  - The sorting has a few effects:
 *    - It accelerates elimination of identical annotations during insertion.
 *    - It determines how the output of \c AnnotationList__debug is sorted.
 *    - Other than that, it's probably not important.
 */
static bool
AnnotationList__insertInto (AnnotationList *self, AnnotationList **list,
                            size_t nitems)
{
  AnnotationList **node;
  for (node = list; *node; node = &(*node)->next)
    {
      int cmp = 0;
      ContributionIndex ci;
      if (self->inadequacyNode->id < (*node)->inadequacyNode->id)
        cmp = 1;
      else if ((*node)->inadequacyNode->id < self->inadequacyNode->id)
        cmp = -1;
      else
        for (ci = 0;
             cmp == 0 && ci < self->inadequacyNode->contributionCount;
             ++ci)
          {
            if (AnnotationList__isContributionAlways (self, ci))
              {
                if (!AnnotationList__isContributionAlways (*node, ci))
                  cmp = -1;
              }
            else if (AnnotationList__isContributionAlways (*node, ci))
              cmp = 1;
            else
              {
                size_t item;
                for (item = 0; cmp == 0 && item < nitems; ++item)
                  {
                    if (!Sbitset__test (self->contributions[ci], item))
                      {
                        if (Sbitset__test ((*node)->contributions[ci], item))
                          cmp = -1;
                      }
                    else if (!Sbitset__test ((*node)->contributions[ci], item))
                      cmp = 1;
                  }
              }
          }
      if (cmp < 0)
        {
          self->next = *node;
          *node = self;
          break;
        }
      else if (cmp == 0)
        {
          self = NULL;
          break;
        }
    }
  if (!*node)
    *node = self;
  return self != NULL;
}

static bitset
AnnotationList__compute_shift_tokens (transitions *trans)
{
  bitset shift_tokens = bitset_create (ntokens, BITSET_FIXED);
  int i;
  FOR_EACH_SHIFT (trans, i)
    bitset_set (shift_tokens, TRANSITION_SYMBOL (trans, i));
  return shift_tokens;
}

static bitset
AnnotationList__compute_conflicted_tokens (bitset shift_tokens,
                                           reductions *reds)
{
  bitset conflicted_tokens = bitset_create (ntokens, BITSET_FIXED);
  bitset conflicted_tokens_rule = bitset_create (ntokens, BITSET_FIXED);
  bitset tokens = bitset_create (ntokens, BITSET_FIXED);
  int i;

  bitset_copy (tokens, shift_tokens);
  for (i = 0; i < reds->num; ++i)
    {
      bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]);
      bitset_or (conflicted_tokens,
                 conflicted_tokens, conflicted_tokens_rule);
      bitset_or (tokens, tokens, reds->lookahead_tokens[i]);
      /* Check that rules are sorted on rule number or the next step in
         AnnotationList__compute_from_inadequacies will misbehave.  */
      aver (i == 0 || reds->rules[i-1] < reds->rules[i]);
    }

  bitset_free (tokens);
  bitset_free (conflicted_tokens_rule);

  return conflicted_tokens;
}

static bool
AnnotationList__compute_lhs_contributions (state *s, rule *the_rule,
                                           symbol_number conflicted_token,
                                           bitsetv follow_kernel_items,
                                           bitsetv always_follows,
                                           state ***predecessors,
                                           bitset **item_lookahead_sets,
                                           Sbitset *items,
                                           struct obstack
                                             *annotations_obstackp)
{
  goto_number lhs_goto = map_goto (s->number, the_rule->lhs->number);
  if (bitset_test (always_follows[lhs_goto], conflicted_token))
    return true;
  *items = Sbitset__new_on_obstack (s->nitems, annotations_obstackp);
  {
    bitset_iterator biter_item;
    bitset_bindex item;
    BITSET_FOR_EACH (biter_item, follow_kernel_items[lhs_goto], item, 0)
      if (ielr_item_has_lookahead (s, 0, item, conflicted_token,
                                   predecessors, item_lookahead_sets))
        Sbitset__set (*items, item);
  }
  return false;
}

static void
AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
                                               bitsetv follow_kernel_items,
                                               bitsetv always_follows,
                                               state ***predecessors,
                                               bitset **item_lookahead_sets,
                                               AnnotationList
                                                 **annotation_lists,
                                               AnnotationIndex
                                                 *annotation_counts,
                                               struct obstack
                                                 *annotations_obstackp)
{
  state **predecessor;
  for (predecessor = predecessors[s->number]; *predecessor; ++predecessor)
    {
      AnnotationList *annotation_node =
        AnnotationList__alloc_on_obstack (
          self->inadequacyNode->contributionCount, annotations_obstackp);
      annotation_node->inadequacyNode = self->inadequacyNode;
      bool potential_contribution = false;
      bitset *lookaheads = NULL;
      {
        ContributionIndex ci;
        for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
          {
            symbol_number contribution_token =
              InadequacyList__getContributionToken (self->inadequacyNode, ci)
                ->number;
            if (AnnotationList__isContributionAlways (self, ci))
              {
                annotation_node->contributions[ci] = NULL;
                continue;
              }
            annotation_node->contributions[ci] =
              Sbitset__new_on_obstack ((*predecessor)->nitems,
                                       annotations_obstackp);
            {
              size_t predecessor_item = 0;
              Sbitset sbiter_item;
              Sbitset__Index self_item;
              SBITSET__FOR_EACH (self->contributions[ci], s->nitems,
                                 sbiter_item, self_item)
                {
                  /* If this kernel item is the beginning of a RHS, it must be
                     the kernel item in the start state, and so it has an empty
                     lookahead set.  Thus, it can't contribute to inadequacies,
                     and so it should never have been identified as a
                     contribution.  If, instead, this kernel item is the
                     successor of the start state's kernel item, the lookahead
                     set is still empty, and so it also should never have been
                     identified as a contribution.  This situation is fortunate
                     because we want to avoid the - 2 below in both cases.  */
                  aver (s->items[self_item] > 1);
                  /* If this kernel item is next to the beginning of the RHS,
                     then check all of the predecessor's goto follows for the
                     LHS.  */
                  if (item_number_is_rule_number (ritem[s->items[self_item]
                                                        - 2]))
                    {
                      Sbitset items;
                      unsigned int rulei;
                      for (rulei = s->items[self_item];
                           !item_number_is_rule_number (ritem[rulei]);
                           ++rulei)
                        ;
                      if (AnnotationList__compute_lhs_contributions (
                            *predecessor,
                            &rules[item_number_as_rule_number (ritem[rulei])],
                            contribution_token,
                            follow_kernel_items, always_follows, predecessors,
                            item_lookahead_sets, &items, annotations_obstackp))
                        {
                          obstack_free (annotations_obstackp,
                                        annotation_node->contributions[ci]);
                          annotation_node->contributions[ci] = NULL;
                          break;
                        }
                      else
                        {
                          Sbitset__or (annotation_node->contributions[ci],
                                       annotation_node->contributions[ci],
                                       items, (*predecessor)->nitems);
                          obstack_free (annotations_obstackp, items);
                        }
                    }
                  /* If this kernel item is later in the RHS, then check the
                     predecessor item's lookahead set.  */
                  else
                    {
                      /* We don't have to start the predecessor item search at
                         the beginning every time because items from both
                         states are sorted by their indices in ritem.  */
                      for (;
                           predecessor_item < (*predecessor)->nitems;
                           ++predecessor_item)
                        if ((*predecessor)->items[predecessor_item]
                            == s->items[self_item] - 1)
                          break;
                      aver (predecessor_item != (*predecessor)->nitems);
                      if (ielr_item_has_lookahead (*predecessor, 0,
                                                   predecessor_item,
                                                   contribution_token,
                                                   predecessors,
                                                   item_lookahead_sets))
                        Sbitset__set (annotation_node->contributions[ci],
                                      predecessor_item);
                    }
                }
            }
            if (annotation_node->contributions[ci])
              {
                Sbitset biter;
                Sbitset__Index i;
                SBITSET__FOR_EACH (annotation_node->contributions[ci],
                                   (*predecessor)->nitems, biter, i)
                  {
                    potential_contribution = true;
                    if (!lookaheads)
                      {
                        size_t j;
                        lookaheads = xnmalloc ((*predecessor)->nitems,
                                               sizeof *lookaheads);
                        for (j = 0; j < (*predecessor)->nitems; ++j)
                          lookaheads[j] = NULL;
                      }
                    if (!lookaheads[i])
                      lookaheads[i] = bitset_create (ntokens, BITSET_FIXED);
                    bitset_set (lookaheads[i], contribution_token);
                  }
              }
          }
      }

      /* If the predecessor has any contributions besides just "always" and
         "never" contributions:
         - If the dominant contribution is split-stable, the annotation could
           not affect merging on this predecessor state or its eventual
           predecessor states.  Moreover, all contributions that affect
           whether the dominant contribution remains dominant must be "always"
           or "never" contributions in order for the dominant contribution to
           be split-stable.  Thus, the dominant contribution computation result
           in eventual successor states will not be affected by lookaheads
           tracked for this predecessor state.  (Also, as in the isocore
           compatibility test, we depend on the fact that isocores with equal
           dominant contributions will have the same dominant contribution when
           merged.  Otherwise, we might have to worry that the presence of a
           potential contribution might somehow be the culprit of that behavior
           and thus need to be tracked regardless of the split stability of the
           dominant contribution.)  Thus, go ahead and discard the annotation
           to save space now plus time during state splitting.
         - Otherwise, record the annotation, and compute any resulting
           annotations needed on predecessor states.  */
      if (potential_contribution)
        {
          if (ContributionIndex__none
              != AnnotationList__computeDominantContribution (
                   annotation_node, (*predecessor)->nitems, lookaheads, true))
            {
              obstack_free (annotations_obstackp, annotation_node);
              annotation_node = NULL;
            }
          {
            size_t i;
            for (i = 0; i < (*predecessor)->nitems; ++i)
              if (lookaheads[i])
                bitset_free (lookaheads[i]);
            free (lookaheads);
          }
          if (annotation_node)
            {
              if (AnnotationList__insertInto (annotation_node,
                                              &annotation_lists[(*predecessor)
                                                                ->number],
                                              (*predecessor)->nitems))
                {
                  ++annotation_counts[(*predecessor)->number];
                  AnnotationList__computePredecessorAnnotations (
                    annotation_node, *predecessor,
                    follow_kernel_items, always_follows, predecessors,
                    item_lookahead_sets, annotation_lists, annotation_counts,
                    annotations_obstackp);
                }
              else
                obstack_free (annotations_obstackp, annotation_node);
            }
        }
      else
        obstack_free (annotations_obstackp, annotation_node);
    }
}

void
AnnotationList__compute_from_inadequacies (
  state *s, bitsetv follow_kernel_items, bitsetv always_follows,
  state ***predecessors, bitset **item_lookahead_sets,
  InadequacyList **inadequacy_lists, AnnotationList **annotation_lists,
  AnnotationIndex *annotation_counts,
  ContributionIndex *max_contributionsp,
  struct obstack *annotations_obstackp,
  InadequacyListNodeCount *inadequacy_list_node_count)
{
  bitsetv all_lookaheads;
  bitset shift_tokens;
  bitset conflicted_tokens;
  bitset_iterator biter_conflict;
  bitset_bindex conflicted_token;

  /* Return an empty list if s->lookahead_tokens = NULL.  */
  if (s->consistent)
    return;

  all_lookaheads = bitsetv_create (s->nitems, ntokens, BITSET_FIXED);
  bitsetv_ones (all_lookaheads);
  shift_tokens = AnnotationList__compute_shift_tokens (s->transitions);
  conflicted_tokens =
    AnnotationList__compute_conflicted_tokens (shift_tokens, s->reductions);

  /* Add an inadequacy annotation for each conflicted_token.  */
  BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0)
    {
      AnnotationList *annotation_node;
      /* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient?  Now
         or convert it inside InadequacyList__new_conflict?  */
      bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED);
      ContributionIndex contribution_count = 0;
      bool potential_contribution = false;

      /* Allocate the annotation node.  */
      {
        int rule_i;
        for (rule_i = 0; rule_i < s->reductions->num; ++rule_i)
          if (bitset_test (s->reductions->lookahead_tokens[rule_i],
                           conflicted_token))
            ++contribution_count;
        if (bitset_test (shift_tokens, conflicted_token))
          ++contribution_count;
        annotation_node =
          AnnotationList__alloc_on_obstack (contribution_count,
                                            annotations_obstackp);
      }

      /* Add a contribution for each reduction that has conflicted_token as a
         lookahead.  */
      {
        ContributionIndex ci = 0;
        int item_i = 0;
        int rule_i;
        for (rule_i = 0; rule_i < s->reductions->num; ++rule_i)
          {
            rule *the_rule = s->reductions->rules[rule_i];
            if (bitset_test (s->reductions->lookahead_tokens[rule_i],
                             conflicted_token))
              {
                bitset_set (actions, rule_i);
                /* If this reduction is on a kernel item, just add it.  */
                if (!item_number_is_rule_number (the_rule->rhs[0]))
                  {
                    annotation_node->contributions[ci] =
                      Sbitset__new_on_obstack (s->nitems,
                                               annotations_obstackp);
                    /* Catch item_i up to rule_i.  This works because both are
                       sorted on rule number.  */
                    while (!item_number_is_rule_number (
                             ritem[s->items[item_i]])
                           || item_number_as_rule_number (
                                ritem[s->items[item_i]])
                              != the_rule->number)
                      {
                        ++item_i;
                        aver (item_i < s->nitems);
                      }
                    Sbitset__set (annotation_node->contributions[ci], item_i);
                  }
                /* Otherwise, add the kernel items whose lookahead sets
                   contribute the conflicted token to this reduction's
                   lookahead set.  */
                else if (AnnotationList__compute_lhs_contributions (
                           s, the_rule, conflicted_token, follow_kernel_items,
                           always_follows, predecessors, item_lookahead_sets,
                           &annotation_node->contributions[ci],
                           annotations_obstackp))
                  {
                    annotation_node->contributions[ci++] = NULL;
                    continue;
                  }
                /* The lookahead token has to come from somewhere.  */
                aver (!Sbitset__isEmpty (annotation_node->contributions[ci],
                                         s->nitems));
                ++ci;
                potential_contribution = true;
              }
          }
      }

      /* If there are any contributions besides just "always" contributions:
         - If there's also a shift contribution, record it.
         - If the dominant contribution is split-stable, then the annotation
           could not affect merging, so go ahead and discard the annotation and
           the inadequacy to save space now plus time during state splitting.
         - Otherwise, record the annotation and the inadequacy, and compute any
           resulting annotations needed on predecessor states.  */
      if (potential_contribution)
        {
          if (bitset_test (shift_tokens, conflicted_token))
            {
              bitset_set (actions, s->reductions->num);
              annotation_node->contributions[contribution_count - 1] = NULL;
            }
          {
            InadequacyList *conflict_node =
              InadequacyList__new_conflict (
                s, symbols[conflicted_token], actions,
                inadequacy_list_node_count);
            actions = NULL;
            annotation_node->inadequacyNode = conflict_node;
            if (ContributionIndex__none
                != AnnotationList__computeDominantContribution (
                     annotation_node, s->nitems, all_lookaheads, true))
              {
                obstack_free (annotations_obstackp, annotation_node);
                InadequacyList__delete (conflict_node);
              }
            else
              {
                InadequacyList__prependTo (conflict_node,
                                           &inadequacy_lists[s->number]);
                aver (AnnotationList__insertInto (
                        annotation_node, &annotation_lists[s->number],
                        s->nitems));
                /* This aver makes sure the
                   AnnotationList__computeDominantContribution check above
                   does discard annotations in the simplest case of a S/R
                   conflict with no token precedence.  */
                aver (!bitset_test (shift_tokens, conflicted_token)
                      || symbols[conflicted_token]->prec);
                ++annotation_counts[s->number];
                if (contribution_count > *max_contributionsp)
                  *max_contributionsp = contribution_count;
                AnnotationList__computePredecessorAnnotations (
                  annotation_node, s,
                  follow_kernel_items, always_follows, predecessors,
                  item_lookahead_sets, annotation_lists, annotation_counts,
                  annotations_obstackp);
              }
          }
        }
      else
        {
          bitset_free (actions);
          obstack_free (annotations_obstackp, annotation_node);
        }
    }

  bitsetv_free (all_lookaheads);
  bitset_free (shift_tokens);
  bitset_free (conflicted_tokens);
}

void
AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
{
  AnnotationList const *a;
  AnnotationIndex ai;
  for (a = self, ai = 0; a; a = a->next, ++ai)
    {
      {
        int j;
        for (j = 0; j < spaces; ++j)
          putc (' ', stderr);
      }
      fprintf (stderr, "Annotation %d (manifesting state %d):\n",
               ai, a->inadequacyNode->manifestingState->number);
      {
        ContributionIndex ci;
        bitset_bindex rulei = 0; /* init suppresses compiler warning */
        rulei = bitset_first (a->inadequacyNode->inadequacy.conflict.actions);
        for (ci = 0; ci < a->inadequacyNode->contributionCount; ++ci)
          {
            symbol_number token =
              InadequacyList__getContributionToken (a->inadequacyNode, ci)
                ->number;
            {
              int j;
              for (j = 0; j < spaces+2; ++j)
                putc (' ', stderr);
            }
            if (ci == InadequacyList__getShiftContributionIndex (
                        a->inadequacyNode))
              fprintf (stderr, "Contributes shift of token %d.\n", token);
            else
              {
                fprintf (stderr, "Contributes token %d", token);
                aver (rulei != BITSET_BINDEX_MAX);
                fprintf (stderr, " as lookahead, rule number %d",
                         a->inadequacyNode->manifestingState
                           ->reductions->rules[rulei]->number);
                rulei =
                  bitset_next (a->inadequacyNode->inadequacy.conflict.actions,
                               rulei+1);
                if (AnnotationList__isContributionAlways (a, ci))
                  fprintf (stderr, " always.");
                else
                  {
                    fprintf (stderr, ", items: ");
                    Sbitset__fprint (a->contributions[ci], nitems, stderr);
                  }
                fprintf (stderr, "\n");
              }
          }
      }
    }
}

void
AnnotationList__computeLookaheadFilter (AnnotationList const *self,
                                        size_t nitems,
                                        bitsetv lookahead_filter)
{
  bitsetv_zero (lookahead_filter);
  for (; self; self = self->next)
    {
      ContributionIndex ci;
      for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
        if (!AnnotationList__isContributionAlways (self, ci))
          {
            Sbitset__Index item;
            Sbitset biter;
            symbol_number token =
              InadequacyList__getContributionToken (self->inadequacyNode, ci)
                ->number;
            SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
              bitset_set (lookahead_filter[item], token);
          }
    }
}

/**
 * \pre
 *   - <tt>self != NULL</tt>.
 *   - \c nitems is the number of kernel items in the LR(0) state that \c self
 *     annotates.
 *   - \c lookaheads describes the lookahead sets on the kernel items of some
 *     isocore of the LR(0) state that \c self annotates.  Either:
 *     - <tt>lookaheads = NULL</tt> only if the lookahead set on every kernel
 *       item is empty.
 *     - For any <tt>0 <= i < nitems</tt>, <tt>lookaheads[i]</tt> is either:
 *       - \c NULL only if the lookahead set on kernel item \c i is empty.
 *       - The (possibly empty) lookahead set on kernel item \c i.
 *   - <tt>0 <= ci < self->inadequacyNode->contributionCount</tt>.
 * \post
 *   - \c result = true iff contribution \c ci in \c self is made by the state
 *     described by \c lookaheads.
 */
static bool
AnnotationList__stateMakesContribution (AnnotationList const *self,
                                        size_t nitems, ContributionIndex ci,
                                        bitset *lookaheads)
{
  if (AnnotationList__isContributionAlways (self, ci))
    return true;
  if (!lookaheads)
    return false;
  {
    symbol_number token =
      InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
    Sbitset__Index item;
    Sbitset biter;
    SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
      if (lookaheads[item] && bitset_test (lookaheads[item], token))
        return true;
  }
  return false;
}

ContributionIndex
AnnotationList__computeDominantContribution (AnnotationList const *self,
                                             size_t nitems, bitset *lookaheads,
                                             bool require_split_stable)
{
  symbol *token;
  ContributionIndex const ci_shift =
    InadequacyList__getShiftContributionIndex (self->inadequacyNode);

  token = self->inadequacyNode->inadequacy.conflict.token;

  /* S/R conflict.  */
  if (ci_shift != ContributionIndex__none)
    {
      bool find_stable_domination_over_shift = false;
      bool find_stable_error_action_domination = false;
      {
        ContributionIndex ci;
        int actioni;
        ContributionIndex ci_rr_dominator = ContributionIndex__none;
        int shift_precedence = token->prec;

        /* If the token has no precedence set, shift is always chosen.  */
        if (!shift_precedence)
          return ci_shift;

        /* Figure out which reductions contribute, which of those would
           dominate in a R/R comparison, and whether any reduction dominates
           the shift so that the R/R comparison is actually needed.  */
        for (ci = 0, actioni = bitset_first (self->inadequacyNode->inadequacy
                                             .conflict.actions);
             ci < self->inadequacyNode->contributionCount;
             ++ci, actioni = bitset_next (self->inadequacyNode->inadequacy
                                          .conflict.actions, actioni+1))
          {
            int reduce_precedence = 0;
            if (ci == ci_shift)
              continue;
            {
              rule *r = self->inadequacyNode->manifestingState
                          ->reductions->rules[actioni];
              if (r->prec)
                reduce_precedence = r->prec->prec;
            }
            /* If there's no need to check whether this reduction actually
               contributes because the shift eliminates it from the R/R
               comparison anyway, continue to the next reduction.  */
            if (reduce_precedence
                && (reduce_precedence < shift_precedence
                    || (reduce_precedence == shift_precedence
                        && token->assoc == right_assoc)))
              continue;
            if (!AnnotationList__stateMakesContribution (self, nitems, ci,
                                                         lookaheads))
              continue;
            /* This uneliminated reduction contributes, so see if it can cause
               an error action.  */
            if (reduce_precedence == shift_precedence
                 && token->assoc == non_assoc)
              {
                /* It's not possible to find split-stable domination over
                   shift after a potential %nonassoc.  */
                if (find_stable_domination_over_shift)
                  return ContributionIndex__none;
                if (!require_split_stable
                    || AnnotationList__isContributionAlways (self, ci))
                  return ContributionIndex__error_action;
                find_stable_error_action_domination = true;
              }
            /* Consider this uneliminated contributing reduction in the R/R
               comparison.  */
            if (ci_rr_dominator == ContributionIndex__none)
              ci_rr_dominator = ci;
            /* If precedence is set for this uneliminated contributing
               reduction, it dominates the shift, so try to figure out which
               reduction dominates the R/R comparison.  */
            if (reduce_precedence)
              {
                /* It's not possible to find split-stable error action
                   domination after a potential reduction.  */
                if (find_stable_error_action_domination)
                  return ContributionIndex__none;
                if (!require_split_stable)
                  return ci_rr_dominator;
                if (!AnnotationList__isContributionAlways (self,
                                                           ci_rr_dominator))
                  return ContributionIndex__none;
                if (AnnotationList__isContributionAlways (self, ci))
                  return ci_rr_dominator;
                find_stable_domination_over_shift = true;
              }
          }
      }
      if (find_stable_domination_over_shift
          || find_stable_error_action_domination)
        return ContributionIndex__none;
      /* No reduce or error action domination found, so shift dominates.  */
      return ci_shift;
    }

  /* R/R conflict, so the reduction with the lowest rule number dominates.
     Fortunately, contributions are sorted by rule number.  */
  {
    ContributionIndex ci;
    for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci)
      if (AnnotationList__stateMakesContribution (self, nitems, ci,
                                                  lookaheads))
        {
          if (require_split_stable
              && !AnnotationList__isContributionAlways (self, ci))
            return ContributionIndex__none;
          return ci;
        }
  }
  return ContributionIndex__none;
}
