Beispiel #1
0
/// Look for every register defined by potential LOHs candidates.
/// Map these registers with dense id in @p RegToId and vice-versa in
/// @p IdToReg. @p IdToReg is populated only in DEBUG mode.
static void collectInvolvedReg(const MachineFunction &MF, MapRegToId &RegToId,
                               MapIdToReg &IdToReg,
                               const TargetRegisterInfo *TRI) {
  unsigned CurRegId = 0;
  if (!PreCollectRegister) {
    unsigned NbReg = TRI->getNumRegs();
    for (; CurRegId < NbReg; ++CurRegId) {
      RegToId[CurRegId] = CurRegId;
      DEBUG(IdToReg.push_back(CurRegId));
      DEBUG(assert(IdToReg[CurRegId] == CurRegId && "Reg index mismatches"));
    }
    return;
  }

  DEBUG(dbgs() << "** Collect Involved Register\n");
  for (const auto &MBB : MF) {
    for (const MachineInstr &MI : MBB) {
      if (!canDefBePartOfLOH(&MI) &&
          !isCandidateLoad(&MI) && !isCandidateStore(&MI))
        continue;

      // Process defs
      for (MachineInstr::const_mop_iterator IO = MI.operands_begin(),
                                            IOEnd = MI.operands_end();
           IO != IOEnd; ++IO) {
        if (!IO->isReg() || !IO->isDef())
          continue;
        unsigned CurReg = IO->getReg();
        for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI)
          if (RegToId.find(*AI) == RegToId.end()) {
            DEBUG(IdToReg.push_back(*AI);
                  assert(IdToReg[CurRegId] == *AI &&
                         "Reg index mismatches insertion index."));
            RegToId[*AI] = CurRegId++;
            DEBUG(dbgs() << "Register: " << PrintReg(*AI, TRI) << '\n');
          }
      }
    }
  }
void MachineVerifier::verifyLiveIntervals() {
  assert(LiveInts && "Don't call verifyLiveIntervals without LiveInts");
  for (LiveIntervals::const_iterator LVI = LiveInts->begin(),
       LVE = LiveInts->end(); LVI != LVE; ++LVI) {
    const LiveInterval &LI = *LVI->second;

    // Spilling and splitting may leave unused registers around. Skip them.
    if (MRI->use_empty(LI.reg))
      continue;

    // Physical registers have much weirdness going on, mostly from coalescing.
    // We should probably fix it, but for now just ignore them.
    if (TargetRegisterInfo::isPhysicalRegister(LI.reg))
      continue;

    assert(LVI->first == LI.reg && "Invalid reg to interval mapping");

    for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
         I!=E; ++I) {
      VNInfo *VNI = *I;
      const VNInfo *DefVNI = LI.getVNInfoAt(VNI->def);

      if (!DefVNI) {
        if (!VNI->isUnused()) {
          report("Valno not live at def and not marked unused", MF);
          *OS << "Valno #" << VNI->id << " in " << LI << '\n';
        }
        continue;
      }

      if (VNI->isUnused())
        continue;

      if (DefVNI != VNI) {
        report("Live range at def has different valno", MF);
        *OS << "Valno #" << VNI->id << " is defined at " << VNI->def
            << " where valno #" << DefVNI->id << " is live in " << LI << '\n';
        continue;
      }

      const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def);
      if (!MBB) {
        report("Invalid definition index", MF);
        *OS << "Valno #" << VNI->id << " is defined at " << VNI->def
            << " in " << LI << '\n';
        continue;
      }

      if (VNI->isPHIDef()) {
        if (VNI->def != LiveInts->getMBBStartIdx(MBB)) {
          report("PHIDef value is not defined at MBB start", MF);
          *OS << "Valno #" << VNI->id << " is defined at " << VNI->def
              << ", not at the beginning of BB#" << MBB->getNumber()
              << " in " << LI << '\n';
        }
      } else {
        // Non-PHI def.
        const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def);
        if (!MI) {
          report("No instruction at def index", MF);
          *OS << "Valno #" << VNI->id << " is defined at " << VNI->def
              << " in " << LI << '\n';
        } else if (!MI->modifiesRegister(LI.reg, TRI)) {
          report("Defining instruction does not modify register", MI);
          *OS << "Valno #" << VNI->id << " in " << LI << '\n';
        }

        bool isEarlyClobber = false;
        if (MI) {
          for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
               MOE = MI->operands_end(); MOI != MOE; ++MOI) {
            if (MOI->isReg() && MOI->getReg() == LI.reg && MOI->isDef() &&
                MOI->isEarlyClobber()) {
              isEarlyClobber = true;
              break;
            }
          }
        }

        // Early clobber defs begin at USE slots, but other defs must begin at
        // DEF slots.
        if (isEarlyClobber) {
          if (!VNI->def.isUse()) {
            report("Early clobber def must be at a USE slot", MF);
            *OS << "Valno #" << VNI->id << " is defined at " << VNI->def
                << " in " << LI << '\n';
          }
        } else if (!VNI->def.isDef()) {
          report("Non-PHI, non-early clobber def must be at a DEF slot", MF);
          *OS << "Valno #" << VNI->id << " is defined at " << VNI->def
              << " in " << LI << '\n';
        }
      }
    }

    for (LiveInterval::const_iterator I = LI.begin(), E = LI.end(); I!=E; ++I) {
      const VNInfo *VNI = I->valno;
      assert(VNI && "Live range has no valno");

      if (VNI->id >= LI.getNumValNums() || VNI != LI.getValNumInfo(VNI->id)) {
        report("Foreign valno in live range", MF);
        I->print(*OS);
        *OS << " has a valno not in " << LI << '\n';
      }

      if (VNI->isUnused()) {
        report("Live range valno is marked unused", MF);
        I->print(*OS);
        *OS << " in " << LI << '\n';
      }

      const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(I->start);
      if (!MBB) {
        report("Bad start of live segment, no basic block", MF);
        I->print(*OS);
        *OS << " in " << LI << '\n';
        continue;
      }
      SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB);
      if (I->start != MBBStartIdx && I->start != VNI->def) {
        report("Live segment must begin at MBB entry or valno def", MBB);
        I->print(*OS);
        *OS << " in " << LI << '\n' << "Basic block starts at "
            << MBBStartIdx << '\n';
      }

      const MachineBasicBlock *EndMBB =
                                LiveInts->getMBBFromIndex(I->end.getPrevSlot());
      if (!EndMBB) {
        report("Bad end of live segment, no basic block", MF);
        I->print(*OS);
        *OS << " in " << LI << '\n';
        continue;
      }
      if (I->end != LiveInts->getMBBEndIdx(EndMBB)) {
        // The live segment is ending inside EndMBB
        const MachineInstr *MI =
                        LiveInts->getInstructionFromIndex(I->end.getPrevSlot());
        if (!MI) {
          report("Live segment doesn't end at a valid instruction", EndMBB);
        I->print(*OS);
        *OS << " in " << LI << '\n' << "Basic block starts at "
            << MBBStartIdx << '\n';
        } else if (TargetRegisterInfo::isVirtualRegister(LI.reg) &&
                   !MI->readsVirtualRegister(LI.reg)) {
          // A live range can end with either a redefinition, a kill flag on a
          // use, or a dead flag on a def.
          // FIXME: Should we check for each of these?
          bool hasDeadDef = false;
          for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
               MOE = MI->operands_end(); MOI != MOE; ++MOI) {
            if (MOI->isReg() && MOI->getReg() == LI.reg && MOI->isDef() && MOI->isDead()) {
              hasDeadDef = true;
              break;
            }
          }

          if (!hasDeadDef) {
            report("Instruction killing live segment neither defines nor reads "
                   "register", MI);
            I->print(*OS);
            *OS << " in " << LI << '\n';
          }
        }
      }

      // Now check all the basic blocks in this live segment.
      MachineFunction::const_iterator MFI = MBB;
      // Is this live range the beginning of a non-PHIDef VN?
      if (I->start == VNI->def && !VNI->isPHIDef()) {
        // Not live-in to any blocks.
        if (MBB == EndMBB)
          continue;
        // Skip this block.
        ++MFI;
      }
      for (;;) {
        assert(LiveInts->isLiveInToMBB(LI, MFI));
        // We don't know how to track physregs into a landing pad.
        if (TargetRegisterInfo::isPhysicalRegister(LI.reg) &&
            MFI->isLandingPad()) {
          if (&*MFI == EndMBB)
            break;
          ++MFI;
          continue;
        }
        // Check that VNI is live-out of all predecessors.
        for (MachineBasicBlock::const_pred_iterator PI = MFI->pred_begin(),
             PE = MFI->pred_end(); PI != PE; ++PI) {
          SlotIndex PEnd = LiveInts->getMBBEndIdx(*PI).getPrevSlot();
          const VNInfo *PVNI = LI.getVNInfoAt(PEnd);

          if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI))
            continue;

          if (!PVNI) {
            report("Register not marked live out of predecessor", *PI);
            *OS << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber()
                << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live at "
                << PEnd << " in " << LI << '\n';
            continue;
          }

          if (PVNI != VNI) {
            report("Different value live out of predecessor", *PI);
            *OS << "Valno #" << PVNI->id << " live out of BB#"
                << (*PI)->getNumber() << '@' << PEnd
                << "\nValno #" << VNI->id << " live into BB#" << MFI->getNumber()
                << '@' << LiveInts->getMBBStartIdx(MFI) << " in " << LI << '\n';
          }
        }
        if (&*MFI == EndMBB)
          break;
        ++MFI;
      }
    }

    // Check the LI only has one connected component.
    if (TargetRegisterInfo::isVirtualRegister(LI.reg)) {
      ConnectedVNInfoEqClasses ConEQ(*LiveInts);
      unsigned NumComp = ConEQ.Classify(&LI);
      if (NumComp > 1) {
        report("Multiple connected components in live interval", MF);
        *OS << NumComp << " components in " << LI << '\n';
        for (unsigned comp = 0; comp != NumComp; ++comp) {
          *OS << comp << ": valnos";
          for (LiveInterval::const_vni_iterator I = LI.vni_begin(),
               E = LI.vni_end(); I!=E; ++I)
            if (comp == ConEQ.getEqClass(*I))
              *OS << ' ' << (*I)->id;
          *OS << '\n';
        }
      }
    }
  }
}