1*9880d681SAndroid Build Coastguard Worker //===- IntervalPartition.cpp - Interval Partition module code -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the definition of the IntervalPartition class, which
11*9880d681SAndroid Build Coastguard Worker // calculates and represent the interval partition of a function.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/IntervalIterator.h"
16*9880d681SAndroid Build Coastguard Worker using namespace llvm;
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker char IntervalPartition::ID = 0;
19*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(IntervalPartition, "intervals",
20*9880d681SAndroid Build Coastguard Worker "Interval Partition Construction", true, true)
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
23*9880d681SAndroid Build Coastguard Worker // IntervalPartition Implementation
24*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker // releaseMemory - Reset state back to before function was analyzed
releaseMemory()27*9880d681SAndroid Build Coastguard Worker void IntervalPartition::releaseMemory() {
28*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Intervals.size(); i != e; ++i)
29*9880d681SAndroid Build Coastguard Worker delete Intervals[i];
30*9880d681SAndroid Build Coastguard Worker IntervalMap.clear();
31*9880d681SAndroid Build Coastguard Worker Intervals.clear();
32*9880d681SAndroid Build Coastguard Worker RootInterval = nullptr;
33*9880d681SAndroid Build Coastguard Worker }
34*9880d681SAndroid Build Coastguard Worker
print(raw_ostream & O,const Module *) const35*9880d681SAndroid Build Coastguard Worker void IntervalPartition::print(raw_ostream &O, const Module*) const {
36*9880d681SAndroid Build Coastguard Worker for(unsigned i = 0, e = Intervals.size(); i != e; ++i)
37*9880d681SAndroid Build Coastguard Worker Intervals[i]->print(O);
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker // addIntervalToPartition - Add an interval to the internal list of intervals,
41*9880d681SAndroid Build Coastguard Worker // and then add mappings from all of the basic blocks in the interval to the
42*9880d681SAndroid Build Coastguard Worker // interval itself (in the IntervalMap).
43*9880d681SAndroid Build Coastguard Worker //
addIntervalToPartition(Interval * I)44*9880d681SAndroid Build Coastguard Worker void IntervalPartition::addIntervalToPartition(Interval *I) {
45*9880d681SAndroid Build Coastguard Worker Intervals.push_back(I);
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker // Add mappings for all of the basic blocks in I to the IntervalPartition
48*9880d681SAndroid Build Coastguard Worker for (Interval::node_iterator It = I->Nodes.begin(), End = I->Nodes.end();
49*9880d681SAndroid Build Coastguard Worker It != End; ++It)
50*9880d681SAndroid Build Coastguard Worker IntervalMap.insert(std::make_pair(*It, I));
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker // updatePredecessors - Interval generation only sets the successor fields of
54*9880d681SAndroid Build Coastguard Worker // the interval data structures. After interval generation is complete,
55*9880d681SAndroid Build Coastguard Worker // run through all of the intervals and propagate successor info as
56*9880d681SAndroid Build Coastguard Worker // predecessor info.
57*9880d681SAndroid Build Coastguard Worker //
updatePredecessors(Interval * Int)58*9880d681SAndroid Build Coastguard Worker void IntervalPartition::updatePredecessors(Interval *Int) {
59*9880d681SAndroid Build Coastguard Worker BasicBlock *Header = Int->getHeaderNode();
60*9880d681SAndroid Build Coastguard Worker for (BasicBlock *Successor : Int->Successors)
61*9880d681SAndroid Build Coastguard Worker getBlockInterval(Successor)->Predecessors.push_back(Header);
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker // IntervalPartition ctor - Build the first level interval partition for the
65*9880d681SAndroid Build Coastguard Worker // specified function...
66*9880d681SAndroid Build Coastguard Worker //
runOnFunction(Function & F)67*9880d681SAndroid Build Coastguard Worker bool IntervalPartition::runOnFunction(Function &F) {
68*9880d681SAndroid Build Coastguard Worker // Pass false to intervals_begin because we take ownership of it's memory
69*9880d681SAndroid Build Coastguard Worker function_interval_iterator I = intervals_begin(&F, false);
70*9880d681SAndroid Build Coastguard Worker assert(I != intervals_end(&F) && "No intervals in function!?!?!");
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker addIntervalToPartition(RootInterval = *I);
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker ++I; // After the first one...
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker // Add the rest of the intervals to the partition.
77*9880d681SAndroid Build Coastguard Worker for (function_interval_iterator E = intervals_end(&F); I != E; ++I)
78*9880d681SAndroid Build Coastguard Worker addIntervalToPartition(*I);
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker // Now that we know all of the successor information, propagate this to the
81*9880d681SAndroid Build Coastguard Worker // predecessors for each block.
82*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Intervals.size(); i != e; ++i)
83*9880d681SAndroid Build Coastguard Worker updatePredecessors(Intervals[i]);
84*9880d681SAndroid Build Coastguard Worker return false;
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker // IntervalPartition ctor - Build a reduced interval partition from an
89*9880d681SAndroid Build Coastguard Worker // existing interval graph. This takes an additional boolean parameter to
90*9880d681SAndroid Build Coastguard Worker // distinguish it from a copy constructor. Always pass in false for now.
91*9880d681SAndroid Build Coastguard Worker //
IntervalPartition(IntervalPartition & IP,bool)92*9880d681SAndroid Build Coastguard Worker IntervalPartition::IntervalPartition(IntervalPartition &IP, bool)
93*9880d681SAndroid Build Coastguard Worker : FunctionPass(ID) {
94*9880d681SAndroid Build Coastguard Worker assert(IP.getRootInterval() && "Cannot operate on empty IntervalPartitions!");
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker // Pass false to intervals_begin because we take ownership of it's memory
97*9880d681SAndroid Build Coastguard Worker interval_part_interval_iterator I = intervals_begin(IP, false);
98*9880d681SAndroid Build Coastguard Worker assert(I != intervals_end(IP) && "No intervals in interval partition!?!?!");
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker addIntervalToPartition(RootInterval = *I);
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker ++I; // After the first one...
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker // Add the rest of the intervals to the partition.
105*9880d681SAndroid Build Coastguard Worker for (interval_part_interval_iterator E = intervals_end(IP); I != E; ++I)
106*9880d681SAndroid Build Coastguard Worker addIntervalToPartition(*I);
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker // Now that we know all of the successor information, propagate this to the
109*9880d681SAndroid Build Coastguard Worker // predecessors for each block.
110*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Intervals.size(); i != e; ++i)
111*9880d681SAndroid Build Coastguard Worker updatePredecessors(Intervals[i]);
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
114