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(); } } }
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; }