mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-03 14:21:30 +00:00 
			
		
		
		
	Use std::unique instead of a SmallPtrSet to ensure unique instructions in UseSlots.
This allows us to always keep the smaller slot for an instruction which is what we want when a register has early clobber defines. Drop the UsingInstrs set and the UsingBlocks map. They are no longer needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		@@ -178,6 +178,11 @@ namespace llvm {
 | 
			
		||||
      return getIndex() >= other.getIndex();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// isSameInstr - Return true if A and B refer to the same instruction.
 | 
			
		||||
    static bool isSameInstr(SlotIndex A, SlotIndex B) {
 | 
			
		||||
      return A.lie.getPointer() == B.lie.getPointer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Return the distance from this index to the given one.
 | 
			
		||||
    int distance(SlotIndex other) const {
 | 
			
		||||
      return other.getIndex() - getIndex();
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@
 | 
			
		||||
#include "llvm/CodeGen/MachineDominators.h"
 | 
			
		||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
 | 
			
		||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
 | 
			
		||||
#include "llvm/Support/CommandLine.h"
 | 
			
		||||
#include "llvm/Support/Debug.h"
 | 
			
		||||
#include "llvm/Support/raw_ostream.h"
 | 
			
		||||
#include "llvm/Target/TargetInstrInfo.h"
 | 
			
		||||
@@ -29,10 +28,6 @@
 | 
			
		||||
 | 
			
		||||
using namespace llvm;
 | 
			
		||||
 | 
			
		||||
static cl::opt<bool>
 | 
			
		||||
AllowSplit("spiller-splits-edges",
 | 
			
		||||
           cl::desc("Allow critical edge splitting during spilling"));
 | 
			
		||||
 | 
			
		||||
STATISTIC(NumFinished, "Number of splits finished");
 | 
			
		||||
STATISTIC(NumSimple,   "Number of splits that were simple");
 | 
			
		||||
 | 
			
		||||
@@ -53,8 +48,6 @@ SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm,
 | 
			
		||||
 | 
			
		||||
void SplitAnalysis::clear() {
 | 
			
		||||
  UseSlots.clear();
 | 
			
		||||
  UsingInstrs.clear();
 | 
			
		||||
  UsingBlocks.clear();
 | 
			
		||||
  LiveBlocks.clear();
 | 
			
		||||
  CurLI = 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -96,21 +89,31 @@ SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) {
 | 
			
		||||
 | 
			
		||||
/// analyzeUses - Count instructions, basic blocks, and loops using CurLI.
 | 
			
		||||
void SplitAnalysis::analyzeUses() {
 | 
			
		||||
  assert(UseSlots.empty() && "Call clear first");
 | 
			
		||||
 | 
			
		||||
  // First get all the defs from the interval values. This provides the correct
 | 
			
		||||
  // slots for early clobbers.
 | 
			
		||||
  for (LiveInterval::const_vni_iterator I = CurLI->vni_begin(),
 | 
			
		||||
       E = CurLI->vni_end(); I != E; ++I)
 | 
			
		||||
    if (!(*I)->isPHIDef() && !(*I)->isUnused())
 | 
			
		||||
      UseSlots.push_back((*I)->def);
 | 
			
		||||
 | 
			
		||||
  // Get use slots form the use-def chain.
 | 
			
		||||
  const MachineRegisterInfo &MRI = MF.getRegInfo();
 | 
			
		||||
  for (MachineRegisterInfo::reg_iterator I = MRI.reg_begin(CurLI->reg),
 | 
			
		||||
       E = MRI.reg_end(); I != E; ++I) {
 | 
			
		||||
    MachineOperand &MO = I.getOperand();
 | 
			
		||||
    if (MO.isUse() && MO.isUndef())
 | 
			
		||||
      continue;
 | 
			
		||||
    MachineInstr *MI = MO.getParent();
 | 
			
		||||
    if (MI->isDebugValue() || !UsingInstrs.insert(MI))
 | 
			
		||||
      continue;
 | 
			
		||||
    UseSlots.push_back(LIS.getInstructionIndex(MI).getDefIndex());
 | 
			
		||||
    MachineBasicBlock *MBB = MI->getParent();
 | 
			
		||||
    UsingBlocks[MBB]++;
 | 
			
		||||
  }
 | 
			
		||||
  for (MachineRegisterInfo::use_nodbg_iterator
 | 
			
		||||
       I = MRI.use_nodbg_begin(CurLI->reg), E = MRI.use_nodbg_end(); I != E;
 | 
			
		||||
       ++I)
 | 
			
		||||
    if (!I.getOperand().isUndef())
 | 
			
		||||
      UseSlots.push_back(LIS.getInstructionIndex(&*I).getDefIndex());
 | 
			
		||||
 | 
			
		||||
  array_pod_sort(UseSlots.begin(), UseSlots.end());
 | 
			
		||||
 | 
			
		||||
  // Remove duplicates, keeping the smaller slot for each instruction.
 | 
			
		||||
  // That is what we want for early clobbers.
 | 
			
		||||
  UseSlots.erase(std::unique(UseSlots.begin(), UseSlots.end(),
 | 
			
		||||
                             SlotIndex::isSameInstr),
 | 
			
		||||
                 UseSlots.end());
 | 
			
		||||
 | 
			
		||||
  // Compute per-live block info.
 | 
			
		||||
  if (!calcLiveBlockInfo()) {
 | 
			
		||||
    // FIXME: calcLiveBlockInfo found inconsistencies in the live range.
 | 
			
		||||
@@ -125,8 +128,7 @@ void SplitAnalysis::analyzeUses() {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DEBUG(dbgs() << "Analyze counted "
 | 
			
		||||
               << UsingInstrs.size() << " instrs, "
 | 
			
		||||
               << UsingBlocks.size() << " blocks, "
 | 
			
		||||
               << UseSlots.size() << " instrs, "
 | 
			
		||||
               << LiveBlocks.size() << " spanned.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -157,8 +159,8 @@ bool SplitAnalysis::calcLiveBlockInfo() {
 | 
			
		||||
      BI.Def = LVI->start;
 | 
			
		||||
 | 
			
		||||
    // Find the first and last uses in the block.
 | 
			
		||||
    BI.Uses = hasUses(MFI);
 | 
			
		||||
    if (BI.Uses && UseI != UseE) {
 | 
			
		||||
    BI.Uses = UseI != UseE && *UseI < Stop;
 | 
			
		||||
    if (BI.Uses) {
 | 
			
		||||
      BI.FirstUse = *UseI;
 | 
			
		||||
      assert(BI.FirstUse >= Start);
 | 
			
		||||
      do ++UseI;
 | 
			
		||||
@@ -224,15 +226,6 @@ bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const {
 | 
			
		||||
  return I != Orig.begin() && (--I)->end == Idx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SplitAnalysis::print(const BlockPtrSet &B, raw_ostream &OS) const {
 | 
			
		||||
  for (BlockPtrSet::const_iterator I = B.begin(), E = B.end(); I != E; ++I) {
 | 
			
		||||
    unsigned count = UsingBlocks.lookup(*I);
 | 
			
		||||
    OS << " BB#" << (*I)->getNumber();
 | 
			
		||||
    if (count)
 | 
			
		||||
      OS << '(' << count << ')';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SplitAnalysis::analyze(const LiveInterval *li) {
 | 
			
		||||
  clear();
 | 
			
		||||
  CurLI = li;
 | 
			
		||||
@@ -918,12 +911,7 @@ bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
 | 
			
		||||
  // Add blocks with multiple uses.
 | 
			
		||||
  for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
 | 
			
		||||
    const BlockInfo &BI = LiveBlocks[i];
 | 
			
		||||
    if (!BI.Uses)
 | 
			
		||||
      continue;
 | 
			
		||||
    unsigned Instrs = UsingBlocks.lookup(BI.MBB);
 | 
			
		||||
    if (Instrs <= 1)
 | 
			
		||||
      continue;
 | 
			
		||||
    if (Instrs == 2 && BI.LiveIn && BI.LiveOut && !BI.LiveThrough)
 | 
			
		||||
    if (!BI.Uses || BI.FirstUse == BI.LastUse)
 | 
			
		||||
      continue;
 | 
			
		||||
    Blocks.insert(BI.MBB);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -50,17 +50,9 @@ public:
 | 
			
		||||
  const MachineLoopInfo &Loops;
 | 
			
		||||
  const TargetInstrInfo &TII;
 | 
			
		||||
 | 
			
		||||
  // Instructions using the the current register.
 | 
			
		||||
  typedef SmallPtrSet<const MachineInstr*, 16> InstrPtrSet;
 | 
			
		||||
  InstrPtrSet UsingInstrs;
 | 
			
		||||
 | 
			
		||||
  // Sorted slot indexes of using instructions.
 | 
			
		||||
  SmallVector<SlotIndex, 8> UseSlots;
 | 
			
		||||
 | 
			
		||||
  // The number of instructions using CurLI in each basic block.
 | 
			
		||||
  typedef DenseMap<const MachineBasicBlock*, unsigned> BlockCountMap;
 | 
			
		||||
  BlockCountMap UsingBlocks;
 | 
			
		||||
 | 
			
		||||
  /// Additional information about basic blocks where the current variable is
 | 
			
		||||
  /// live. Such a block will look like one of these templates:
 | 
			
		||||
  ///
 | 
			
		||||
@@ -130,11 +122,6 @@ public:
 | 
			
		||||
    return computeLastSplitPoint(Num);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// hasUses - Return true if MBB has any uses of CurLI.
 | 
			
		||||
  bool hasUses(const MachineBasicBlock *MBB) const {
 | 
			
		||||
    return UsingBlocks.lookup(MBB);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// isOriginalEndpoint - Return true if the original live range was killed or
 | 
			
		||||
  /// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def,
 | 
			
		||||
  /// and 'use' for an early-clobber def.
 | 
			
		||||
@@ -144,9 +131,6 @@ public:
 | 
			
		||||
 | 
			
		||||
  typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet;
 | 
			
		||||
 | 
			
		||||
  // Print a set of blocks with use counts.
 | 
			
		||||
  void print(const BlockPtrSet&, raw_ostream&) const;
 | 
			
		||||
 | 
			
		||||
  /// getMultiUseBlocks - Add basic blocks to Blocks that may benefit from
 | 
			
		||||
  /// having CurLI split to a new live interval. Return true if Blocks can be
 | 
			
		||||
  /// passed to SplitEditor::splitSingleBlocks.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user