Exemple #1
0
void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X,
                              DefUseInfoMap &DUM) {
    unsigned Index = 0;
    unsigned NR = HRI->getNumRegs();
    BitVector Defs(NR), Uses(NR);

    for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) {
        MachineInstr *MI = &*I;
        I2X.insert(std::make_pair(MI, Index));
        Defs.reset();
        Uses.reset();
        getDefsUses(MI, Defs, Uses);
        DUM.insert(std::make_pair(Index, DefUseInfo(Defs, Uses)));
        Index++;
    }
}
HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeDeadMap(
      InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) {
  RegToRangeMap DeadMap;

  auto addDeadRanges = [&IndexMap,&LiveMap,&DeadMap] (RegisterRef R) -> void {
    auto F = LiveMap.find(R);
    if (F == LiveMap.end() || F->second.empty()) {
      DeadMap[R].add(IndexType::Entry, IndexType::Exit, false, false);
      return;
    }

    RangeList &RL = F->second;
    RangeList::iterator A = RL.begin(), Z = RL.end()-1;

    // Try to create the initial range.
    if (A->start() != IndexType::Entry) {
      IndexType DE = IndexMap.getPrevIndex(A->start());
      if (DE != IndexType::Entry)
        DeadMap[R].add(IndexType::Entry, DE, false, false);
    }

    while (A != Z) {
      // Creating a dead range that follows A.  Pay attention to empty
      // ranges (i.e. those ending with "None").
      IndexType AE = (A->end() == IndexType::None) ? A->start() : A->end();
      IndexType DS = IndexMap.getNextIndex(AE);
      ++A;
      IndexType DE = IndexMap.getPrevIndex(A->start());
      if (DS < DE)
        DeadMap[R].add(DS, DE, false, false);
    }

    // Try to create the final range.
    if (Z->end() != IndexType::Exit) {
      IndexType ZE = (Z->end() == IndexType::None) ? Z->start() : Z->end();
      IndexType DS = IndexMap.getNextIndex(ZE);
      if (DS < IndexType::Exit)
        DeadMap[R].add(DS, IndexType::Exit, false, false);
    }
  };

  MachineFunction &MF = *IndexMap.getBlock().getParent();
  auto &MRI = MF.getRegInfo();
  unsigned NumRegs = TRI.getNumRegs();
  BitVector Visited(NumRegs);
  for (unsigned R = 1; R < NumRegs; ++R) {
    for (auto S : expandToSubRegs({R,0}, MRI, TRI)) {
      if (Reserved[S.Reg] || Visited[S.Reg])
        continue;
      addDeadRanges(S);
      Visited[S.Reg] = true;
    }
  }
  for (auto &P : LiveMap)
    if (TargetRegisterInfo::isVirtualRegister(P.first.Reg))
      addDeadRanges(P.first);

  LLVM_DEBUG(dbgs() << __func__ << ": dead map\n"
                    << PrintRangeMap(DeadMap, TRI) << '\n');
  return DeadMap;
}
void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
      RegToRangeMap &LiveMap) {
  std::map<RegisterRef,IndexType> LastDef, LastUse;
  RegisterSet LiveOnEntry;
  MachineBasicBlock &B = IndexMap.getBlock();
  MachineRegisterInfo &MRI = B.getParent()->getRegInfo();

  for (auto R : getLiveIns(B, MRI, TRI))
    LiveOnEntry.insert(R);

  for (auto R : LiveOnEntry)
    LastDef[R] = IndexType::Entry;

  auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) -> void {
    auto LD = LastDef[R], LU = LastUse[R];
    if (LD == IndexType::None)
      LD = IndexType::Entry;
    if (LU == IndexType::None)
      LU = IndexType::Exit;
    LiveMap[R].add(LD, LU, false, false);
    LastUse[R] = LastDef[R] = IndexType::None;
  };

  RegisterSet Defs, Clobbers;

  for (auto &In : B) {
    if (In.isDebugInstr())
      continue;
    IndexType Index = IndexMap.getIndex(&In);
    // Process uses first.
    for (auto &Op : In.operands()) {
      if (!Op.isReg() || !Op.isUse() || Op.isUndef())
        continue;
      RegisterRef R = { Op.getReg(), Op.getSubReg() };
      if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg])
        continue;
      bool IsKill = Op.isKill();
      for (auto S : expandToSubRegs(R, MRI, TRI)) {
        LastUse[S] = Index;
        if (IsKill)
          closeRange(S);
      }
    }
    // Process defs and clobbers.
    Defs.clear();
    Clobbers.clear();
    for (auto &Op : In.operands()) {
      if (!Op.isReg() || !Op.isDef() || Op.isUndef())
        continue;
      RegisterRef R = { Op.getReg(), Op.getSubReg() };
      for (auto S : expandToSubRegs(R, MRI, TRI)) {
        if (TargetRegisterInfo::isPhysicalRegister(S.Reg) && Reserved[S.Reg])
          continue;
        if (Op.isDead())
          Clobbers.insert(S);
        else
          Defs.insert(S);
      }
    }

    for (auto &Op : In.operands()) {
      if (!Op.isRegMask())
        continue;
      const uint32_t *BM = Op.getRegMask();
      for (unsigned PR = 1, N = TRI.getNumRegs(); PR != N; ++PR) {
        // Skip registers that have subregisters. A register is preserved
        // iff its bit is set in the regmask, so if R1:0 was preserved, both
        // R1 and R0 would also be present.
        if (MCSubRegIterator(PR, &TRI, false).isValid())
          continue;
        if (Reserved[PR])
          continue;
        if (BM[PR/32] & (1u << (PR%32)))
          continue;
        RegisterRef R = { PR, 0 };
        if (!Defs.count(R))
          Clobbers.insert(R);
      }
    }
    // Defs and clobbers can overlap, e.g.
    // dead %d0 = COPY %5, implicit-def %r0, implicit-def %r1
    for (RegisterRef R : Defs)
      Clobbers.erase(R);

    // Update maps for defs.
    for (RegisterRef S : Defs) {
      // Defs should already be expanded into subregs.
      assert(!TargetRegisterInfo::isPhysicalRegister(S.Reg) ||
             !MCSubRegIterator(S.Reg, &TRI, false).isValid());
      if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None)
        closeRange(S);
      LastDef[S] = Index;
    }
    // Update maps for clobbers.
    for (RegisterRef S : Clobbers) {
      // Clobbers should already be expanded into subregs.
      assert(!TargetRegisterInfo::isPhysicalRegister(S.Reg) ||
             !MCSubRegIterator(S.Reg, &TRI, false).isValid());
      if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None)
        closeRange(S);
      // Create a single-instruction range.
      LastDef[S] = LastUse[S] = Index;
      closeRange(S);
    }
  }

  // Collect live-on-exit.
  RegisterSet LiveOnExit;
  for (auto *SB : B.successors())
    for (auto R : getLiveIns(*SB, MRI, TRI))
      LiveOnExit.insert(R);

  for (auto R : LiveOnExit)
    LastUse[R] = IndexType::Exit;

  // Process remaining registers.
  RegisterSet Left;
  for (auto &I : LastUse)
    if (I.second != IndexType::None)
      Left.insert(I.first);
  for (auto &I : LastDef)
    if (I.second != IndexType::None)
      Left.insert(I.first);
  for (auto R : Left)
    closeRange(R);

  // Finalize the live ranges.
  for (auto &P : LiveMap)
    P.second.unionize();
}
Exemple #4
0
void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
      RegToRangeMap &LiveMap) {
  std::map<RegisterRef,IndexType> LastDef, LastUse;
  RegisterSet LiveOnEntry;
  MachineBasicBlock &B = IndexMap.getBlock();
  MachineRegisterInfo &MRI = B.getParent()->getRegInfo();

  for (auto R : getLiveIns(B))
    for (auto S : expandToSubRegs(R, MRI, TRI))
      LiveOnEntry.insert(S);

  for (auto R : LiveOnEntry)
    LastDef[R] = IndexType::Entry;

  auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) -> void {
    auto LD = LastDef[R], LU = LastUse[R];
    if (LD == IndexType::None)
      LD = IndexType::Entry;
    if (LU == IndexType::None)
      LU = IndexType::Exit;
    LiveMap[R].add(LD, LU, false, false);
    LastUse[R] = LastDef[R] = IndexType::None;
  };

  for (auto &In : B) {
    if (In.isDebugValue())
      continue;
    IndexType Index = IndexMap.getIndex(&In);
    // Process uses first.
    for (auto &Op : In.operands()) {
      if (!Op.isReg() || !Op.isUse() || Op.isUndef())
        continue;
      RegisterRef R = { Op.getReg(), Op.getSubReg() };
      if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg])
        continue;
      bool IsKill = Op.isKill();
      for (auto S : expandToSubRegs(R, MRI, TRI)) {
        LastUse[S] = Index;
        if (IsKill)
          closeRange(S);
      }
    }
    // Process defs.
    for (auto &Op : In.operands()) {
      if (!Op.isReg() || !Op.isDef() || Op.isUndef())
        continue;
      RegisterRef R = { Op.getReg(), Op.getSubReg() };
      if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg])
        continue;
      for (auto S : expandToSubRegs(R, MRI, TRI)) {
        if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None)
          closeRange(S);
        LastDef[S] = Index;
      }
    }
  }

  // Collect live-on-exit.
  RegisterSet LiveOnExit;
  for (auto *SB : B.successors())
    for (auto R : getLiveIns(*SB))
      for (auto S : expandToSubRegs(R, MRI, TRI))
        LiveOnExit.insert(S);

  for (auto R : LiveOnExit)
    LastUse[R] = IndexType::Exit;

  // Process remaining registers.
  RegisterSet Left;
  for (auto &I : LastUse)
    if (I.second != IndexType::None)
      Left.insert(I.first);
  for (auto &I : LastDef)
    if (I.second != IndexType::None)
      Left.insert(I.first);
  for (auto R : Left)
    closeRange(R);

  // Finalize the live ranges.
  for (auto &P : LiveMap)
    P.second.unionize();
}