bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
  // Shortcut: We cannot have split components with a single definition.
  if (LI.valnos.size() < 2)
    return false;

  SmallVector<SubRangeInfo, 4> SubRangeInfos;
  IntEqClasses Classes;
  if (!findComponents(Classes, SubRangeInfos, LI))
    return false;

  // Create a new VReg for each class.
  unsigned Reg = LI.reg;
  const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
  SmallVector<LiveInterval*, 4> Intervals;
  Intervals.push_back(&LI);
  DEBUG(dbgs() << PrintReg(Reg) << ": Found " << Classes.getNumClasses()
        << " equivalence classes.\n");
  DEBUG(dbgs() << PrintReg(Reg) << ": Splitting into newly created:");
  for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
       ++I) {
    unsigned NewVReg = MRI->createVirtualRegister(RegClass);
    LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
    Intervals.push_back(&NewLI);
    DEBUG(dbgs() << ' ' << PrintReg(NewVReg));
  }
  DEBUG(dbgs() << '\n');

  rewriteOperands(Classes, SubRangeInfos, Intervals);
  distribute(Classes, SubRangeInfos, Intervals);
  computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
  return true;
}
bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
    SmallVectorImpl<RenameIndependentSubregs::SubRangeInfo> &SubRangeInfos,
    LiveInterval &LI) const {
  // First step: Create connected components for the VNInfos inside the
  // subranges and count the global number of such components.
  unsigned NumComponents = 0;
  for (LiveInterval::SubRange &SR : LI.subranges()) {
    SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
    ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;

    unsigned NumSubComponents = ConEQ.Classify(SR);
    NumComponents += NumSubComponents;
  }
  // Shortcut: With only 1 subrange, the normal separate component tests are
  // enough and we do not need to perform the union-find on the subregister
  // segments.
  if (SubRangeInfos.size() < 2)
    return false;

  // Next step: Build union-find structure over all subranges and merge classes
  // across subranges when they are affected by the same MachineOperand.
  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
  Classes.grow(NumComponents);
  unsigned Reg = LI.reg;
  for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
    if (!MO.isDef() && !MO.readsReg())
      continue;
    unsigned SubRegIdx = MO.getSubReg();
    LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
    unsigned MergedID = ~0u;
    for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
      const LiveInterval::SubRange &SR = *SRInfo.SR;
      if ((SR.LaneMask & LaneMask) == 0)
        continue;
      SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
      Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
                       : Pos.getBaseIndex();
      const VNInfo *VNI = SR.getVNInfoAt(Pos);
      if (VNI == nullptr)
        continue;

      // Map to local representant ID.
      unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
      // Global ID
      unsigned ID = LocalID + SRInfo.Index;
      // Merge other sets
      MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
    }
  }

  // Early exit if we ended up with a single equivalence class.
  Classes.compress();
  unsigned NumClasses = Classes.getNumClasses();
  return NumClasses > 1;
}
void RenameIndependentSubregs::distribute(const IntEqClasses &Classes,
    const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
    const SmallVectorImpl<LiveInterval*> &Intervals) const {
  unsigned NumClasses = Classes.getNumClasses();
  SmallVector<unsigned, 8> VNIMapping;
  SmallVector<LiveInterval::SubRange*, 8> SubRanges;
  BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
  for (const SubRangeInfo &SRInfo : SubRangeInfos) {
    LiveInterval::SubRange &SR = *SRInfo.SR;
    unsigned NumValNos = SR.valnos.size();
    VNIMapping.clear();
    VNIMapping.reserve(NumValNos);
    SubRanges.clear();
    SubRanges.resize(NumClasses-1, nullptr);
    for (unsigned I = 0; I < NumValNos; ++I) {
      const VNInfo &VNI = *SR.valnos[I];
      unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
      unsigned ID = Classes[LocalID + SRInfo.Index];
      VNIMapping.push_back(ID);
      if (ID > 0 && SubRanges[ID-1] == nullptr)
        SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
    }
    DistributeRange(SR, SubRanges.data(), VNIMapping);
  }
}
Example #4
0
 /// Set each node's subtree ID to the representative ID and record connections
 /// between trees.
 void finalize() {
   SubtreeClasses.compress();
   R.SubtreeConnections.resize(SubtreeClasses.getNumClasses());
   R.SubtreeConnectLevels.resize(SubtreeClasses.getNumClasses());
   DEBUG(dbgs() << R.getNumSubtrees() << " subtrees:\n");
   for (unsigned Idx = 0, End = R.DFSData.size(); Idx != End; ++Idx) {
     R.DFSData[Idx].SubtreeID = SubtreeClasses[Idx];
     DEBUG(dbgs() << "  SU(" << Idx << ") in tree "
           << R.DFSData[Idx].SubtreeID << '\n');
   }
   for (std::vector<std::pair<const SUnit*, const SUnit*> >::const_iterator
          I = ConnectionPairs.begin(), E = ConnectionPairs.end();
        I != E; ++I) {
     unsigned PredTree = SubtreeClasses[I->first->NodeNum];
     unsigned SuccTree = SubtreeClasses[I->second->NodeNum];
     if (PredTree == SuccTree)
       continue;
     unsigned Depth = I->first->getDepth();
     addConnection(PredTree, SuccTree, Depth);
     addConnection(SuccTree, PredTree, Depth);
   }
 }
Example #5
0
 /// Determine whether the DFS cross edge should be considered a subtree edge
 /// or a connection between subtrees.
 void visitCross(const SDep &PredDep, const SUnit *Succ) {
   if (PredDep.getKind() == SDep::Data) {
     // If this is a cross edge to a root, join the subtrees. This happens when
     // the root was first reached by a non-data dependence.
     unsigned NodeNum = PredDep.getSUnit()->NodeNum;
     unsigned PredCnt = R.DFSData[NodeNum].InstrCount;
     if (R.DFSData[NodeNum].SubtreeID == NodeNum && PredCnt < R.SubtreeLimit) {
       R.DFSData[NodeNum].SubtreeID = Succ->NodeNum;
       R.DFSData[Succ->NodeNum].InstrCount += PredCnt;
       SubtreeClasses.join(Succ->NodeNum, NodeNum);
       return;
     }
   }
   ConnectionPairs.push_back(std::make_pair(PredDep.getSUnit(), Succ));
 }
Example #6
0
  /// Mark this node as either the root of a subtree or an interior
  /// node. Increment the parent node's instruction count.
  void visitPostorder(const SUnit *SU, const SDep *PredDep, const SUnit *Parent) {
    R.DFSData[SU->NodeNum].SubtreeID = SU->NodeNum;

    // Join the child to its parent if they are connected via data dependence
    // and do not exceed the limit.
    if (!Parent || PredDep->getKind() != SDep::Data)
      return;

    unsigned PredCnt = R.DFSData[SU->NodeNum].InstrCount;
    if (PredCnt > R.SubtreeLimit)
      return;

    R.DFSData[SU->NodeNum].SubtreeID = Parent->NodeNum;

    // Add the recently finished predecessor's bottom-up descendent count.
    R.DFSData[Parent->NodeNum].InstrCount += PredCnt;
    SubtreeClasses.join(Parent->NodeNum, SU->NodeNum);
  }