Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 //===- subzero/src/Liveness.cpp - Liveness analysis implementation -----===// | |
|
jvoung (off chromium)
2014/05/28 17:48:15
IceLiveness.cpp
Jim Stichnoth
2014/05/29 01:39:46
Done.
| |
| 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 provides some of the support for the Liveness class. | |
| 11 // In particular, it handles the sparsity representation of the | |
| 12 // mapping between Variables and CfgNodes. The idea is that | |
| 13 // since most variables are used only within a single basic block, we | |
| 14 // can partition the variables into "local" and "global" sets. | |
| 15 // Instead of sizing and indexing vectors according to | |
| 16 // Variable::Number, we create a mapping such that global variables | |
| 17 // are mapped to low indexes that are common across nodes, and local | |
| 18 // variables are mapped to a higher index space that is shared across | |
| 19 // nodes. | |
| 20 // | |
| 21 //===----------------------------------------------------------------------===// | |
| 22 | |
| 23 #include "IceDefs.h" | |
| 24 #include "IceCfg.h" | |
| 25 #include "IceCfgNode.h" | |
| 26 #include "IceInst.h" | |
| 27 #include "IceLiveness.h" | |
| 28 #include "IceOperand.h" | |
| 29 | |
| 30 namespace Ice { | |
| 31 | |
| 32 void Liveness::init() { | |
| 33 // Initialize most of the container sizes. | |
| 34 SizeT NumVars = Func->getVariables().size(); | |
| 35 SizeT NumNodes = Func->getNumNodes(); | |
| 36 Nodes.resize(NumNodes); | |
| 37 VarToLiveMap.resize(NumVars); | |
| 38 if (Mode == Liveness_RangesFull) | |
| 39 LiveRanges.resize(NumVars); | |
| 40 | |
| 41 // Count the number of globals, and the number of locals for each | |
| 42 // block. | |
| 43 for (SizeT i = 0; i < NumVars; ++i) { | |
| 44 Variable *Var = Func->getVariables()[i]; | |
| 45 if (Var->isMultiblockLife()) { | |
| 46 ++NumGlobals; | |
| 47 } else { | |
| 48 SizeT Index = Var->getLocalUseNode()->getIndex(); | |
| 49 ++Nodes[Index].NumLocals; | |
| 50 } | |
| 51 } | |
| 52 | |
| 53 // Resize each LivenessNode::LiveToVarMap, and the global | |
| 54 // LiveToVarMap. Reset the counts to 0. | |
| 55 for (SizeT i = 0; i < NumNodes; ++i) { | |
| 56 Nodes[i].LiveToVarMap.assign(Nodes[i].NumLocals, NULL); | |
| 57 Nodes[i].NumLocals = 0; | |
| 58 } | |
| 59 LiveToVarMap.assign(NumGlobals, NULL); | |
| 60 | |
| 61 // Sort each variable into the appropriate LiveToVarMap. Also set | |
| 62 // VarToLiveMap. | |
| 63 SizeT TmpNumGlobals = 0; | |
| 64 for (SizeT i = 0; i < NumVars; ++i) { | |
| 65 Variable *Var = Func->getVariables()[i]; | |
| 66 SizeT VarIndex = Var->getIndex(); | |
| 67 SizeT LiveIndex; | |
| 68 if (Var->isMultiblockLife()) { | |
| 69 LiveIndex = TmpNumGlobals++; | |
| 70 LiveToVarMap[LiveIndex] = Var; | |
| 71 } else { | |
| 72 SizeT NodeIndex = Var->getLocalUseNode()->getIndex(); | |
| 73 LiveIndex = Nodes[NodeIndex].NumLocals++; | |
| 74 Nodes[NodeIndex].LiveToVarMap[LiveIndex] = Var; | |
| 75 LiveIndex += NumGlobals; | |
| 76 } | |
| 77 VarToLiveMap[VarIndex] = LiveIndex; | |
| 78 } | |
| 79 assert(NumGlobals == TmpNumGlobals); | |
| 80 | |
| 81 // Process each node. | |
| 82 const NodeList &LNodes = Func->getNodes(); | |
| 83 SizeT NumLNodes = LNodes.size(); | |
| 84 for (SizeT i = 0; i < NumLNodes; ++i) { | |
| 85 LivenessNode &Node = Nodes[LNodes[i]->getIndex()]; | |
| 86 // NumLocals, LiveToVarMap already initialized | |
| 87 Node.LiveIn.resize(NumGlobals); | |
| 88 Node.LiveOut.resize(NumGlobals); | |
| 89 // LiveBegin and LiveEnd are reinitialized before each pass over | |
| 90 // the block. | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 Variable *Liveness::getVariable(SizeT LiveIndex, const CfgNode *Node) const { | |
| 95 if (LiveIndex < NumGlobals) | |
| 96 return LiveToVarMap[LiveIndex]; | |
| 97 SizeT NodeIndex = Node->getIndex(); | |
| 98 return Nodes[NodeIndex].LiveToVarMap[LiveIndex - NumGlobals]; | |
| 99 } | |
| 100 | |
| 101 SizeT Liveness::getLiveIndex(const Variable *Var) const { | |
| 102 return VarToLiveMap[Var->getIndex()]; | |
| 103 } | |
| 104 | |
| 105 void Liveness::addLiveRange(Variable *Var, int32_t Start, int32_t End, | |
| 106 uint32_t WeightDelta) { | |
| 107 LiveRange &LiveRange = LiveRanges[Var->getIndex()]; | |
| 108 assert(WeightDelta != RegWeight::Inf); | |
| 109 LiveRange.addSegment(Start, End); | |
| 110 LiveRange.addWeight(WeightDelta); | |
| 111 } | |
| 112 | |
| 113 LiveRange &Liveness::getLiveRange(Variable *Var) { | |
| 114 return LiveRanges[Var->getIndex()]; | |
| 115 } | |
| 116 | |
| 117 } // end of namespace Ice | |
| OLD | NEW |