void SwingDetector::add(ChordRest *cr)
      {
      if (elements.empty()) {
            if (ReducedFraction(cr->globalDuration()) >= FULL_LEN)
                  return;
            const int tickInBar = cr->tick() - cr->measure()->tick();
            if (tickInBar % MScore::division == 0)
                  append(cr);
            }
      else {
            if (sumLen + ReducedFraction(cr->globalDuration()) > FULL_LEN) {
                  reset();
                  return;
                  }
            append(cr);
            if (sumLen == FULL_LEN) {
                              // check for swing patterns
                  switch (swingType) {
                        case MidiOperation::Swing::SWING:
                              checkNormalSwing();
                              break;
                        case MidiOperation::Swing::SHUFFLE:
                              checkShuffle();
                              break;
                        default:
                              break;
                        }
                  reset();
                  }
            }
      }
Exemple #2
0
bool checkRegisters(const IRUnit& unit, const RegAllocInfo& regs) {
  assert(checkCfg(unit));
  auto blocks = rpoSortCfg(unit);
  StateVector<Block, RegState> states(unit, RegState());
  StateVector<Block, bool> reached(unit, false);
  for (auto* block : blocks) {
    RegState state = states[block];
    for (IRInstruction& inst : *block) {
      if (inst.op() == Jmp) continue; // handled by Shuffle
      auto& inst_regs = regs[inst];
      for (int i = 0, n = inst.numSrcs(); i < n; ++i) {
        auto const &rs = inst_regs.src(i);
        if (!rs.spilled()) {
          // hack - ignore rbx and rbp
          bool ignore_frame_regs;

          switch (arch()) {
            case Arch::X64:
              ignore_frame_regs = (rs.reg(0) == X64::rVmSp ||
                                  rs.reg(0) == X64::rVmFp);
              break;
            case Arch::ARM:
               ignore_frame_regs = (rs.reg(0) == ARM::rVmSp ||
                                   rs.reg(0) == ARM::rVmFp);
              break;
          }
          if (ignore_frame_regs) continue;
        }
        DEBUG_ONLY auto src = inst.src(i);
        assert(rs.numWords() == src->numWords() ||
               (src->isConst() && rs.numWords() == 0));
        DEBUG_ONLY auto allocated = rs.numAllocated();
        if (allocated == 2) {
          if (rs.spilled()) {
            assert(rs.slot(0) != rs.slot(1));
          } else {
            assert(rs.reg(0) != rs.reg(1));
          }
        }
        for (unsigned i = 0, n = rs.numAllocated(); i < n; ++i) {
          assert(state.tmp(rs, i) == src);
        }
      }
      auto update = [&](SSATmp* tmp, const PhysLoc& loc) {
        for (unsigned i = 0, n = loc.numAllocated(); i < n; ++i) {
          state.tmp(loc, i) = tmp;
        }
      };
      if (inst.op() == Shuffle) {
        checkShuffle(inst, regs);
        for (unsigned i = 0; i < inst.numSrcs(); ++i) {
          update(inst.src(i), inst.extra<Shuffle>()->dests[i]);
        }
      } else {
        for (unsigned i = 0; i < inst.numDsts(); ++i) {
          update(inst.dst(i), inst_regs.dst(i));
        }
      }
    }
    // State contains the PhysLoc->SSATmp reverse mappings at block end;
    // propagate the state to succ
    auto updateEdge = [&](Block* succ) {
      if (!reached[succ]) {
        states[succ] = state;
      } else {
        states[succ].merge(state);
      }
    };
    if (auto* next = block->next()) updateEdge(next);
    if (auto* taken = block->taken()) updateEdge(taken);
  }

  return true;
}