Avoid looking at stale data in verifyAnalysis().
[oota-llvm.git] / lib / CodeGen / MachineTraceMetrics.cpp
1 //===- lib/CodeGen/MachineTraceMetrics.cpp ----------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #define DEBUG_TYPE "early-ifcvt"
11 #include "MachineTraceMetrics.h"
12 #include "llvm/CodeGen/MachineBasicBlock.h"
13 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
14 #include "llvm/CodeGen/MachineLoopInfo.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/CodeGen/Passes.h"
17 #include "llvm/Target/TargetInstrInfo.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/ADT/PostOrderIterator.h"
22
23 using namespace llvm;
24
25 char MachineTraceMetrics::ID = 0;
26 char &llvm::MachineTraceMetricsID = MachineTraceMetrics::ID;
27
28 INITIALIZE_PASS_BEGIN(MachineTraceMetrics,
29                   "machine-trace-metrics", "Machine Trace Metrics", false, true)
30 INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
31 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
32 INITIALIZE_PASS_END(MachineTraceMetrics,
33                   "machine-trace-metrics", "Machine Trace Metrics", false, true)
34
35 MachineTraceMetrics::MachineTraceMetrics()
36   : MachineFunctionPass(ID), MF(0), TII(0), TRI(0), MRI(0), Loops(0) {
37   std::fill(Ensembles, array_endof(Ensembles), (Ensemble*)0);
38 }
39
40 void MachineTraceMetrics::getAnalysisUsage(AnalysisUsage &AU) const {
41   AU.setPreservesAll();
42   AU.addRequired<MachineBranchProbabilityInfo>();
43   AU.addRequired<MachineLoopInfo>();
44   MachineFunctionPass::getAnalysisUsage(AU);
45 }
46
47 bool MachineTraceMetrics::runOnMachineFunction(MachineFunction &Func) {
48   MF = &Func;
49   TII = MF->getTarget().getInstrInfo();
50   TRI = MF->getTarget().getRegisterInfo();
51   MRI = &MF->getRegInfo();
52   Loops = &getAnalysis<MachineLoopInfo>();
53   BlockInfo.resize(MF->getNumBlockIDs());
54   return false;
55 }
56
57 void MachineTraceMetrics::releaseMemory() {
58   MF = 0;
59   BlockInfo.clear();
60   for (unsigned i = 0; i != TS_NumStrategies; ++i) {
61     delete Ensembles[i];
62     Ensembles[i] = 0;
63   }
64 }
65
66 //===----------------------------------------------------------------------===//
67 //                          Fixed block information
68 //===----------------------------------------------------------------------===//
69 //
70 // The number of instructions in a basic block and the CPU resources used by
71 // those instructions don't depend on any given trace strategy.
72
73 /// Compute the resource usage in basic block MBB.
74 const MachineTraceMetrics::FixedBlockInfo*
75 MachineTraceMetrics::getResources(const MachineBasicBlock *MBB) {
76   assert(MBB && "No basic block");
77   FixedBlockInfo *FBI = &BlockInfo[MBB->getNumber()];
78   if (FBI->hasResources())
79     return FBI;
80
81   // Compute resource usage in the block.
82   // FIXME: Compute per-functional unit counts.
83   FBI->HasCalls = false;
84   unsigned InstrCount = 0;
85   for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
86        I != E; ++I) {
87     const MachineInstr *MI = I;
88     if (MI->isTransient())
89       continue;
90     ++InstrCount;
91     if (MI->isCall())
92       FBI->HasCalls = true;
93   }
94   FBI->InstrCount = InstrCount;
95   return FBI;
96 }
97
98 //===----------------------------------------------------------------------===//
99 //                         Ensemble utility functions
100 //===----------------------------------------------------------------------===//
101
102 MachineTraceMetrics::Ensemble::Ensemble(MachineTraceMetrics *ct)
103   : CT(*ct) {
104   BlockInfo.resize(CT.BlockInfo.size());
105 }
106
107 // Virtual destructor serves as an anchor.
108 MachineTraceMetrics::Ensemble::~Ensemble() {}
109
110 const MachineLoop*
111 MachineTraceMetrics::Ensemble::getLoopFor(const MachineBasicBlock *MBB) const {
112   return CT.Loops->getLoopFor(MBB);
113 }
114
115 // Update resource-related information in the TraceBlockInfo for MBB.
116 // Only update resources related to the trace above MBB.
117 void MachineTraceMetrics::Ensemble::
118 computeDepthResources(const MachineBasicBlock *MBB) {
119   TraceBlockInfo *TBI = &BlockInfo[MBB->getNumber()];
120
121   // Compute resources from trace above. The top block is simple.
122   if (!TBI->Pred) {
123     TBI->InstrDepth = 0;
124     TBI->Head = MBB->getNumber();
125     return;
126   }
127
128   // Compute from the block above. A post-order traversal ensures the
129   // predecessor is always computed first.
130   TraceBlockInfo *PredTBI = &BlockInfo[TBI->Pred->getNumber()];
131   assert(PredTBI->hasValidDepth() && "Trace above has not been computed yet");
132   const FixedBlockInfo *PredFBI = CT.getResources(TBI->Pred);
133   TBI->InstrDepth = PredTBI->InstrDepth + PredFBI->InstrCount;
134   TBI->Head = PredTBI->Head;
135 }
136
137 // Update resource-related information in the TraceBlockInfo for MBB.
138 // Only update resources related to the trace below MBB.
139 void MachineTraceMetrics::Ensemble::
140 computeHeightResources(const MachineBasicBlock *MBB) {
141   TraceBlockInfo *TBI = &BlockInfo[MBB->getNumber()];
142
143   // Compute resources for the current block.
144   TBI->InstrHeight = CT.getResources(MBB)->InstrCount;
145
146   // The trace tail is done.
147   if (!TBI->Succ) {
148     TBI->Tail = MBB->getNumber();
149     return;
150   }
151
152   // Compute from the block below. A post-order traversal ensures the
153   // predecessor is always computed first.
154   TraceBlockInfo *SuccTBI = &BlockInfo[TBI->Succ->getNumber()];
155   assert(SuccTBI->hasValidHeight() && "Trace below has not been computed yet");
156   TBI->InstrHeight += SuccTBI->InstrHeight;
157   TBI->Tail = SuccTBI->Tail;
158 }
159
160 // Check if depth resources for MBB are valid and return the TBI.
161 // Return NULL if the resources have been invalidated.
162 const MachineTraceMetrics::TraceBlockInfo*
163 MachineTraceMetrics::Ensemble::
164 getDepthResources(const MachineBasicBlock *MBB) const {
165   const TraceBlockInfo *TBI = &BlockInfo[MBB->getNumber()];
166   return TBI->hasValidDepth() ? TBI : 0;
167 }
168
169 // Check if height resources for MBB are valid and return the TBI.
170 // Return NULL if the resources have been invalidated.
171 const MachineTraceMetrics::TraceBlockInfo*
172 MachineTraceMetrics::Ensemble::
173 getHeightResources(const MachineBasicBlock *MBB) const {
174   const TraceBlockInfo *TBI = &BlockInfo[MBB->getNumber()];
175   return TBI->hasValidHeight() ? TBI : 0;
176 }
177
178 //===----------------------------------------------------------------------===//
179 //                         Trace Selection Strategies
180 //===----------------------------------------------------------------------===//
181 //
182 // A trace selection strategy is implemented as a sub-class of Ensemble. The
183 // trace through a block B is computed by two DFS traversals of the CFG
184 // starting from B. One upwards, and one downwards. During the upwards DFS,
185 // pickTracePred() is called on the post-ordered blocks. During the downwards
186 // DFS, pickTraceSucc() is called in a post-order.
187 //
188
189 // We never allow traces that leave loops, but we do allow traces to enter
190 // nested loops. We also never allow traces to contain back-edges.
191 //
192 // This means that a loop header can never appear above the center block of a
193 // trace, except as the trace head. Below the center block, loop exiting edges
194 // are banned.
195 //
196 // Return true if an edge from the From loop to the To loop is leaving a loop.
197 // Either of To and From can be null.
198 static bool isExitingLoop(const MachineLoop *From, const MachineLoop *To) {
199   return From && !From->contains(To);
200 }
201
202 // MinInstrCountEnsemble - Pick the trace that executes the least number of
203 // instructions.
204 namespace {
205 class MinInstrCountEnsemble : public MachineTraceMetrics::Ensemble {
206   const char *getName() const { return "MinInstr"; }
207   const MachineBasicBlock *pickTracePred(const MachineBasicBlock*);
208   const MachineBasicBlock *pickTraceSucc(const MachineBasicBlock*);
209
210 public:
211   MinInstrCountEnsemble(MachineTraceMetrics *ct)
212     : MachineTraceMetrics::Ensemble(ct) {}
213 };
214 }
215
216 // Select the preferred predecessor for MBB.
217 const MachineBasicBlock*
218 MinInstrCountEnsemble::pickTracePred(const MachineBasicBlock *MBB) {
219   if (MBB->pred_empty())
220     return 0;
221   const MachineLoop *CurLoop = getLoopFor(MBB);
222   // Don't leave loops, and never follow back-edges.
223   if (CurLoop && MBB == CurLoop->getHeader())
224     return 0;
225   unsigned CurCount = CT.getResources(MBB)->InstrCount;
226   const MachineBasicBlock *Best = 0;
227   unsigned BestDepth = 0;
228   for (MachineBasicBlock::const_pred_iterator
229        I = MBB->pred_begin(), E = MBB->pred_end(); I != E; ++I) {
230     const MachineBasicBlock *Pred = *I;
231     const MachineTraceMetrics::TraceBlockInfo *PredTBI =
232       getDepthResources(Pred);
233     assert(PredTBI && "Predecessor must be visited first");
234     // Pick the predecessor that would give this block the smallest InstrDepth.
235     unsigned Depth = PredTBI->InstrDepth + CurCount;
236     if (!Best || Depth < BestDepth)
237       Best = Pred, BestDepth = Depth;
238   }
239   return Best;
240 }
241
242 // Select the preferred successor for MBB.
243 const MachineBasicBlock*
244 MinInstrCountEnsemble::pickTraceSucc(const MachineBasicBlock *MBB) {
245   if (MBB->pred_empty())
246     return 0;
247   const MachineLoop *CurLoop = getLoopFor(MBB);
248   const MachineBasicBlock *Best = 0;
249   unsigned BestHeight = 0;
250   for (MachineBasicBlock::const_succ_iterator
251        I = MBB->succ_begin(), E = MBB->succ_end(); I != E; ++I) {
252     const MachineBasicBlock *Succ = *I;
253     // Don't consider back-edges.
254     if (CurLoop && Succ == CurLoop->getHeader())
255       continue;
256     // Don't consider successors exiting CurLoop.
257     if (isExitingLoop(CurLoop, getLoopFor(Succ)))
258       continue;
259     const MachineTraceMetrics::TraceBlockInfo *SuccTBI =
260       getHeightResources(Succ);
261     assert(SuccTBI && "Successor must be visited first");
262     // Pick the successor that would give this block the smallest InstrHeight.
263     unsigned Height = SuccTBI->InstrHeight;
264     if (!Best || Height < BestHeight)
265       Best = Succ, BestHeight = Height;
266   }
267   return Best;
268 }
269
270 // Get an Ensemble sub-class for the requested trace strategy.
271 MachineTraceMetrics::Ensemble *
272 MachineTraceMetrics::getEnsemble(MachineTraceMetrics::Strategy strategy) {
273   assert(strategy < TS_NumStrategies && "Invalid trace strategy enum");
274   Ensemble *&E = Ensembles[strategy];
275   if (E)
276     return E;
277
278   // Allocate new Ensemble on demand.
279   switch (strategy) {
280   case TS_MinInstrCount: return (E = new MinInstrCountEnsemble(this));
281   default: llvm_unreachable("Invalid trace strategy enum");
282   }
283 }
284
285 void MachineTraceMetrics::invalidate(const MachineBasicBlock *MBB) {
286   DEBUG(dbgs() << "Invalidate traces through BB#" << MBB->getNumber() << '\n');
287   BlockInfo[MBB->getNumber()].invalidate();
288   for (unsigned i = 0; i != TS_NumStrategies; ++i)
289     if (Ensembles[i])
290       Ensembles[i]->invalidate(MBB);
291 }
292
293 void MachineTraceMetrics::verifyAnalysis() const {
294   if (!MF)
295     return;
296 #ifndef NDEBUG
297   assert(BlockInfo.size() == MF->getNumBlockIDs() && "Outdated BlockInfo size");
298   for (unsigned i = 0; i != TS_NumStrategies; ++i)
299     if (Ensembles[i])
300       Ensembles[i]->verify();
301 #endif
302 }
303
304 //===----------------------------------------------------------------------===//
305 //                               Trace building
306 //===----------------------------------------------------------------------===//
307 //
308 // Traces are built by two CFG traversals. To avoid recomputing too much, use a
309 // set abstraction that confines the search to the current loop, and doesn't
310 // revisit blocks.
311
312 namespace {
313 struct LoopBounds {
314   MutableArrayRef<MachineTraceMetrics::TraceBlockInfo> Blocks;
315   const MachineLoopInfo *Loops;
316   bool Downward;
317   LoopBounds(MutableArrayRef<MachineTraceMetrics::TraceBlockInfo> blocks,
318              const MachineLoopInfo *loops)
319     : Blocks(blocks), Loops(loops), Downward(false) {}
320 };
321 }
322
323 // Specialize po_iterator_storage in order to prune the post-order traversal so
324 // it is limited to the current loop and doesn't traverse the loop back edges.
325 namespace llvm {
326 template<>
327 class po_iterator_storage<LoopBounds, true> {
328   LoopBounds &LB;
329 public:
330   po_iterator_storage(LoopBounds &lb) : LB(lb) {}
331   void finishPostorder(const MachineBasicBlock*) {}
332
333   bool insertEdge(const MachineBasicBlock *From, const MachineBasicBlock *To) {
334     // Skip already visited To blocks.
335     MachineTraceMetrics::TraceBlockInfo &TBI = LB.Blocks[To->getNumber()];
336     if (LB.Downward ? TBI.hasValidHeight() : TBI.hasValidDepth())
337       return false;
338     // From is null once when To is the trace center block.
339     if (!From)
340       return true;
341     const MachineLoop *FromLoop = LB.Loops->getLoopFor(From);
342     if (!FromLoop)
343       return true;
344     // Don't follow backedges, don't leave FromLoop when going upwards.
345     if ((LB.Downward ? To : From) == FromLoop->getHeader())
346       return false;
347     // Don't leave FromLoop.
348     if (isExitingLoop(FromLoop, LB.Loops->getLoopFor(To)))
349       return false;
350     // This is a new block. The PO traversal will compute height/depth
351     // resources, causing us to reject new edges to To. This only works because
352     // we reject back-edges, so the CFG is cycle-free.
353     return true;
354   }
355 };
356 }
357
358 /// Compute the trace through MBB.
359 void MachineTraceMetrics::Ensemble::computeTrace(const MachineBasicBlock *MBB) {
360   DEBUG(dbgs() << "Computing " << getName() << " trace through BB#"
361                << MBB->getNumber() << '\n');
362   // Set up loop bounds for the backwards post-order traversal.
363   LoopBounds Bounds(BlockInfo, CT.Loops);
364
365   // Run an upwards post-order search for the trace start.
366   Bounds.Downward = false;
367   typedef ipo_ext_iterator<const MachineBasicBlock*, LoopBounds> UpwardPO;
368   for (UpwardPO I = ipo_ext_begin(MBB, Bounds), E = ipo_ext_end(MBB, Bounds);
369        I != E; ++I) {
370     DEBUG(dbgs() << "  pred for BB#" << I->getNumber() << ": ");
371     TraceBlockInfo &TBI = BlockInfo[I->getNumber()];
372     // All the predecessors have been visited, pick the preferred one.
373     TBI.Pred = pickTracePred(*I);
374     DEBUG({
375       if (TBI.Pred)
376         dbgs() << "BB#" << TBI.Pred->getNumber() << '\n';
377       else
378         dbgs() << "null\n";
379     });
380     // The trace leading to I is now known, compute the depth resources.
381     computeDepthResources(*I);
382   }
383
384   // Run a downwards post-order search for the trace end.
385   Bounds.Downward = true;
386   typedef po_ext_iterator<const MachineBasicBlock*, LoopBounds> DownwardPO;
387   for (DownwardPO I = po_ext_begin(MBB, Bounds), E = po_ext_end(MBB, Bounds);
388        I != E; ++I) {
389     DEBUG(dbgs() << "  succ for BB#" << I->getNumber() << ": ");
390     TraceBlockInfo &TBI = BlockInfo[I->getNumber()];
391     // All the successors have been visited, pick the preferred one.
392     TBI.Succ = pickTraceSucc(*I);
393     DEBUG({
394       if (TBI.Succ)
395         dbgs() << "BB#" << TBI.Succ->getNumber() << '\n';
396       else
397         dbgs() << "null\n";
398     });
399     // The trace leaving I is now known, compute the height resources.
400     computeHeightResources(*I);
401   }
402 }
403
404 /// Invalidate traces through BadMBB.
405 void
406 MachineTraceMetrics::Ensemble::invalidate(const MachineBasicBlock *BadMBB) {
407   SmallVector<const MachineBasicBlock*, 16> WorkList;
408   TraceBlockInfo &BadTBI = BlockInfo[BadMBB->getNumber()];
409
410   // Invalidate height resources of blocks above MBB.
411   if (BadTBI.hasValidHeight()) {
412     BadTBI.invalidateHeight();
413     WorkList.push_back(BadMBB);
414     do {
415       const MachineBasicBlock *MBB = WorkList.pop_back_val();
416       DEBUG(dbgs() << "Invalidate BB#" << MBB->getNumber() << ' ' << getName()
417             << " height.\n");
418       // Find any MBB predecessors that have MBB as their preferred successor.
419       // They are the only ones that need to be invalidated.
420       for (MachineBasicBlock::const_pred_iterator
421            I = MBB->pred_begin(), E = MBB->pred_end(); I != E; ++I) {
422         TraceBlockInfo &TBI = BlockInfo[(*I)->getNumber()];
423         if (!TBI.hasValidHeight())
424           continue;
425         if (TBI.Succ == MBB) {
426           TBI.invalidateHeight();
427           WorkList.push_back(*I);
428           continue;
429         }
430         // Verify that TBI.Succ is actually a *I successor.
431         assert((!TBI.Succ || (*I)->isSuccessor(TBI.Succ)) && "CFG changed");
432       }
433     } while (!WorkList.empty());
434   }
435
436   // Invalidate depth resources of blocks below MBB.
437   if (BadTBI.hasValidDepth()) {
438     BadTBI.invalidateDepth();
439     WorkList.push_back(BadMBB);
440     do {
441       const MachineBasicBlock *MBB = WorkList.pop_back_val();
442       DEBUG(dbgs() << "Invalidate BB#" << MBB->getNumber() << ' ' << getName()
443             << " depth.\n");
444       // Find any MBB successors that have MBB as their preferred predecessor.
445       // They are the only ones that need to be invalidated.
446       for (MachineBasicBlock::const_succ_iterator
447            I = MBB->succ_begin(), E = MBB->succ_end(); I != E; ++I) {
448         TraceBlockInfo &TBI = BlockInfo[(*I)->getNumber()];
449         if (!TBI.hasValidDepth())
450           continue;
451         if (TBI.Pred == MBB) {
452           TBI.invalidateDepth();
453           WorkList.push_back(*I);
454           continue;
455         }
456         // Verify that TBI.Pred is actually a *I predecessor.
457         assert((!TBI.Pred || (*I)->isPredecessor(TBI.Pred)) && "CFG changed");
458       }
459     } while (!WorkList.empty());
460   }
461 }
462
463 void MachineTraceMetrics::Ensemble::verify() const {
464 #ifndef NDEBUG
465   assert(BlockInfo.size() == CT.MF->getNumBlockIDs() &&
466          "Outdated BlockInfo size");
467   for (unsigned Num = 0, e = BlockInfo.size(); Num != e; ++Num) {
468     const TraceBlockInfo &TBI = BlockInfo[Num];
469     if (TBI.hasValidDepth() && TBI.Pred) {
470       const MachineBasicBlock *MBB = CT.MF->getBlockNumbered(Num);
471       assert(MBB->isPredecessor(TBI.Pred) && "CFG doesn't match trace");
472       assert(BlockInfo[TBI.Pred->getNumber()].hasValidDepth() &&
473              "Trace is broken, depth should have been invalidated.");
474       const MachineLoop *Loop = getLoopFor(MBB);
475       assert(!(Loop && MBB == Loop->getHeader()) && "Trace contains backedge");
476     }
477     if (TBI.hasValidHeight() && TBI.Succ) {
478       const MachineBasicBlock *MBB = CT.MF->getBlockNumbered(Num);
479       assert(MBB->isSuccessor(TBI.Succ) && "CFG doesn't match trace");
480       assert(BlockInfo[TBI.Succ->getNumber()].hasValidHeight() &&
481              "Trace is broken, height should have been invalidated.");
482       const MachineLoop *Loop = getLoopFor(MBB);
483       const MachineLoop *SuccLoop = getLoopFor(TBI.Succ);
484       assert(!(Loop && Loop == SuccLoop && TBI.Succ == Loop->getHeader()) &&
485              "Trace contains backedge");
486     }
487   }
488 #endif
489 }
490
491 MachineTraceMetrics::Trace
492 MachineTraceMetrics::Ensemble::getTrace(const MachineBasicBlock *MBB) {
493   // FIXME: Check cache tags, recompute as needed.
494   computeTrace(MBB);
495   return Trace(*this, BlockInfo[MBB->getNumber()]);
496 }
497
498 void MachineTraceMetrics::Ensemble::print(raw_ostream &OS) const {
499   OS << getName() << " ensemble:\n";
500   for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
501     OS << "  BB#" << i << '\t';
502     BlockInfo[i].print(OS);
503     OS << '\n';
504   }
505 }
506
507 void MachineTraceMetrics::TraceBlockInfo::print(raw_ostream &OS) const {
508   if (hasValidDepth()) {
509     OS << "depth=" << InstrDepth;
510     if (Pred)
511       OS << " pred=BB#" << Pred->getNumber();
512     else
513       OS << " pred=null";
514     OS << " head=BB#" << Head;
515   } else
516     OS << "depth invalid";
517   OS << ", ";
518   if (hasValidHeight()) {
519     OS << "height=" << InstrHeight;
520     if (Succ)
521       OS << " succ=BB#" << Succ->getNumber();
522     else
523       OS << " succ=null";
524     OS << " tail=BB#" << Tail;
525   } else
526     OS << "height invalid";
527 }
528
529 void MachineTraceMetrics::Trace::print(raw_ostream &OS) const {
530   unsigned MBBNum = &TBI - &TE.BlockInfo[0];
531
532   OS << TE.getName() << " trace BB#" << TBI.Head << " --> BB#" << MBBNum
533      << " --> BB#" << TBI.Tail << ':';
534   if (TBI.hasValidHeight() && TBI.hasValidDepth())
535     OS << ' ' << getInstrCount() << " instrs.";
536
537   const MachineTraceMetrics::TraceBlockInfo *Block = &TBI;
538   OS << "\nBB#" << MBBNum;
539   while (Block->hasValidDepth() && Block->Pred) {
540     unsigned Num = Block->Pred->getNumber();
541     OS << " <- BB#" << Num;
542     Block = &TE.BlockInfo[Num];
543   }
544
545   Block = &TBI;
546   OS << "\n    ";
547   while (Block->hasValidHeight() && Block->Succ) {
548     unsigned Num = Block->Succ->getNumber();
549     OS << " -> BB#" << Num;
550     Block = &TE.BlockInfo[Num];
551   }
552   OS << '\n';
553 }