Ejemplo n.º 1
0
/*
 * Check that each destination register or spill slot is unique,
 * and that sources have the same number or less operands than
 * destinations.
 */
bool checkShuffle(const IRInstruction& inst, const RegAllocInfo& regs) {
  auto n = inst.numSrcs();
  assert(n == inst.extra<Shuffle>()->size);
  RegSet destRegs;
  std::bitset<NumPreAllocatedSpillLocs> destSlots;
  auto& inst_regs = regs[inst];
  for (uint32_t i = 0; i < n; ++i) {
    DEBUG_ONLY auto& rs = inst_regs.src(i);
    DEBUG_ONLY auto& rd = inst.extra<Shuffle>()->dests[i];
    if (rd.numAllocated() == 0) continue; // dest was unused; ignore.
    if (rd.spilled()) {
      assert(!rs.spilled()); // no mem-mem copies
    } else {
      // rs could have less assigned registers/slots than rd, in these cases:
      // - when rs is empty, because the source is a constant.
      // - when rs has 1 register because it's untagged but rd needs 2 because
      //   it's a more general (tagged) type, because of a phi.
      assert(rs.numWords() <= rd.numWords());
      assert(rs.spilled() || rs.isFullSIMD() == rd.isFullSIMD());
    }
    for (int j = 0; j < rd.numAllocated(); ++j) {
      if (rd.spilled()) {
        assert(!destSlots.test(rd.slot(j)));
        destSlots.set(rd.slot(j));
      } else {
        assert(!destRegs.contains(rd.reg(j))); // no duplicate dests
        destRegs.add(rd.reg(j));
      }
    }
  }
  return true;
}