1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker ///
10*03ce13f7SAndroid Build Coastguard Worker /// \file
11*03ce13f7SAndroid Build Coastguard Worker /// \brief Implements the Operand class and its target-independent subclasses,
12*03ce13f7SAndroid Build Coastguard Worker /// primarily for the methods of the Variable class.
13*03ce13f7SAndroid Build Coastguard Worker ///
14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*03ce13f7SAndroid Build Coastguard Worker
16*03ce13f7SAndroid Build Coastguard Worker #include "IceOperand.h"
17*03ce13f7SAndroid Build Coastguard Worker
18*03ce13f7SAndroid Build Coastguard Worker #include "IceCfg.h"
19*03ce13f7SAndroid Build Coastguard Worker #include "IceCfgNode.h"
20*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h"
21*03ce13f7SAndroid Build Coastguard Worker #include "IceInstVarIter.h"
22*03ce13f7SAndroid Build Coastguard Worker #include "IceMemory.h"
23*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h" // dumping stack/frame pointer register
24*03ce13f7SAndroid Build Coastguard Worker
25*03ce13f7SAndroid Build Coastguard Worker namespace Ice {
26*03ce13f7SAndroid Build Coastguard Worker
initShouldBePooled()27*03ce13f7SAndroid Build Coastguard Worker void Constant::initShouldBePooled() {
28*03ce13f7SAndroid Build Coastguard Worker ShouldBePooled = TargetLowering::shouldBePooled(this);
29*03ce13f7SAndroid Build Coastguard Worker }
30*03ce13f7SAndroid Build Coastguard Worker
operator ==(const RelocatableTuple & A,const RelocatableTuple & B)31*03ce13f7SAndroid Build Coastguard Worker bool operator==(const RelocatableTuple &A, const RelocatableTuple &B) {
32*03ce13f7SAndroid Build Coastguard Worker // A and B are the same if:
33*03ce13f7SAndroid Build Coastguard Worker // (1) they have the same name; and
34*03ce13f7SAndroid Build Coastguard Worker // (2) they have the same offset.
35*03ce13f7SAndroid Build Coastguard Worker //
36*03ce13f7SAndroid Build Coastguard Worker // (1) is trivial to check, but (2) requires some care.
37*03ce13f7SAndroid Build Coastguard Worker //
38*03ce13f7SAndroid Build Coastguard Worker // For (2):
39*03ce13f7SAndroid Build Coastguard Worker // if A and B have known offsets (i.e., no symbolic references), then
40*03ce13f7SAndroid Build Coastguard Worker // A == B -> A.Offset == B.Offset.
41*03ce13f7SAndroid Build Coastguard Worker // else each element i in A.OffsetExpr[i] must be the same (or have the same
42*03ce13f7SAndroid Build Coastguard Worker // value) as B.OffsetExpr[i].
43*03ce13f7SAndroid Build Coastguard Worker if (A.Name != B.Name) {
44*03ce13f7SAndroid Build Coastguard Worker return false;
45*03ce13f7SAndroid Build Coastguard Worker }
46*03ce13f7SAndroid Build Coastguard Worker
47*03ce13f7SAndroid Build Coastguard Worker bool BothHaveKnownOffsets = true;
48*03ce13f7SAndroid Build Coastguard Worker RelocOffsetT OffsetA = A.Offset;
49*03ce13f7SAndroid Build Coastguard Worker RelocOffsetT OffsetB = B.Offset;
50*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < A.OffsetExpr.size() && BothHaveKnownOffsets; ++i) {
51*03ce13f7SAndroid Build Coastguard Worker BothHaveKnownOffsets = A.OffsetExpr[i]->hasOffset();
52*03ce13f7SAndroid Build Coastguard Worker if (BothHaveKnownOffsets) {
53*03ce13f7SAndroid Build Coastguard Worker OffsetA += A.OffsetExpr[i]->getOffset();
54*03ce13f7SAndroid Build Coastguard Worker }
55*03ce13f7SAndroid Build Coastguard Worker }
56*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < B.OffsetExpr.size() && BothHaveKnownOffsets; ++i) {
57*03ce13f7SAndroid Build Coastguard Worker BothHaveKnownOffsets = B.OffsetExpr[i]->hasOffset();
58*03ce13f7SAndroid Build Coastguard Worker if (BothHaveKnownOffsets) {
59*03ce13f7SAndroid Build Coastguard Worker OffsetB += B.OffsetExpr[i]->getOffset();
60*03ce13f7SAndroid Build Coastguard Worker }
61*03ce13f7SAndroid Build Coastguard Worker }
62*03ce13f7SAndroid Build Coastguard Worker if (BothHaveKnownOffsets) {
63*03ce13f7SAndroid Build Coastguard Worker // Both have known offsets (i.e., no unresolved symbolic references), so
64*03ce13f7SAndroid Build Coastguard Worker // A == B -> A.Offset == B.Offset.
65*03ce13f7SAndroid Build Coastguard Worker return OffsetA == OffsetB;
66*03ce13f7SAndroid Build Coastguard Worker }
67*03ce13f7SAndroid Build Coastguard Worker
68*03ce13f7SAndroid Build Coastguard Worker // Otherwise, A and B are not the same if their OffsetExpr's have different
69*03ce13f7SAndroid Build Coastguard Worker // sizes.
70*03ce13f7SAndroid Build Coastguard Worker if (A.OffsetExpr.size() != B.OffsetExpr.size()) {
71*03ce13f7SAndroid Build Coastguard Worker return false;
72*03ce13f7SAndroid Build Coastguard Worker }
73*03ce13f7SAndroid Build Coastguard Worker
74*03ce13f7SAndroid Build Coastguard Worker // If the OffsetExprs' sizes are the same, then
75*03ce13f7SAndroid Build Coastguard Worker // for each i in OffsetExprSize:
76*03ce13f7SAndroid Build Coastguard Worker for (SizeT i = 0; i < A.OffsetExpr.size(); ++i) {
77*03ce13f7SAndroid Build Coastguard Worker const auto *const RelocOffsetA = A.OffsetExpr[i];
78*03ce13f7SAndroid Build Coastguard Worker const auto *const RelocOffsetB = B.OffsetExpr[i];
79*03ce13f7SAndroid Build Coastguard Worker if (RelocOffsetA->hasOffset() && RelocOffsetB->hasOffset()) {
80*03ce13f7SAndroid Build Coastguard Worker // A.OffsetExpr[i].Offset == B.OffsetExpr[i].Offset iff they are both
81*03ce13f7SAndroid Build Coastguard Worker // defined;
82*03ce13f7SAndroid Build Coastguard Worker if (RelocOffsetA->getOffset() != RelocOffsetB->getOffset()) {
83*03ce13f7SAndroid Build Coastguard Worker return false;
84*03ce13f7SAndroid Build Coastguard Worker }
85*03ce13f7SAndroid Build Coastguard Worker } else if (RelocOffsetA != RelocOffsetB) {
86*03ce13f7SAndroid Build Coastguard Worker // or, if they are undefined, then the RelocOffsets must be the same.
87*03ce13f7SAndroid Build Coastguard Worker return false;
88*03ce13f7SAndroid Build Coastguard Worker }
89*03ce13f7SAndroid Build Coastguard Worker }
90*03ce13f7SAndroid Build Coastguard Worker
91*03ce13f7SAndroid Build Coastguard Worker return true;
92*03ce13f7SAndroid Build Coastguard Worker }
93*03ce13f7SAndroid Build Coastguard Worker
94*03ce13f7SAndroid Build Coastguard Worker RegNumT::BaseType RegNumT::Limit = 0;
95*03ce13f7SAndroid Build Coastguard Worker
operator <(const RegWeight & A,const RegWeight & B)96*03ce13f7SAndroid Build Coastguard Worker bool operator<(const RegWeight &A, const RegWeight &B) {
97*03ce13f7SAndroid Build Coastguard Worker return A.getWeight() < B.getWeight();
98*03ce13f7SAndroid Build Coastguard Worker }
operator <=(const RegWeight & A,const RegWeight & B)99*03ce13f7SAndroid Build Coastguard Worker bool operator<=(const RegWeight &A, const RegWeight &B) { return !(B < A); }
operator ==(const RegWeight & A,const RegWeight & B)100*03ce13f7SAndroid Build Coastguard Worker bool operator==(const RegWeight &A, const RegWeight &B) {
101*03ce13f7SAndroid Build Coastguard Worker return !(B < A) && !(A < B);
102*03ce13f7SAndroid Build Coastguard Worker }
103*03ce13f7SAndroid Build Coastguard Worker
addSegment(InstNumberT Start,InstNumberT End,CfgNode * Node)104*03ce13f7SAndroid Build Coastguard Worker void LiveRange::addSegment(InstNumberT Start, InstNumberT End, CfgNode *Node) {
105*03ce13f7SAndroid Build Coastguard Worker if (getFlags().getSplitGlobalVars()) {
106*03ce13f7SAndroid Build Coastguard Worker // Disable merging to make sure a live range 'segment' has a single node.
107*03ce13f7SAndroid Build Coastguard Worker // Might be possible to enable when the target segment has the same node.
108*03ce13f7SAndroid Build Coastguard Worker assert(NodeMap.find(Start) == NodeMap.end());
109*03ce13f7SAndroid Build Coastguard Worker NodeMap[Start] = Node;
110*03ce13f7SAndroid Build Coastguard Worker } else {
111*03ce13f7SAndroid Build Coastguard Worker if (!Range.empty()) {
112*03ce13f7SAndroid Build Coastguard Worker // Check for merge opportunity.
113*03ce13f7SAndroid Build Coastguard Worker InstNumberT CurrentEnd = Range.back().second;
114*03ce13f7SAndroid Build Coastguard Worker assert(Start >= CurrentEnd);
115*03ce13f7SAndroid Build Coastguard Worker if (Start == CurrentEnd) {
116*03ce13f7SAndroid Build Coastguard Worker Range.back().second = End;
117*03ce13f7SAndroid Build Coastguard Worker return;
118*03ce13f7SAndroid Build Coastguard Worker }
119*03ce13f7SAndroid Build Coastguard Worker }
120*03ce13f7SAndroid Build Coastguard Worker }
121*03ce13f7SAndroid Build Coastguard Worker Range.push_back(RangeElementType(Start, End));
122*03ce13f7SAndroid Build Coastguard Worker }
123*03ce13f7SAndroid Build Coastguard Worker
124*03ce13f7SAndroid Build Coastguard Worker // Returns true if this live range ends before Other's live range starts. This
125*03ce13f7SAndroid Build Coastguard Worker // means that the highest instruction number in this live range is less than or
126*03ce13f7SAndroid Build Coastguard Worker // equal to the lowest instruction number of the Other live range.
endsBefore(const LiveRange & Other) const127*03ce13f7SAndroid Build Coastguard Worker bool LiveRange::endsBefore(const LiveRange &Other) const {
128*03ce13f7SAndroid Build Coastguard Worker // Neither range should be empty, but let's be graceful.
129*03ce13f7SAndroid Build Coastguard Worker if (Range.empty() || Other.Range.empty())
130*03ce13f7SAndroid Build Coastguard Worker return true;
131*03ce13f7SAndroid Build Coastguard Worker InstNumberT MyEnd = (*Range.rbegin()).second;
132*03ce13f7SAndroid Build Coastguard Worker InstNumberT OtherStart = (*Other.Range.begin()).first;
133*03ce13f7SAndroid Build Coastguard Worker return MyEnd <= OtherStart;
134*03ce13f7SAndroid Build Coastguard Worker }
135*03ce13f7SAndroid Build Coastguard Worker
136*03ce13f7SAndroid Build Coastguard Worker // Returns true if there is any overlap between the two live ranges.
overlaps(const LiveRange & Other,bool UseTrimmed) const137*03ce13f7SAndroid Build Coastguard Worker bool LiveRange::overlaps(const LiveRange &Other, bool UseTrimmed) const {
138*03ce13f7SAndroid Build Coastguard Worker // Do a two-finger walk through the two sorted lists of segments.
139*03ce13f7SAndroid Build Coastguard Worker auto I1 = (UseTrimmed ? TrimmedBegin : Range.begin()),
140*03ce13f7SAndroid Build Coastguard Worker I2 = (UseTrimmed ? Other.TrimmedBegin : Other.Range.begin());
141*03ce13f7SAndroid Build Coastguard Worker auto E1 = Range.end(), E2 = Other.Range.end();
142*03ce13f7SAndroid Build Coastguard Worker while (I1 != E1 && I2 != E2) {
143*03ce13f7SAndroid Build Coastguard Worker if (I1->second <= I2->first) {
144*03ce13f7SAndroid Build Coastguard Worker ++I1;
145*03ce13f7SAndroid Build Coastguard Worker continue;
146*03ce13f7SAndroid Build Coastguard Worker }
147*03ce13f7SAndroid Build Coastguard Worker if (I2->second <= I1->first) {
148*03ce13f7SAndroid Build Coastguard Worker ++I2;
149*03ce13f7SAndroid Build Coastguard Worker continue;
150*03ce13f7SAndroid Build Coastguard Worker }
151*03ce13f7SAndroid Build Coastguard Worker return true;
152*03ce13f7SAndroid Build Coastguard Worker }
153*03ce13f7SAndroid Build Coastguard Worker return false;
154*03ce13f7SAndroid Build Coastguard Worker }
155*03ce13f7SAndroid Build Coastguard Worker
overlapsInst(InstNumberT OtherBegin,bool UseTrimmed) const156*03ce13f7SAndroid Build Coastguard Worker bool LiveRange::overlapsInst(InstNumberT OtherBegin, bool UseTrimmed) const {
157*03ce13f7SAndroid Build Coastguard Worker bool Result = false;
158*03ce13f7SAndroid Build Coastguard Worker for (auto I = (UseTrimmed ? TrimmedBegin : Range.begin()), E = Range.end();
159*03ce13f7SAndroid Build Coastguard Worker I != E; ++I) {
160*03ce13f7SAndroid Build Coastguard Worker if (OtherBegin < I->first) {
161*03ce13f7SAndroid Build Coastguard Worker Result = false;
162*03ce13f7SAndroid Build Coastguard Worker break;
163*03ce13f7SAndroid Build Coastguard Worker }
164*03ce13f7SAndroid Build Coastguard Worker if (OtherBegin < I->second) {
165*03ce13f7SAndroid Build Coastguard Worker Result = true;
166*03ce13f7SAndroid Build Coastguard Worker break;
167*03ce13f7SAndroid Build Coastguard Worker }
168*03ce13f7SAndroid Build Coastguard Worker }
169*03ce13f7SAndroid Build Coastguard Worker // This is an equivalent but less inefficient implementation. It's expensive
170*03ce13f7SAndroid Build Coastguard Worker // enough that we wouldn't want to run it under any build, but it could be
171*03ce13f7SAndroid Build Coastguard Worker // enabled if e.g. the LiveRange implementation changes and extra testing is
172*03ce13f7SAndroid Build Coastguard Worker // needed.
173*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::extraValidation()) {
174*03ce13f7SAndroid Build Coastguard Worker LiveRange Temp;
175*03ce13f7SAndroid Build Coastguard Worker Temp.addSegment(OtherBegin, OtherBegin + 1);
176*03ce13f7SAndroid Build Coastguard Worker bool Validation = overlaps(Temp);
177*03ce13f7SAndroid Build Coastguard Worker (void)Validation;
178*03ce13f7SAndroid Build Coastguard Worker assert(Result == Validation);
179*03ce13f7SAndroid Build Coastguard Worker }
180*03ce13f7SAndroid Build Coastguard Worker return Result;
181*03ce13f7SAndroid Build Coastguard Worker }
182*03ce13f7SAndroid Build Coastguard Worker
183*03ce13f7SAndroid Build Coastguard Worker // Returns true if the live range contains the given instruction number. This
184*03ce13f7SAndroid Build Coastguard Worker // is only used for validating the live range calculation. The IsDest argument
185*03ce13f7SAndroid Build Coastguard Worker // indicates whether the Variable being tested is used in the Dest position (as
186*03ce13f7SAndroid Build Coastguard Worker // opposed to a Src position).
containsValue(InstNumberT Value,bool IsDest) const187*03ce13f7SAndroid Build Coastguard Worker bool LiveRange::containsValue(InstNumberT Value, bool IsDest) const {
188*03ce13f7SAndroid Build Coastguard Worker for (const RangeElementType &I : Range) {
189*03ce13f7SAndroid Build Coastguard Worker if (I.first <= Value &&
190*03ce13f7SAndroid Build Coastguard Worker (Value < I.second || (!IsDest && Value == I.second)))
191*03ce13f7SAndroid Build Coastguard Worker return true;
192*03ce13f7SAndroid Build Coastguard Worker }
193*03ce13f7SAndroid Build Coastguard Worker return false;
194*03ce13f7SAndroid Build Coastguard Worker }
195*03ce13f7SAndroid Build Coastguard Worker
trim(InstNumberT Lower)196*03ce13f7SAndroid Build Coastguard Worker void LiveRange::trim(InstNumberT Lower) {
197*03ce13f7SAndroid Build Coastguard Worker while (TrimmedBegin != Range.end() && TrimmedBegin->second <= Lower)
198*03ce13f7SAndroid Build Coastguard Worker ++TrimmedBegin;
199*03ce13f7SAndroid Build Coastguard Worker }
200*03ce13f7SAndroid Build Coastguard Worker
asType(const Cfg * Func,Type Ty,RegNumT NewRegNum) const201*03ce13f7SAndroid Build Coastguard Worker const Variable *Variable::asType(const Cfg *Func, Type Ty,
202*03ce13f7SAndroid Build Coastguard Worker RegNumT NewRegNum) const {
203*03ce13f7SAndroid Build Coastguard Worker // Note: This returns a Variable, even if the "this" object is a subclass of
204*03ce13f7SAndroid Build Coastguard Worker // Variable.
205*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump() || getType() == Ty)
206*03ce13f7SAndroid Build Coastguard Worker return this;
207*03ce13f7SAndroid Build Coastguard Worker static constexpr SizeT One = 1;
208*03ce13f7SAndroid Build Coastguard Worker auto *V = new (CfgLocalAllocator<Variable>().allocate(One))
209*03ce13f7SAndroid Build Coastguard Worker Variable(Func, kVariable, Ty, Number);
210*03ce13f7SAndroid Build Coastguard Worker V->Name = Name;
211*03ce13f7SAndroid Build Coastguard Worker V->RegNum = NewRegNum.hasValue() ? NewRegNum : RegNum;
212*03ce13f7SAndroid Build Coastguard Worker V->StackOffset = StackOffset;
213*03ce13f7SAndroid Build Coastguard Worker V->LinkedTo = LinkedTo;
214*03ce13f7SAndroid Build Coastguard Worker return V;
215*03ce13f7SAndroid Build Coastguard Worker }
216*03ce13f7SAndroid Build Coastguard Worker
getWeight(const Cfg * Func) const217*03ce13f7SAndroid Build Coastguard Worker RegWeight Variable::getWeight(const Cfg *Func) const {
218*03ce13f7SAndroid Build Coastguard Worker if (mustHaveReg())
219*03ce13f7SAndroid Build Coastguard Worker return RegWeight(RegWeight::Inf);
220*03ce13f7SAndroid Build Coastguard Worker if (mustNotHaveReg())
221*03ce13f7SAndroid Build Coastguard Worker return RegWeight(RegWeight::Zero);
222*03ce13f7SAndroid Build Coastguard Worker return Func->getVMetadata()->getUseWeight(this);
223*03ce13f7SAndroid Build Coastguard Worker }
224*03ce13f7SAndroid Build Coastguard Worker
225*03ce13f7SAndroid Build Coastguard Worker int32_t
getRematerializableOffset(const::Ice::TargetLowering * Target)226*03ce13f7SAndroid Build Coastguard Worker Variable::getRematerializableOffset(const ::Ice::TargetLowering *Target) {
227*03ce13f7SAndroid Build Coastguard Worker int32_t Disp = getStackOffset();
228*03ce13f7SAndroid Build Coastguard Worker const auto RegNum = getRegNum();
229*03ce13f7SAndroid Build Coastguard Worker if (RegNum == Target->getFrameReg()) {
230*03ce13f7SAndroid Build Coastguard Worker Disp += Target->getFrameFixedAllocaOffset();
231*03ce13f7SAndroid Build Coastguard Worker } else if (RegNum != Target->getStackReg()) {
232*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error("Unexpected rematerializable register type");
233*03ce13f7SAndroid Build Coastguard Worker }
234*03ce13f7SAndroid Build Coastguard Worker return Disp;
235*03ce13f7SAndroid Build Coastguard Worker }
markUse(MetadataKind TrackingKind,const Inst * Instr,CfgNode * Node,bool IsImplicit)236*03ce13f7SAndroid Build Coastguard Worker void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr,
237*03ce13f7SAndroid Build Coastguard Worker CfgNode *Node, bool IsImplicit) {
238*03ce13f7SAndroid Build Coastguard Worker (void)TrackingKind;
239*03ce13f7SAndroid Build Coastguard Worker
240*03ce13f7SAndroid Build Coastguard Worker // Increment the use weight depending on the loop nest depth. The weight is
241*03ce13f7SAndroid Build Coastguard Worker // exponential in the nest depth as inner loops are expected to be executed
242*03ce13f7SAndroid Build Coastguard Worker // an exponentially greater number of times.
243*03ce13f7SAndroid Build Coastguard Worker constexpr uint32_t LogLoopTripCountEstimate = 2; // 2^2 = 4
244*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT MaxShift = sizeof(uint32_t) * CHAR_BIT - 1;
245*03ce13f7SAndroid Build Coastguard Worker constexpr SizeT MaxLoopNestDepth = MaxShift / LogLoopTripCountEstimate;
246*03ce13f7SAndroid Build Coastguard Worker const uint32_t LoopNestDepth =
247*03ce13f7SAndroid Build Coastguard Worker std::min(Node->getLoopNestDepth(), MaxLoopNestDepth);
248*03ce13f7SAndroid Build Coastguard Worker const uint32_t ThisUseWeight = uint32_t(1)
249*03ce13f7SAndroid Build Coastguard Worker << LoopNestDepth * LogLoopTripCountEstimate;
250*03ce13f7SAndroid Build Coastguard Worker UseWeight.addWeight(ThisUseWeight);
251*03ce13f7SAndroid Build Coastguard Worker
252*03ce13f7SAndroid Build Coastguard Worker if (MultiBlock == MBS_MultiBlock)
253*03ce13f7SAndroid Build Coastguard Worker return;
254*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): If the use occurs as a source operand in the first
255*03ce13f7SAndroid Build Coastguard Worker // instruction of the block, and its definition is in this block's only
256*03ce13f7SAndroid Build Coastguard Worker // predecessor, we might consider not marking this as a separate use. This
257*03ce13f7SAndroid Build Coastguard Worker // may also apply if it's the first instruction of the block that actually
258*03ce13f7SAndroid Build Coastguard Worker // uses a Variable.
259*03ce13f7SAndroid Build Coastguard Worker assert(Node);
260*03ce13f7SAndroid Build Coastguard Worker bool MakeMulti = false;
261*03ce13f7SAndroid Build Coastguard Worker if (IsImplicit)
262*03ce13f7SAndroid Build Coastguard Worker MakeMulti = true;
263*03ce13f7SAndroid Build Coastguard Worker // A phi source variable conservatively needs to be marked as multi-block,
264*03ce13f7SAndroid Build Coastguard Worker // even if its definition is in the same block. This is because there can be
265*03ce13f7SAndroid Build Coastguard Worker // additional control flow before branching back to this node, and the
266*03ce13f7SAndroid Build Coastguard Worker // variable is live throughout those nodes.
267*03ce13f7SAndroid Build Coastguard Worker if (Instr && llvm::isa<InstPhi>(Instr))
268*03ce13f7SAndroid Build Coastguard Worker MakeMulti = true;
269*03ce13f7SAndroid Build Coastguard Worker
270*03ce13f7SAndroid Build Coastguard Worker if (!MakeMulti) {
271*03ce13f7SAndroid Build Coastguard Worker switch (MultiBlock) {
272*03ce13f7SAndroid Build Coastguard Worker case MBS_Unknown:
273*03ce13f7SAndroid Build Coastguard Worker case MBS_NoUses:
274*03ce13f7SAndroid Build Coastguard Worker MultiBlock = MBS_SingleBlock;
275*03ce13f7SAndroid Build Coastguard Worker SingleUseNode = Node;
276*03ce13f7SAndroid Build Coastguard Worker break;
277*03ce13f7SAndroid Build Coastguard Worker case MBS_SingleBlock:
278*03ce13f7SAndroid Build Coastguard Worker if (SingleUseNode != Node)
279*03ce13f7SAndroid Build Coastguard Worker MakeMulti = true;
280*03ce13f7SAndroid Build Coastguard Worker break;
281*03ce13f7SAndroid Build Coastguard Worker case MBS_MultiBlock:
282*03ce13f7SAndroid Build Coastguard Worker break;
283*03ce13f7SAndroid Build Coastguard Worker }
284*03ce13f7SAndroid Build Coastguard Worker }
285*03ce13f7SAndroid Build Coastguard Worker
286*03ce13f7SAndroid Build Coastguard Worker if (MakeMulti) {
287*03ce13f7SAndroid Build Coastguard Worker MultiBlock = MBS_MultiBlock;
288*03ce13f7SAndroid Build Coastguard Worker SingleUseNode = nullptr;
289*03ce13f7SAndroid Build Coastguard Worker }
290*03ce13f7SAndroid Build Coastguard Worker }
291*03ce13f7SAndroid Build Coastguard Worker
markDef(MetadataKind TrackingKind,const Inst * Instr,CfgNode * Node)292*03ce13f7SAndroid Build Coastguard Worker void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr,
293*03ce13f7SAndroid Build Coastguard Worker CfgNode *Node) {
294*03ce13f7SAndroid Build Coastguard Worker // TODO(stichnot): If the definition occurs in the last instruction of the
295*03ce13f7SAndroid Build Coastguard Worker // block, consider not marking this as a separate use. But be careful not to
296*03ce13f7SAndroid Build Coastguard Worker // omit all uses of the variable if markDef() and markUse() both use this
297*03ce13f7SAndroid Build Coastguard Worker // optimization.
298*03ce13f7SAndroid Build Coastguard Worker assert(Node);
299*03ce13f7SAndroid Build Coastguard Worker // Verify that instructions are added in increasing order.
300*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::asserts()) {
301*03ce13f7SAndroid Build Coastguard Worker if (TrackingKind == VMK_All) {
302*03ce13f7SAndroid Build Coastguard Worker const Inst *LastInstruction =
303*03ce13f7SAndroid Build Coastguard Worker Definitions.empty() ? FirstOrSingleDefinition : Definitions.back();
304*03ce13f7SAndroid Build Coastguard Worker (void)LastInstruction;
305*03ce13f7SAndroid Build Coastguard Worker assert(LastInstruction == nullptr ||
306*03ce13f7SAndroid Build Coastguard Worker Instr->getNumber() >= LastInstruction->getNumber());
307*03ce13f7SAndroid Build Coastguard Worker }
308*03ce13f7SAndroid Build Coastguard Worker }
309*03ce13f7SAndroid Build Coastguard Worker constexpr bool IsImplicit = false;
310*03ce13f7SAndroid Build Coastguard Worker markUse(TrackingKind, Instr, Node, IsImplicit);
311*03ce13f7SAndroid Build Coastguard Worker if (TrackingKind == VMK_Uses)
312*03ce13f7SAndroid Build Coastguard Worker return;
313*03ce13f7SAndroid Build Coastguard Worker if (FirstOrSingleDefinition == nullptr)
314*03ce13f7SAndroid Build Coastguard Worker FirstOrSingleDefinition = Instr;
315*03ce13f7SAndroid Build Coastguard Worker else if (TrackingKind == VMK_All)
316*03ce13f7SAndroid Build Coastguard Worker Definitions.push_back(Instr);
317*03ce13f7SAndroid Build Coastguard Worker switch (MultiDef) {
318*03ce13f7SAndroid Build Coastguard Worker case MDS_Unknown:
319*03ce13f7SAndroid Build Coastguard Worker assert(SingleDefNode == nullptr);
320*03ce13f7SAndroid Build Coastguard Worker MultiDef = MDS_SingleDef;
321*03ce13f7SAndroid Build Coastguard Worker SingleDefNode = Node;
322*03ce13f7SAndroid Build Coastguard Worker break;
323*03ce13f7SAndroid Build Coastguard Worker case MDS_SingleDef:
324*03ce13f7SAndroid Build Coastguard Worker assert(SingleDefNode);
325*03ce13f7SAndroid Build Coastguard Worker if (Node == SingleDefNode) {
326*03ce13f7SAndroid Build Coastguard Worker MultiDef = MDS_MultiDefSingleBlock;
327*03ce13f7SAndroid Build Coastguard Worker } else {
328*03ce13f7SAndroid Build Coastguard Worker MultiDef = MDS_MultiDefMultiBlock;
329*03ce13f7SAndroid Build Coastguard Worker SingleDefNode = nullptr;
330*03ce13f7SAndroid Build Coastguard Worker }
331*03ce13f7SAndroid Build Coastguard Worker break;
332*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefSingleBlock:
333*03ce13f7SAndroid Build Coastguard Worker assert(SingleDefNode);
334*03ce13f7SAndroid Build Coastguard Worker if (Node != SingleDefNode) {
335*03ce13f7SAndroid Build Coastguard Worker MultiDef = MDS_MultiDefMultiBlock;
336*03ce13f7SAndroid Build Coastguard Worker SingleDefNode = nullptr;
337*03ce13f7SAndroid Build Coastguard Worker }
338*03ce13f7SAndroid Build Coastguard Worker break;
339*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefMultiBlock:
340*03ce13f7SAndroid Build Coastguard Worker assert(SingleDefNode == nullptr);
341*03ce13f7SAndroid Build Coastguard Worker break;
342*03ce13f7SAndroid Build Coastguard Worker }
343*03ce13f7SAndroid Build Coastguard Worker }
344*03ce13f7SAndroid Build Coastguard Worker
getFirstDefinitionSingleBlock() const345*03ce13f7SAndroid Build Coastguard Worker const Inst *VariableTracking::getFirstDefinitionSingleBlock() const {
346*03ce13f7SAndroid Build Coastguard Worker switch (MultiDef) {
347*03ce13f7SAndroid Build Coastguard Worker case MDS_Unknown:
348*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefMultiBlock:
349*03ce13f7SAndroid Build Coastguard Worker return nullptr;
350*03ce13f7SAndroid Build Coastguard Worker case MDS_SingleDef:
351*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefSingleBlock:
352*03ce13f7SAndroid Build Coastguard Worker assert(FirstOrSingleDefinition);
353*03ce13f7SAndroid Build Coastguard Worker return FirstOrSingleDefinition;
354*03ce13f7SAndroid Build Coastguard Worker }
355*03ce13f7SAndroid Build Coastguard Worker return nullptr;
356*03ce13f7SAndroid Build Coastguard Worker }
357*03ce13f7SAndroid Build Coastguard Worker
getSingleDefinition() const358*03ce13f7SAndroid Build Coastguard Worker const Inst *VariableTracking::getSingleDefinition() const {
359*03ce13f7SAndroid Build Coastguard Worker switch (MultiDef) {
360*03ce13f7SAndroid Build Coastguard Worker case MDS_Unknown:
361*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefMultiBlock:
362*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefSingleBlock:
363*03ce13f7SAndroid Build Coastguard Worker return nullptr;
364*03ce13f7SAndroid Build Coastguard Worker case MDS_SingleDef:
365*03ce13f7SAndroid Build Coastguard Worker assert(FirstOrSingleDefinition);
366*03ce13f7SAndroid Build Coastguard Worker return FirstOrSingleDefinition;
367*03ce13f7SAndroid Build Coastguard Worker }
368*03ce13f7SAndroid Build Coastguard Worker return nullptr;
369*03ce13f7SAndroid Build Coastguard Worker }
370*03ce13f7SAndroid Build Coastguard Worker
getFirstDefinition() const371*03ce13f7SAndroid Build Coastguard Worker const Inst *VariableTracking::getFirstDefinition() const {
372*03ce13f7SAndroid Build Coastguard Worker switch (MultiDef) {
373*03ce13f7SAndroid Build Coastguard Worker case MDS_Unknown:
374*03ce13f7SAndroid Build Coastguard Worker return nullptr;
375*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefMultiBlock:
376*03ce13f7SAndroid Build Coastguard Worker case MDS_SingleDef:
377*03ce13f7SAndroid Build Coastguard Worker case MDS_MultiDefSingleBlock:
378*03ce13f7SAndroid Build Coastguard Worker assert(FirstOrSingleDefinition);
379*03ce13f7SAndroid Build Coastguard Worker return FirstOrSingleDefinition;
380*03ce13f7SAndroid Build Coastguard Worker }
381*03ce13f7SAndroid Build Coastguard Worker return nullptr;
382*03ce13f7SAndroid Build Coastguard Worker }
383*03ce13f7SAndroid Build Coastguard Worker
init(MetadataKind TrackingKind)384*03ce13f7SAndroid Build Coastguard Worker void VariablesMetadata::init(MetadataKind TrackingKind) {
385*03ce13f7SAndroid Build Coastguard Worker TimerMarker T(TimerStack::TT_vmetadata, Func);
386*03ce13f7SAndroid Build Coastguard Worker Kind = TrackingKind;
387*03ce13f7SAndroid Build Coastguard Worker Metadata.clear();
388*03ce13f7SAndroid Build Coastguard Worker Metadata.resize(Func->getNumVariables(), VariableTracking::MBS_NoUses);
389*03ce13f7SAndroid Build Coastguard Worker
390*03ce13f7SAndroid Build Coastguard Worker // Mark implicit args as being used in the entry node.
391*03ce13f7SAndroid Build Coastguard Worker for (Variable *Var : Func->getImplicitArgs()) {
392*03ce13f7SAndroid Build Coastguard Worker constexpr Inst *NoInst = nullptr;
393*03ce13f7SAndroid Build Coastguard Worker CfgNode *EntryNode = Func->getEntryNode();
394*03ce13f7SAndroid Build Coastguard Worker constexpr bool IsImplicit = true;
395*03ce13f7SAndroid Build Coastguard Worker Metadata[Var->getIndex()].markUse(Kind, NoInst, EntryNode, IsImplicit);
396*03ce13f7SAndroid Build Coastguard Worker }
397*03ce13f7SAndroid Build Coastguard Worker
398*03ce13f7SAndroid Build Coastguard Worker for (CfgNode *Node : Func->getNodes())
399*03ce13f7SAndroid Build Coastguard Worker addNode(Node);
400*03ce13f7SAndroid Build Coastguard Worker }
401*03ce13f7SAndroid Build Coastguard Worker
addNode(CfgNode * Node)402*03ce13f7SAndroid Build Coastguard Worker void VariablesMetadata::addNode(CfgNode *Node) {
403*03ce13f7SAndroid Build Coastguard Worker if (Func->getNumVariables() > Metadata.size())
404*03ce13f7SAndroid Build Coastguard Worker Metadata.resize(Func->getNumVariables());
405*03ce13f7SAndroid Build Coastguard Worker
406*03ce13f7SAndroid Build Coastguard Worker for (Inst &I : Node->getPhis()) {
407*03ce13f7SAndroid Build Coastguard Worker if (I.isDeleted())
408*03ce13f7SAndroid Build Coastguard Worker continue;
409*03ce13f7SAndroid Build Coastguard Worker if (Variable *Dest = I.getDest()) {
410*03ce13f7SAndroid Build Coastguard Worker SizeT DestNum = Dest->getIndex();
411*03ce13f7SAndroid Build Coastguard Worker assert(DestNum < Metadata.size());
412*03ce13f7SAndroid Build Coastguard Worker Metadata[DestNum].markDef(Kind, &I, Node);
413*03ce13f7SAndroid Build Coastguard Worker }
414*03ce13f7SAndroid Build Coastguard Worker for (SizeT SrcNum = 0; SrcNum < I.getSrcSize(); ++SrcNum) {
415*03ce13f7SAndroid Build Coastguard Worker if (auto *Var = llvm::dyn_cast<Variable>(I.getSrc(SrcNum))) {
416*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
417*03ce13f7SAndroid Build Coastguard Worker assert(VarNum < Metadata.size());
418*03ce13f7SAndroid Build Coastguard Worker constexpr bool IsImplicit = false;
419*03ce13f7SAndroid Build Coastguard Worker Metadata[VarNum].markUse(Kind, &I, Node, IsImplicit);
420*03ce13f7SAndroid Build Coastguard Worker }
421*03ce13f7SAndroid Build Coastguard Worker }
422*03ce13f7SAndroid Build Coastguard Worker }
423*03ce13f7SAndroid Build Coastguard Worker
424*03ce13f7SAndroid Build Coastguard Worker for (Inst &I : Node->getInsts()) {
425*03ce13f7SAndroid Build Coastguard Worker if (I.isDeleted())
426*03ce13f7SAndroid Build Coastguard Worker continue;
427*03ce13f7SAndroid Build Coastguard Worker // Note: The implicit definitions (and uses) from InstFakeKill are
428*03ce13f7SAndroid Build Coastguard Worker // deliberately ignored.
429*03ce13f7SAndroid Build Coastguard Worker if (Variable *Dest = I.getDest()) {
430*03ce13f7SAndroid Build Coastguard Worker SizeT DestNum = Dest->getIndex();
431*03ce13f7SAndroid Build Coastguard Worker assert(DestNum < Metadata.size());
432*03ce13f7SAndroid Build Coastguard Worker Metadata[DestNum].markDef(Kind, &I, Node);
433*03ce13f7SAndroid Build Coastguard Worker }
434*03ce13f7SAndroid Build Coastguard Worker FOREACH_VAR_IN_INST(Var, I) {
435*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
436*03ce13f7SAndroid Build Coastguard Worker assert(VarNum < Metadata.size());
437*03ce13f7SAndroid Build Coastguard Worker constexpr bool IsImplicit = false;
438*03ce13f7SAndroid Build Coastguard Worker Metadata[VarNum].markUse(Kind, &I, Node, IsImplicit);
439*03ce13f7SAndroid Build Coastguard Worker }
440*03ce13f7SAndroid Build Coastguard Worker }
441*03ce13f7SAndroid Build Coastguard Worker }
442*03ce13f7SAndroid Build Coastguard Worker
isMultiDef(const Variable * Var) const443*03ce13f7SAndroid Build Coastguard Worker bool VariablesMetadata::isMultiDef(const Variable *Var) const {
444*03ce13f7SAndroid Build Coastguard Worker assert(Kind != VMK_Uses);
445*03ce13f7SAndroid Build Coastguard Worker if (Var->getIsArg())
446*03ce13f7SAndroid Build Coastguard Worker return false;
447*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
448*03ce13f7SAndroid Build Coastguard Worker return true; // conservative answer
449*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
450*03ce13f7SAndroid Build Coastguard Worker // Conservatively return true if the state is unknown.
451*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef;
452*03ce13f7SAndroid Build Coastguard Worker }
453*03ce13f7SAndroid Build Coastguard Worker
isMultiBlock(const Variable * Var) const454*03ce13f7SAndroid Build Coastguard Worker bool VariablesMetadata::isMultiBlock(const Variable *Var) const {
455*03ce13f7SAndroid Build Coastguard Worker if (Var->getIsArg())
456*03ce13f7SAndroid Build Coastguard Worker return true;
457*03ce13f7SAndroid Build Coastguard Worker if (Var->isRematerializable())
458*03ce13f7SAndroid Build Coastguard Worker return false;
459*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
460*03ce13f7SAndroid Build Coastguard Worker return true; // conservative answer
461*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
462*03ce13f7SAndroid Build Coastguard Worker switch (Metadata[VarNum].getMultiBlock()) {
463*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_NoUses:
464*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_SingleBlock:
465*03ce13f7SAndroid Build Coastguard Worker return false;
466*03ce13f7SAndroid Build Coastguard Worker // Conservatively return true if the state is unknown.
467*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_Unknown:
468*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_MultiBlock:
469*03ce13f7SAndroid Build Coastguard Worker return true;
470*03ce13f7SAndroid Build Coastguard Worker }
471*03ce13f7SAndroid Build Coastguard Worker assert(0);
472*03ce13f7SAndroid Build Coastguard Worker return true;
473*03ce13f7SAndroid Build Coastguard Worker }
474*03ce13f7SAndroid Build Coastguard Worker
isSingleBlock(const Variable * Var) const475*03ce13f7SAndroid Build Coastguard Worker bool VariablesMetadata::isSingleBlock(const Variable *Var) const {
476*03ce13f7SAndroid Build Coastguard Worker if (Var->getIsArg())
477*03ce13f7SAndroid Build Coastguard Worker return false;
478*03ce13f7SAndroid Build Coastguard Worker if (Var->isRematerializable())
479*03ce13f7SAndroid Build Coastguard Worker return false;
480*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
481*03ce13f7SAndroid Build Coastguard Worker return false; // conservative answer
482*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
483*03ce13f7SAndroid Build Coastguard Worker switch (Metadata[VarNum].getMultiBlock()) {
484*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_SingleBlock:
485*03ce13f7SAndroid Build Coastguard Worker return true;
486*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_Unknown:
487*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_NoUses:
488*03ce13f7SAndroid Build Coastguard Worker case VariableTracking::MBS_MultiBlock:
489*03ce13f7SAndroid Build Coastguard Worker return false;
490*03ce13f7SAndroid Build Coastguard Worker }
491*03ce13f7SAndroid Build Coastguard Worker assert(0);
492*03ce13f7SAndroid Build Coastguard Worker return false;
493*03ce13f7SAndroid Build Coastguard Worker }
494*03ce13f7SAndroid Build Coastguard Worker
495*03ce13f7SAndroid Build Coastguard Worker const Inst *
getFirstDefinitionSingleBlock(const Variable * Var) const496*03ce13f7SAndroid Build Coastguard Worker VariablesMetadata::getFirstDefinitionSingleBlock(const Variable *Var) const {
497*03ce13f7SAndroid Build Coastguard Worker assert(Kind != VMK_Uses);
498*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
499*03ce13f7SAndroid Build Coastguard Worker return nullptr; // conservative answer
500*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
501*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getFirstDefinitionSingleBlock();
502*03ce13f7SAndroid Build Coastguard Worker }
503*03ce13f7SAndroid Build Coastguard Worker
getSingleDefinition(const Variable * Var) const504*03ce13f7SAndroid Build Coastguard Worker const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const {
505*03ce13f7SAndroid Build Coastguard Worker assert(Kind != VMK_Uses);
506*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
507*03ce13f7SAndroid Build Coastguard Worker return nullptr; // conservative answer
508*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
509*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getSingleDefinition();
510*03ce13f7SAndroid Build Coastguard Worker }
511*03ce13f7SAndroid Build Coastguard Worker
getFirstDefinition(const Variable * Var) const512*03ce13f7SAndroid Build Coastguard Worker const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const {
513*03ce13f7SAndroid Build Coastguard Worker assert(Kind != VMK_Uses);
514*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
515*03ce13f7SAndroid Build Coastguard Worker return nullptr; // conservative answer
516*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
517*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getFirstDefinition();
518*03ce13f7SAndroid Build Coastguard Worker }
519*03ce13f7SAndroid Build Coastguard Worker
520*03ce13f7SAndroid Build Coastguard Worker const InstDefList &
getLatterDefinitions(const Variable * Var) const521*03ce13f7SAndroid Build Coastguard Worker VariablesMetadata::getLatterDefinitions(const Variable *Var) const {
522*03ce13f7SAndroid Build Coastguard Worker assert(Kind == VMK_All);
523*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var)) {
524*03ce13f7SAndroid Build Coastguard Worker // NoDefinitions has to be initialized after we've had a chance to set the
525*03ce13f7SAndroid Build Coastguard Worker // CfgAllocator, so it can't be a static global object. Also, while C++11
526*03ce13f7SAndroid Build Coastguard Worker // guarantees the initialization of static local objects to be thread-safe,
527*03ce13f7SAndroid Build Coastguard Worker // we use a pointer to it so we can avoid frequent mutex locking overhead.
528*03ce13f7SAndroid Build Coastguard Worker if (NoDefinitions == nullptr) {
529*03ce13f7SAndroid Build Coastguard Worker static const InstDefList NoDefinitionsInstance;
530*03ce13f7SAndroid Build Coastguard Worker NoDefinitions = &NoDefinitionsInstance;
531*03ce13f7SAndroid Build Coastguard Worker }
532*03ce13f7SAndroid Build Coastguard Worker return *NoDefinitions;
533*03ce13f7SAndroid Build Coastguard Worker }
534*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
535*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getLatterDefinitions();
536*03ce13f7SAndroid Build Coastguard Worker }
537*03ce13f7SAndroid Build Coastguard Worker
getLocalUseNode(const Variable * Var) const538*03ce13f7SAndroid Build Coastguard Worker CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const {
539*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
540*03ce13f7SAndroid Build Coastguard Worker return nullptr; // conservative answer
541*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
542*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getNode();
543*03ce13f7SAndroid Build Coastguard Worker }
544*03ce13f7SAndroid Build Coastguard Worker
getUseWeight(const Variable * Var) const545*03ce13f7SAndroid Build Coastguard Worker RegWeight VariablesMetadata::getUseWeight(const Variable *Var) const {
546*03ce13f7SAndroid Build Coastguard Worker if (!isTracked(Var))
547*03ce13f7SAndroid Build Coastguard Worker return RegWeight(1); // conservative answer
548*03ce13f7SAndroid Build Coastguard Worker SizeT VarNum = Var->getIndex();
549*03ce13f7SAndroid Build Coastguard Worker return Metadata[VarNum].getUseWeight();
550*03ce13f7SAndroid Build Coastguard Worker }
551*03ce13f7SAndroid Build Coastguard Worker
552*03ce13f7SAndroid Build Coastguard Worker const InstDefList *VariablesMetadata::NoDefinitions = nullptr;
553*03ce13f7SAndroid Build Coastguard Worker
554*03ce13f7SAndroid Build Coastguard Worker // ======================== dump routines ======================== //
555*03ce13f7SAndroid Build Coastguard Worker
emit(const Cfg * Func) const556*03ce13f7SAndroid Build Coastguard Worker void Variable::emit(const Cfg *Func) const {
557*03ce13f7SAndroid Build Coastguard Worker if (BuildDefs::dump())
558*03ce13f7SAndroid Build Coastguard Worker Func->getTarget()->emitVariable(this);
559*03ce13f7SAndroid Build Coastguard Worker }
560*03ce13f7SAndroid Build Coastguard Worker
dump(const Cfg * Func,Ostream & Str) const561*03ce13f7SAndroid Build Coastguard Worker void Variable::dump(const Cfg *Func, Ostream &Str) const {
562*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
563*03ce13f7SAndroid Build Coastguard Worker return;
564*03ce13f7SAndroid Build Coastguard Worker if (Func == nullptr) {
565*03ce13f7SAndroid Build Coastguard Worker Str << "%" << getName();
566*03ce13f7SAndroid Build Coastguard Worker return;
567*03ce13f7SAndroid Build Coastguard Worker }
568*03ce13f7SAndroid Build Coastguard Worker if (Func->isVerbose(IceV_RegOrigins) ||
569*03ce13f7SAndroid Build Coastguard Worker (!hasReg() && !Func->getTarget()->hasComputedFrame())) {
570*03ce13f7SAndroid Build Coastguard Worker Str << "%" << getName();
571*03ce13f7SAndroid Build Coastguard Worker for (Variable *Link = getLinkedTo(); Link != nullptr;
572*03ce13f7SAndroid Build Coastguard Worker Link = Link->getLinkedTo()) {
573*03ce13f7SAndroid Build Coastguard Worker Str << ":%" << Link->getName();
574*03ce13f7SAndroid Build Coastguard Worker }
575*03ce13f7SAndroid Build Coastguard Worker }
576*03ce13f7SAndroid Build Coastguard Worker if (hasReg()) {
577*03ce13f7SAndroid Build Coastguard Worker if (Func->isVerbose(IceV_RegOrigins))
578*03ce13f7SAndroid Build Coastguard Worker Str << ":";
579*03ce13f7SAndroid Build Coastguard Worker Str << Func->getTarget()->getRegName(RegNum, getType());
580*03ce13f7SAndroid Build Coastguard Worker } else if (Func->getTarget()->hasComputedFrame()) {
581*03ce13f7SAndroid Build Coastguard Worker if (Func->isVerbose(IceV_RegOrigins))
582*03ce13f7SAndroid Build Coastguard Worker Str << ":";
583*03ce13f7SAndroid Build Coastguard Worker const auto BaseRegisterNumber =
584*03ce13f7SAndroid Build Coastguard Worker hasReg() ? getBaseRegNum() : Func->getTarget()->getFrameOrStackReg();
585*03ce13f7SAndroid Build Coastguard Worker Str << "["
586*03ce13f7SAndroid Build Coastguard Worker << Func->getTarget()->getRegName(BaseRegisterNumber, IceType_i32);
587*03ce13f7SAndroid Build Coastguard Worker if (hasKnownStackOffset()) {
588*03ce13f7SAndroid Build Coastguard Worker int32_t Offset = getStackOffset();
589*03ce13f7SAndroid Build Coastguard Worker if (Offset) {
590*03ce13f7SAndroid Build Coastguard Worker if (Offset > 0)
591*03ce13f7SAndroid Build Coastguard Worker Str << "+";
592*03ce13f7SAndroid Build Coastguard Worker Str << Offset;
593*03ce13f7SAndroid Build Coastguard Worker }
594*03ce13f7SAndroid Build Coastguard Worker }
595*03ce13f7SAndroid Build Coastguard Worker Str << "]";
596*03ce13f7SAndroid Build Coastguard Worker }
597*03ce13f7SAndroid Build Coastguard Worker }
598*03ce13f7SAndroid Build Coastguard Worker
emit(TargetLowering * Target) const599*03ce13f7SAndroid Build Coastguard Worker template <> void ConstantInteger32::emit(TargetLowering *Target) const {
600*03ce13f7SAndroid Build Coastguard Worker Target->emit(this);
601*03ce13f7SAndroid Build Coastguard Worker }
602*03ce13f7SAndroid Build Coastguard Worker
emit(TargetLowering * Target) const603*03ce13f7SAndroid Build Coastguard Worker template <> void ConstantInteger64::emit(TargetLowering *Target) const {
604*03ce13f7SAndroid Build Coastguard Worker Target->emit(this);
605*03ce13f7SAndroid Build Coastguard Worker }
606*03ce13f7SAndroid Build Coastguard Worker
emit(TargetLowering * Target) const607*03ce13f7SAndroid Build Coastguard Worker template <> void ConstantFloat::emit(TargetLowering *Target) const {
608*03ce13f7SAndroid Build Coastguard Worker Target->emit(this);
609*03ce13f7SAndroid Build Coastguard Worker }
610*03ce13f7SAndroid Build Coastguard Worker
emit(TargetLowering * Target) const611*03ce13f7SAndroid Build Coastguard Worker template <> void ConstantDouble::emit(TargetLowering *Target) const {
612*03ce13f7SAndroid Build Coastguard Worker Target->emit(this);
613*03ce13f7SAndroid Build Coastguard Worker }
614*03ce13f7SAndroid Build Coastguard Worker
emit(TargetLowering * Target) const615*03ce13f7SAndroid Build Coastguard Worker void ConstantRelocatable::emit(TargetLowering *Target) const {
616*03ce13f7SAndroid Build Coastguard Worker Target->emit(this);
617*03ce13f7SAndroid Build Coastguard Worker }
618*03ce13f7SAndroid Build Coastguard Worker
emitWithoutPrefix(const TargetLowering * Target,const char * Suffix) const619*03ce13f7SAndroid Build Coastguard Worker void ConstantRelocatable::emitWithoutPrefix(const TargetLowering *Target,
620*03ce13f7SAndroid Build Coastguard Worker const char *Suffix) const {
621*03ce13f7SAndroid Build Coastguard Worker Target->emitWithoutPrefix(this, Suffix);
622*03ce13f7SAndroid Build Coastguard Worker }
623*03ce13f7SAndroid Build Coastguard Worker
dump(const Cfg *,Ostream & Str) const624*03ce13f7SAndroid Build Coastguard Worker void ConstantRelocatable::dump(const Cfg *, Ostream &Str) const {
625*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
626*03ce13f7SAndroid Build Coastguard Worker return;
627*03ce13f7SAndroid Build Coastguard Worker if (!EmitString.empty()) {
628*03ce13f7SAndroid Build Coastguard Worker Str << EmitString;
629*03ce13f7SAndroid Build Coastguard Worker return;
630*03ce13f7SAndroid Build Coastguard Worker }
631*03ce13f7SAndroid Build Coastguard Worker Str << "@" << (Name.hasStdString() ? Name.toString() : "<Unnamed>");
632*03ce13f7SAndroid Build Coastguard Worker const RelocOffsetT Offset = getOffset();
633*03ce13f7SAndroid Build Coastguard Worker if (Offset) {
634*03ce13f7SAndroid Build Coastguard Worker if (Offset >= 0) {
635*03ce13f7SAndroid Build Coastguard Worker Str << "+";
636*03ce13f7SAndroid Build Coastguard Worker }
637*03ce13f7SAndroid Build Coastguard Worker Str << Offset;
638*03ce13f7SAndroid Build Coastguard Worker }
639*03ce13f7SAndroid Build Coastguard Worker }
640*03ce13f7SAndroid Build Coastguard Worker
emit(TargetLowering * Target) const641*03ce13f7SAndroid Build Coastguard Worker void ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); }
642*03ce13f7SAndroid Build Coastguard Worker
dump(Ostream & Str) const643*03ce13f7SAndroid Build Coastguard Worker void LiveRange::dump(Ostream &Str) const {
644*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
645*03ce13f7SAndroid Build Coastguard Worker return;
646*03ce13f7SAndroid Build Coastguard Worker bool First = true;
647*03ce13f7SAndroid Build Coastguard Worker for (const RangeElementType &I : Range) {
648*03ce13f7SAndroid Build Coastguard Worker if (!First)
649*03ce13f7SAndroid Build Coastguard Worker Str << ", ";
650*03ce13f7SAndroid Build Coastguard Worker First = false;
651*03ce13f7SAndroid Build Coastguard Worker Str << "[" << I.first << ":" << I.second << ")";
652*03ce13f7SAndroid Build Coastguard Worker }
653*03ce13f7SAndroid Build Coastguard Worker }
654*03ce13f7SAndroid Build Coastguard Worker
operator <<(Ostream & Str,const LiveRange & L)655*03ce13f7SAndroid Build Coastguard Worker Ostream &operator<<(Ostream &Str, const LiveRange &L) {
656*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
657*03ce13f7SAndroid Build Coastguard Worker return Str;
658*03ce13f7SAndroid Build Coastguard Worker L.dump(Str);
659*03ce13f7SAndroid Build Coastguard Worker return Str;
660*03ce13f7SAndroid Build Coastguard Worker }
661*03ce13f7SAndroid Build Coastguard Worker
operator <<(Ostream & Str,const RegWeight & W)662*03ce13f7SAndroid Build Coastguard Worker Ostream &operator<<(Ostream &Str, const RegWeight &W) {
663*03ce13f7SAndroid Build Coastguard Worker if (!BuildDefs::dump())
664*03ce13f7SAndroid Build Coastguard Worker return Str;
665*03ce13f7SAndroid Build Coastguard Worker if (W.getWeight() == RegWeight::Inf)
666*03ce13f7SAndroid Build Coastguard Worker Str << "Inf";
667*03ce13f7SAndroid Build Coastguard Worker else
668*03ce13f7SAndroid Build Coastguard Worker Str << W.getWeight();
669*03ce13f7SAndroid Build Coastguard Worker return Str;
670*03ce13f7SAndroid Build Coastguard Worker }
671*03ce13f7SAndroid Build Coastguard Worker
672*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice
673