SlotIndexes.cpp revision b3661585c0f87b6045f0d65b5cac16921ae27086
1233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames//===-- SlotIndexes.cpp - Slot Indexes Pass  ------------------------------===//
2233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames//
3233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames//                     The LLVM Compiler Infrastructure
4233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames//
5233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames// This file is distributed under the University of Illinois Open Source
6233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames// License. See LICENSE.TXT for details.
7233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames//
8233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames//===----------------------------------------------------------------------===//
9233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
10233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames#define DEBUG_TYPE "slotindexes"
11233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
12233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames#include "llvm/CodeGen/SlotIndexes.h"
13233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames#include "llvm/CodeGen/MachineFunction.h"
14233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames#include "llvm/Support/Debug.h"
15233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames#include "llvm/Support/raw_ostream.h"
1616dcaf59960d699735a57b1623092d561c18a165Lang Hames#include "llvm/Support/ManagedStatic.h"
17233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
18233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesusing namespace llvm;
19233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
20d6ef7fac1a020c58ec61cad2325e5f6afd0bbee6Lang Hames
21d6ef7fac1a020c58ec61cad2325e5f6afd0bbee6Lang Hames// Yep - these are thread safe. See the header for details.
2216dcaf59960d699735a57b1623092d561c18a165Lang Hamesnamespace {
2316dcaf59960d699735a57b1623092d561c18a165Lang Hames
2416dcaf59960d699735a57b1623092d561c18a165Lang Hames
2516dcaf59960d699735a57b1623092d561c18a165Lang Hames  class EmptyIndexListEntry : public IndexListEntry {
2616dcaf59960d699735a57b1623092d561c18a165Lang Hames  public:
2716dcaf59960d699735a57b1623092d561c18a165Lang Hames    EmptyIndexListEntry() : IndexListEntry(EMPTY_KEY) {}
2816dcaf59960d699735a57b1623092d561c18a165Lang Hames  };
2916dcaf59960d699735a57b1623092d561c18a165Lang Hames
3016dcaf59960d699735a57b1623092d561c18a165Lang Hames  class TombstoneIndexListEntry : public IndexListEntry {
3116dcaf59960d699735a57b1623092d561c18a165Lang Hames  public:
3216dcaf59960d699735a57b1623092d561c18a165Lang Hames    TombstoneIndexListEntry() : IndexListEntry(TOMBSTONE_KEY) {}
3316dcaf59960d699735a57b1623092d561c18a165Lang Hames  };
3416dcaf59960d699735a57b1623092d561c18a165Lang Hames
3516dcaf59960d699735a57b1623092d561c18a165Lang Hames  // The following statics are thread safe. They're read only, and you
3616dcaf59960d699735a57b1623092d561c18a165Lang Hames  // can't step from them to any other list entries.
3716dcaf59960d699735a57b1623092d561c18a165Lang Hames  ManagedStatic<EmptyIndexListEntry> IndexListEntryEmptyKey;
3816dcaf59960d699735a57b1623092d561c18a165Lang Hames  ManagedStatic<TombstoneIndexListEntry> IndexListEntryTombstoneKey;
3916dcaf59960d699735a57b1623092d561c18a165Lang Hames}
40233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
41233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hameschar SlotIndexes::ID = 0;
42233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesstatic RegisterPass<SlotIndexes> X("slotindexes", "Slot index numbering");
43233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
4416dcaf59960d699735a57b1623092d561c18a165Lang HamesIndexListEntry* IndexListEntry::getEmptyKeyEntry() {
4516dcaf59960d699735a57b1623092d561c18a165Lang Hames  return &*IndexListEntryEmptyKey;
4616dcaf59960d699735a57b1623092d561c18a165Lang Hames}
4716dcaf59960d699735a57b1623092d561c18a165Lang Hames
4816dcaf59960d699735a57b1623092d561c18a165Lang HamesIndexListEntry* IndexListEntry::getTombstoneKeyEntry() {
4916dcaf59960d699735a57b1623092d561c18a165Lang Hames  return &*IndexListEntryTombstoneKey;
5016dcaf59960d699735a57b1623092d561c18a165Lang Hames}
5116dcaf59960d699735a57b1623092d561c18a165Lang Hames
5216dcaf59960d699735a57b1623092d561c18a165Lang Hames
53233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesvoid SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const {
54233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  au.setPreservesAll();
55233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  MachineFunctionPass::getAnalysisUsage(au);
56233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
57233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
58233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesvoid SlotIndexes::releaseMemory() {
59233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  mi2iMap.clear();
60233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  mbb2IdxMap.clear();
61233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  idx2MBBMap.clear();
62233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  terminatorGaps.clear();
63233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  clearList();
64233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
65233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
66233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesbool SlotIndexes::runOnMachineFunction(MachineFunction &fn) {
67233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
68233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // Compute numbering as follows:
69233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // Grab an iterator to the start of the index list.
70233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // Iterate over all MBBs, and within each MBB all MIs, keeping the MI
71233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // iterator in lock-step (though skipping it over indexes which have
72233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // null pointers in the instruction field).
73233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // At each iteration assert that the instruction pointed to in the index
74233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // is the same one pointed to by the MI iterator. This
75233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
76233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should
77233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // only need to be set up once after the first numbering is computed.
78233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
79233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  mf = &fn;
80233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  initList();
81233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
82233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // Check that the list contains only the sentinal.
83233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  assert(indexListHead->getNext() == 0 &&
84233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames         "Index list non-empty at initial numbering?");
85233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  assert(idx2MBBMap.empty() &&
86233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames         "Index -> MBB mapping non-empty at initial numbering?");
87233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  assert(mbb2IdxMap.empty() &&
88233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames         "MBB -> Index mapping non-empty at initial numbering?");
89233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  assert(mi2iMap.empty() &&
90233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames         "MachineInstr -> Index mapping non-empty at initial numbering?");
91233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
92233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  functionSize = 0;
93233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  unsigned index = 0;
94233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
95233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // Iterate over the the function.
96233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  for (MachineFunction::iterator mbbItr = mf->begin(), mbbEnd = mf->end();
97233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames       mbbItr != mbbEnd; ++mbbItr) {
98233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    MachineBasicBlock *mbb = &*mbbItr;
99233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
100233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    // Insert an index for the MBB start.
101233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    push_back(createEntry(0, index));
102233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    SlotIndex blockStartIndex(back(), SlotIndex::LOAD);
103233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
104fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames    index += SlotIndex::NUM;
105233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
106233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end();
107233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames         miItr != miEnd; ++miItr) {
108233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      MachineInstr *mi = &*miItr;
109233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
110233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      if (miItr == mbb->getFirstTerminator()) {
111233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames        push_back(createEntry(0, index));
112233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames        terminatorGaps.insert(
113233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames          std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT)));
114fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames        index += SlotIndex::NUM;
115233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      }
116233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
117233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      // Insert a store index for the instr.
118233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      push_back(createEntry(mi, index));
119233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
120233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      // Save this base index in the maps.
121233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      mi2iMap.insert(
122233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames        std::make_pair(mi, SlotIndex(back(), SlotIndex::LOAD)));
123233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
124233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      ++functionSize;
125233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
126233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      unsigned Slots = mi->getDesc().getNumDefs();
127233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      if (Slots == 0)
128233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames        Slots = 1;
129233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
130fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      index += (Slots + 1) * SlotIndex::NUM;
131233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    }
132233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
133233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    if (mbb->getFirstTerminator() == mbb->end()) {
134233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      push_back(createEntry(0, index));
135233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      terminatorGaps.insert(
136233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames        std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT)));
137fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      index += SlotIndex::NUM;
138233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    }
139233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
140233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    SlotIndex blockEndIndex(back(), SlotIndex::STORE);
141233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    mbb2IdxMap.insert(
142233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      std::make_pair(mbb, std::make_pair(blockStartIndex, blockEndIndex)));
143233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
144233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, mbb));
145233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  }
146233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
147233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // One blank instruction at the end.
148233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  push_back(createEntry(0, index));
149233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
150233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // Sort the Idx2MBBMap
151233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
152233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
153233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  DEBUG(dump());
154233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
155233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  // And we're done!
156233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  return false;
157233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
158233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
159b3661585c0f87b6045f0d65b5cac16921ae27086Lang Hamesvoid SlotIndexes::renumberIndexes() {
160233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
161fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  // Renumber updates the index of every element of the index list.
162fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  // If all instrs in the function have been allocated an index (which has been
163fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  // placed in the index list in the order of instruction iteration) then the
164fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  // resulting numbering will match what would have been generated by the
165fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  // pass during the initial numbering of the function if the new instructions
166fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  // had been present.
167233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
168fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  functionSize = 0;
169fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  unsigned index = 0;
170fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames
171fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  for (IndexListEntry *curEntry = front(); curEntry != getTail();
172fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames       curEntry = curEntry->getNext()) {
173fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames
174fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames    curEntry->setIndex(index);
175fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames
176fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames    if (curEntry->getInstr() == 0) {
177fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      // MBB start entry or terminator gap. Just step index by 1.
178fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      index += SlotIndex::NUM;
179fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames    }
180fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames    else {
181fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      ++functionSize;
182fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      unsigned Slots = curEntry->getInstr()->getDesc().getNumDefs();
183fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      if (Slots == 0)
184fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames        Slots = 1;
185233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
186fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames      index += (Slots + 1) * SlotIndex::NUM;
187fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames    }
188fbb8fa247ec13067d9ad3f0c426e2029d15222b2Lang Hames  }
189233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
190233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
191233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesvoid SlotIndexes::dump() const {
192233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  for (const IndexListEntry *itr = front(); itr != getTail();
193233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames       itr = itr->getNext()) {
194233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    errs() << itr->getIndex() << " ";
195233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
196233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    if (itr->getInstr() != 0) {
197233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      errs() << *itr->getInstr();
198233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    } else {
199233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames      errs() << "\n";
200233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    }
201233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  }
202233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
20381cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin  for (MBB2IdxMap::const_iterator itr = mbb2IdxMap.begin();
204233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames       itr != mbb2IdxMap.end(); ++itr) {
205233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    errs() << "MBB " << itr->first->getNumber() << " (" << itr->first << ") - ["
206233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames           << itr->second.first << ", " << itr->second.second << "]\n";
207233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  }
208233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
209233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
210233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames// Print a SlotIndex to a raw_ostream.
211233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesvoid SlotIndex::print(raw_ostream &os) const {
212233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  os << getIndex();
213233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  if (isPHI())
214233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames    os << "*";
215233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
216233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
217233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames// Dump a SlotIndex to stderr.
218233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hamesvoid SlotIndex::dump() const {
219233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  print(errs());
220233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames  errs() << "\n";
221233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames}
222233a60ec40b41027ff429e2f2c27fa2be762f2e9Lang Hames
223