blob: 634bc35465f7b598980eb6c304438176a4a48d97 [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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares the Liveness and LivenessNode classes, which are used for
12/// liveness analysis.
13///
14/// The node-specific information tracked for each Variable includes whether it
15/// is live on entry, whether it is live on exit, the instruction number that
16/// starts its live range, and the instruction number that ends its live range.
17/// At the Cfg level, the actual live intervals are recorded.
Andrew Scull9612d322015-07-06 14:53:25 -070018///
Jim Stichnothd97c7df2014-06-04 11:57:08 -070019//===----------------------------------------------------------------------===//
20
21#ifndef SUBZERO_SRC_ICELIVENESS_H
22#define SUBZERO_SRC_ICELIVENESS_H
23
24#include "IceDefs.h"
John Porto36d6aa62016-02-26 07:19:59 -080025#include "IceBitVector.h"
26#include "IceCfgNode.h"
John Porto7bb9cab2016-04-01 05:43:09 -070027#include "IceTLS.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070028#include "IceTypes.h"
29
John Porto7bb9cab2016-04-01 05:43:09 -070030#include <memory>
31#include <utility>
32
Jim Stichnothd97c7df2014-06-04 11:57:08 -070033namespace Ice {
34
Jim Stichnothd97c7df2014-06-04 11:57:08 -070035class Liveness {
Jim Stichnothc6ead202015-02-24 09:30:30 -080036 Liveness() = delete;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070037 Liveness(const Liveness &) = delete;
38 Liveness &operator=(const Liveness &) = delete;
39
Jim Stichnoth7e571362015-01-09 11:43:26 -080040 class LivenessNode {
41 LivenessNode &operator=(const LivenessNode &) = delete;
42
43 public:
Jim Stichnotheafb56c2015-06-22 10:35:22 -070044 LivenessNode() = default;
Jim Stichnoth7e571362015-01-09 11:43:26 -080045 LivenessNode(const LivenessNode &) = default;
Andrew Scull9612d322015-07-06 14:53:25 -070046 /// NumLocals is the number of Variables local to this block.
Jim Stichnotheafb56c2015-06-22 10:35:22 -070047 SizeT NumLocals = 0;
Andrew Scull9612d322015-07-06 14:53:25 -070048 /// NumNonDeadPhis tracks the number of Phi instructions that
Andrew Scull57e12682015-09-16 11:30:19 -070049 /// Inst::liveness() identified as tentatively live. If NumNonDeadPhis
50 /// changes from the last liveness pass, then liveness has not yet
51 /// converged.
Jim Stichnotheafb56c2015-06-22 10:35:22 -070052 SizeT NumNonDeadPhis = 0;
Andrew Scull57e12682015-09-16 11:30:19 -070053 // LiveToVarMap maps a liveness bitvector index to a Variable. This is
54 // generally just for printing/dumping. The index should be less than
55 // NumLocals + Liveness::NumGlobals.
John Porto7bb9cab2016-04-01 05:43:09 -070056 LivenessVector<Variable *> LiveToVarMap;
Jim Stichnoth7e571362015-01-09 11:43:26 -080057 // LiveIn and LiveOut track the in- and out-liveness of the global
Andrew Scull57e12682015-09-16 11:30:19 -070058 // variables. The size of each vector is LivenessNode::NumGlobals.
Jim Stichnoth7e571362015-01-09 11:43:26 -080059 LivenessBV LiveIn, LiveOut;
Andrew Scull57e12682015-09-16 11:30:19 -070060 // LiveBegin and LiveEnd track the instruction numbers of the start and end
61 // of each variable's live range within this block. The index/key of each
62 // element is less than NumLocals + Liveness::NumGlobals.
Jim Stichnoth7e571362015-01-09 11:43:26 -080063 LiveBeginEndMap LiveBegin, LiveEnd;
64 };
65
Jim Stichnothd97c7df2014-06-04 11:57:08 -070066public:
Jim Stichnothd97c7df2014-06-04 11:57:08 -070067 void init();
Jim Stichnotha3f57b92015-07-30 12:46:04 -070068 void initPhiEdgeSplits(NodeList::const_iterator FirstNode,
69 VarList::const_iterator FirstVar);
Jim Stichnoth47752552014-10-13 17:15:08 -070070 Cfg *getFunc() const { return Func; }
71 LivenessMode getMode() const { return Mode; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070072 Variable *getVariable(SizeT LiveIndex, const CfgNode *Node) const;
Jim Stichnothcc89c952016-03-31 11:55:23 -070073 SizeT getLiveIndex(SizeT VarIndex) const {
74 const SizeT LiveIndex = VarToLiveMap[VarIndex];
75 assert(LiveIndex != InvalidLiveIndex);
76 return LiveIndex;
77 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070078 SizeT getNumGlobalVars() const { return NumGlobals; }
79 SizeT getNumVarsInNode(const CfgNode *Node) const {
80 return NumGlobals + Nodes[Node->getIndex()].NumLocals;
81 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -070082 SizeT &getNumNonDeadPhis(const CfgNode *Node) {
83 return Nodes[Node->getIndex()].NumNonDeadPhis;
84 }
Jim Stichnoth47752552014-10-13 17:15:08 -070085 LivenessBV &getLiveIn(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070086 SizeT Index = Node->getIndex();
87 resize(Index);
88 return Nodes[Index].LiveIn;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070089 }
Jim Stichnoth47752552014-10-13 17:15:08 -070090 LivenessBV &getLiveOut(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070091 SizeT Index = Node->getIndex();
92 resize(Index);
93 return Nodes[Index].LiveOut;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070094 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -080095 LivenessBV &getScratchBV() { return ScratchBV; }
Jim Stichnoth47752552014-10-13 17:15:08 -070096 LiveBeginEndMap *getLiveBegin(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -070097 SizeT Index = Node->getIndex();
98 resize(Index);
99 return &Nodes[Index].LiveBegin;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700100 }
Jim Stichnoth47752552014-10-13 17:15:08 -0700101 LiveBeginEndMap *getLiveEnd(const CfgNode *Node) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700102 SizeT Index = Node->getIndex();
103 resize(Index);
104 return &Nodes[Index].LiveEnd;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700105 }
Jim Stichnoth552490c2015-08-05 16:21:42 -0700106 bool getRangeMask(SizeT Index) const { return RangeMask[Index]; }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700107
John Porto7bb9cab2016-04-01 05:43:09 -0700108 ArenaAllocator *getAllocator() const { return Alloc.get(); }
109
110 static std::unique_ptr<Liveness> create(Cfg *Func, LivenessMode Mode) {
111 return std::unique_ptr<Liveness>(new Liveness(Func, Mode));
112 }
113
114 static void TlsInit() { LivenessAllocatorTraits::init(); }
115
116 std::string dumpStr() const {
117 return "MaxLocals(" + std::to_string(MaxLocals) + "), "
118 "NumGlobals(" +
119 std::to_string(NumGlobals) + ")";
120 }
121
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700122private:
John Porto7bb9cab2016-04-01 05:43:09 -0700123 Liveness(Cfg *Func, LivenessMode Mode)
124 : Alloc(new ArenaAllocator()), AllocScope(this), Func(Func), Mode(Mode) {}
125
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700126 void initInternal(NodeList::const_iterator FirstNode,
127 VarList::const_iterator FirstVar, bool IsFullInit);
Andrew Scull9612d322015-07-06 14:53:25 -0700128 /// Resize Nodes so that Nodes[Index] is valid.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700129 void resize(SizeT Index) {
John Porto7bb9cab2016-04-01 05:43:09 -0700130 if (Index >= Nodes.size()) {
131 assert(false && "The Nodes array is not expected to be resized.");
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700132 Nodes.resize(Index + 1);
John Porto7bb9cab2016-04-01 05:43:09 -0700133 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700134 }
John Porto7bb9cab2016-04-01 05:43:09 -0700135 std::unique_ptr<ArenaAllocator> Alloc;
136 LivenessAllocatorScope AllocScope; // Must be declared after Alloc.
Jim Stichnothcc89c952016-03-31 11:55:23 -0700137 static constexpr SizeT InvalidLiveIndex = -1;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700138 Cfg *Func;
139 LivenessMode Mode;
Andrew Scull9612d322015-07-06 14:53:25 -0700140 /// Size of Nodes is Cfg::Nodes.size().
John Porto7bb9cab2016-04-01 05:43:09 -0700141 LivenessVector<LivenessNode> Nodes;
Andrew Scull57e12682015-09-16 11:30:19 -0700142 /// VarToLiveMap maps a Variable's Variable::Number to its live index within
143 /// its basic block.
John Porto7bb9cab2016-04-01 05:43:09 -0700144 LivenessVector<SizeT> VarToLiveMap;
Andrew Scull57e12682015-09-16 11:30:19 -0700145 /// LiveToVarMap is analogous to LivenessNode::LiveToVarMap, but for non-local
146 /// variables.
John Porto7bb9cab2016-04-01 05:43:09 -0700147 LivenessVector<Variable *> LiveToVarMap;
Jim Stichnoth552490c2015-08-05 16:21:42 -0700148 /// RangeMask[Variable::Number] indicates whether we want to track that
149 /// Variable's live range.
John Porto36d6aa62016-02-26 07:19:59 -0800150 LivenessBV RangeMask;
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800151 /// ScratchBV is a bitvector that can be reused across CfgNode passes, to
152 /// avoid having to allocate/deallocate memory so frequently.
153 LivenessBV ScratchBV;
John Porto7bb9cab2016-04-01 05:43:09 -0700154 /// MaxLocals indicates what is the maximum number of local variables in a
155 /// single basic block, across all blocks in a function.
156 SizeT MaxLocals = 0;
157 /// NumGlobals indicates how many global variables (i.e., Multi Block) exist
158 /// for a function.
159 SizeT NumGlobals = 0;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700160};
161
162} // end of namespace Ice
163
164#endif // SUBZERO_SRC_ICELIVENESS_H