| //===- IntervalPartition.cpp - Interval Partition module code -------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file was developed by the LLVM research group and is distributed under | 
 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file contains the definition of the IntervalPartition class, which | 
 | // calculates and represent the interval partition of a function. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "llvm/Analysis/IntervalIterator.h" | 
 | using namespace llvm; | 
 |  | 
 | static RegisterAnalysis<IntervalPartition> | 
 | X("intervals", "Interval Partition Construction", true); | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // IntervalPartition Implementation | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | // destroy - Reset state back to before function was analyzed | 
 | void IntervalPartition::destroy() { | 
 |   for (unsigned i = 0, e = Intervals.size(); i != e; ++i) | 
 |     delete Intervals[i]; | 
 |   IntervalMap.clear(); | 
 |   RootInterval = 0; | 
 | } | 
 |  | 
 | void IntervalPartition::print(std::ostream &O, const Module*) const { | 
 |   for(unsigned i = 0, e = Intervals.size(); i != e; ++i) | 
 |     Intervals[i]->print(O); | 
 | } | 
 |  | 
 | // addIntervalToPartition - Add an interval to the internal list of intervals, | 
 | // and then add mappings from all of the basic blocks in the interval to the | 
 | // interval itself (in the IntervalMap). | 
 | // | 
 | void IntervalPartition::addIntervalToPartition(Interval *I) { | 
 |   Intervals.push_back(I); | 
 |  | 
 |   // Add mappings for all of the basic blocks in I to the IntervalPartition | 
 |   for (Interval::node_iterator It = I->Nodes.begin(), End = I->Nodes.end(); | 
 |        It != End; ++It) | 
 |     IntervalMap.insert(std::make_pair(*It, I)); | 
 | } | 
 |  | 
 | // updatePredecessors - Interval generation only sets the successor fields of | 
 | // the interval data structures.  After interval generation is complete, | 
 | // run through all of the intervals and propagate successor info as | 
 | // predecessor info. | 
 | // | 
 | void IntervalPartition::updatePredecessors(Interval *Int) { | 
 |   BasicBlock *Header = Int->getHeaderNode(); | 
 |   for (Interval::succ_iterator I = Int->Successors.begin(), | 
 |          E = Int->Successors.end(); I != E; ++I) | 
 |     getBlockInterval(*I)->Predecessors.push_back(Header); | 
 | } | 
 |  | 
 | // IntervalPartition ctor - Build the first level interval partition for the | 
 | // specified function... | 
 | // | 
 | bool IntervalPartition::runOnFunction(Function &F) { | 
 |   // Pass false to intervals_begin because we take ownership of it's memory | 
 |   function_interval_iterator I = intervals_begin(&F, false); | 
 |   assert(I != intervals_end(&F) && "No intervals in function!?!?!"); | 
 |  | 
 |   addIntervalToPartition(RootInterval = *I); | 
 |  | 
 |   ++I;  // After the first one... | 
 |  | 
 |   // Add the rest of the intervals to the partition. | 
 |   for (function_interval_iterator E = intervals_end(&F); I != E; ++I) | 
 |     addIntervalToPartition(*I); | 
 |  | 
 |   // Now that we know all of the successor information, propagate this to the | 
 |   // predecessors for each block. | 
 |   for (unsigned i = 0, e = Intervals.size(); i != e; ++i) | 
 |     updatePredecessors(Intervals[i]); | 
 |   return false; | 
 | } | 
 |  | 
 |  | 
 | // IntervalPartition ctor - Build a reduced interval partition from an | 
 | // existing interval graph.  This takes an additional boolean parameter to | 
 | // distinguish it from a copy constructor.  Always pass in false for now. | 
 | // | 
 | IntervalPartition::IntervalPartition(IntervalPartition &IP, bool) { | 
 |   Interval *FunctionStart = IP.getRootInterval(); | 
 |   assert(FunctionStart && "Cannot operate on empty IntervalPartitions!"); | 
 |  | 
 |   // Pass false to intervals_begin because we take ownership of it's memory | 
 |   interval_part_interval_iterator I = intervals_begin(IP, false); | 
 |   assert(I != intervals_end(IP) && "No intervals in interval partition!?!?!"); | 
 |  | 
 |   addIntervalToPartition(RootInterval = *I); | 
 |  | 
 |   ++I;  // After the first one... | 
 |  | 
 |   // Add the rest of the intervals to the partition. | 
 |   for (interval_part_interval_iterator E = intervals_end(IP); I != E; ++I) | 
 |     addIntervalToPartition(*I); | 
 |  | 
 |   // Now that we know all of the successor information, propagate this to the | 
 |   // predecessors for each block. | 
 |   for (unsigned i = 0, e = Intervals.size(); i != e; ++i) | 
 |     updatePredecessors(Intervals[i]); | 
 | } | 
 |  |