| //===- IntervalPartition.cpp - Interval Partition module code -------------===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file contains the definition of the IntervalPartition class, which | 
 | // calculates and represent the interval partition of a function. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "llvm/Analysis/IntervalPartition.h" | 
 | #include "llvm/Analysis/Interval.h" | 
 | #include "llvm/Analysis/IntervalIterator.h" | 
 | #include "llvm/InitializePasses.h" | 
 | #include "llvm/Pass.h" | 
 | #include <cassert> | 
 | #include <utility> | 
 |  | 
 | using namespace llvm; | 
 |  | 
 | char IntervalPartition::ID = 0; | 
 |  | 
 | IntervalPartition::IntervalPartition() : FunctionPass(ID) { | 
 |   initializeIntervalPartitionPass(*PassRegistry::getPassRegistry()); | 
 | } | 
 |  | 
 | INITIALIZE_PASS(IntervalPartition, "intervals", | 
 |                 "Interval Partition Construction", true, true) | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // IntervalPartition Implementation | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | // releaseMemory - Reset state back to before function was analyzed | 
 | void IntervalPartition::releaseMemory() { | 
 |   for (Interval *I : Intervals) | 
 |     delete I; | 
 |   IntervalMap.clear(); | 
 |   Intervals.clear(); | 
 |   RootInterval = nullptr; | 
 | } | 
 |  | 
 | void IntervalPartition::print(raw_ostream &O, const Module*) const { | 
 |   for (const Interval *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 (BasicBlock *Successor : Int->Successors) | 
 |     getBlockInterval(Successor)->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 (Interval *I : Intervals) | 
 |     updatePredecessors(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) | 
 |   : FunctionPass(ID) { | 
 |   assert(IP.getRootInterval() && "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 (Interval *I : Intervals) | 
 |     updatePredecessors(I); | 
 | } |