blob: a542f3ea3d98e252562dc3ed181a992561474d2c [file] [log] [blame]
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001//===- subzero/src/IceLiveness.h - Liveness analysis ------------*- C++ -*-===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the Liveness and LivenessNode classes,
11// which are used for liveness analysis. The node-specific
12// information tracked for each Variable includes whether it is
13// live on entry, whether it is live on exit, the instruction number
14// that starts its live range, and the instruction number that ends
15// its live range. At the Cfg level, the actual live intervals are
16// recorded.
17//
18//===----------------------------------------------------------------------===//
19
20#ifndef SUBZERO_SRC_ICELIVENESS_H
21#define SUBZERO_SRC_ICELIVENESS_H
22
23#include "IceDefs.h"
24#include "IceTypes.h"
25
26namespace Ice {
27
28class LivenessNode {
Jim Stichnoth7b451a92014-10-15 14:39:23 -070029 // TODO: Disable these constructors when Liveness::Nodes is no
30 // longer an STL container.
31 // LivenessNode(const LivenessNode &) = delete;
32 // LivenessNode &operator=(const LivenessNode &) = delete;
33
Jim Stichnothd97c7df2014-06-04 11:57:08 -070034public:
Jim Stichnoth336f6c42014-10-30 15:01:31 -070035 LivenessNode() : NumLocals(0), NumNonDeadPhis(0) {}
Jim Stichnothd97c7df2014-06-04 11:57:08 -070036 // NumLocals is the number of Variables local to this block.
37 SizeT NumLocals;
Jim Stichnoth336f6c42014-10-30 15:01:31 -070038 // NumNonDeadPhis tracks the number of Phi instructions that
39 // Inst::liveness() identified as tentatively live. If
40 // NumNonDeadPhis changes from the last liveness pass, then liveness
41 // has not yet converged.
42 SizeT NumNonDeadPhis;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070043 // LiveToVarMap maps a liveness bitvector index to a Variable. This
44 // is generally just for printing/dumping. The index should be less
45 // than NumLocals + Liveness::NumGlobals.
46 std::vector<Variable *> LiveToVarMap;
47 // LiveIn and LiveOut track the in- and out-liveness of the global
48 // variables. The size of each vector is
49 // LivenessNode::NumGlobals.
Jim Stichnoth47752552014-10-13 17:15:08 -070050 LivenessBV LiveIn, LiveOut;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070051 // LiveBegin and LiveEnd track the instruction numbers of the start
52 // and end of each variable's live range within this block. The
Jim Stichnoth47752552014-10-13 17:15:08 -070053 // index/key of each element is less than NumLocals +
54 // Liveness::NumGlobals.
55 LiveBeginEndMap LiveBegin, LiveEnd;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070056};
57
58class Liveness {
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070059 Liveness(const Liveness &) = delete;
60 Liveness &operator=(const Liveness &) = delete;
61
Jim Stichnothd97c7df2014-06-04 11:57:08 -070062public:
63 Liveness(Cfg *Func, LivenessMode Mode)
64 : Func(Func), Mode(Mode), NumGlobals(0) {}
65 void init();
Jim Stichnoth47752552014-10-13 17:15:08 -070066 Cfg *getFunc() const { return Func; }
67 LivenessMode getMode() const { return Mode; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070068 Variable *getVariable(SizeT LiveIndex, const CfgNode *Node) const;
Jim Stichnoth47752552014-10-13 17:15:08 -070069 SizeT getLiveIndex(SizeT VarIndex) const { return VarToLiveMap[VarIndex]; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070070 SizeT getNumGlobalVars() const { return NumGlobals; }
71 SizeT getNumVarsInNode(const CfgNode *Node) const {
72 return NumGlobals + Nodes[Node->getIndex()].NumLocals;
73 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -070074 SizeT &getNumNonDeadPhis(const CfgNode *Node) {
75 return Nodes[Node->getIndex()].NumNonDeadPhis;
76 }
Jim Stichnoth47752552014-10-13 17:15:08 -070077 LivenessBV &getLiveIn(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070078 SizeT Index = Node->getIndex();
79 resize(Index);
80 return Nodes[Index].LiveIn;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070081 }
Jim Stichnoth47752552014-10-13 17:15:08 -070082 LivenessBV &getLiveOut(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070083 SizeT Index = Node->getIndex();
84 resize(Index);
85 return Nodes[Index].LiveOut;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070086 }
Jim Stichnoth47752552014-10-13 17:15:08 -070087 LiveBeginEndMap *getLiveBegin(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070088 SizeT Index = Node->getIndex();
89 resize(Index);
90 return &Nodes[Index].LiveBegin;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070091 }
Jim Stichnoth47752552014-10-13 17:15:08 -070092 LiveBeginEndMap *getLiveEnd(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070093 SizeT Index = Node->getIndex();
94 resize(Index);
95 return &Nodes[Index].LiveEnd;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070096 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070097
98private:
Jim Stichnoth336f6c42014-10-30 15:01:31 -070099 // Resize Nodes so that Nodes[Index] is valid.
100 void resize(SizeT Index) {
101 if (Index >= Nodes.size())
102 Nodes.resize(Index + 1);
103 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700104 Cfg *Func;
105 LivenessMode Mode;
106 SizeT NumGlobals;
107 // Size of Nodes is Cfg::Nodes.size().
108 std::vector<LivenessNode> Nodes;
109 // VarToLiveMap maps a Variable's Variable::Number to its live index
110 // within its basic block.
111 std::vector<SizeT> VarToLiveMap;
112 // LiveToVarMap is analogous to LivenessNode::LiveToVarMap, but for
113 // non-local variables.
114 std::vector<Variable *> LiveToVarMap;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700115};
116
117} // end of namespace Ice
118
119#endif // SUBZERO_SRC_ICELIVENESS_H