1f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//===- subzero/src/IceOperand.cpp - High-level operand implementation -----===//
2f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
3f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//                        The Subzero Code Generator
4f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
5f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// This file is distributed under the University of Illinois Open Source
6f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// License. See LICENSE.TXT for details.
7f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//
8f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//===----------------------------------------------------------------------===//
99612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull///
109612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// \file
1192a6e5b08ec68e7076d637ebc680da2fcc346a00Jim Stichnoth/// \brief Implements the Operand class and its target-independent subclasses,
1292a6e5b08ec68e7076d637ebc680da2fcc346a00Jim Stichnoth/// primarily for the methods of the Variable class.
139612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull///
14f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth//===----------------------------------------------------------------------===//
15f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
1667f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "IceOperand.h"
1767f8de9adf6439881a00d8e0f081918436c71f62John Porto
18f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#include "IceCfg.h"
19144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth#include "IceCfgNode.h"
20f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth#include "IceInst.h"
21ec3f56532be1792d04ed470221df663bb8ca9c19John Porto#include "IceInstVarIter.h"
22e82b560e649f8a68bcb252b9b002708e74d962d3John Porto#include "IceMemory.h"
235bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth#include "IceTargetLowering.h" // dumping stack/frame pointer register
24f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
25f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnothnamespace Ice {
26f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
27467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnothvoid Constant::initShouldBePooled() {
28467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth  ShouldBePooled = TargetLowering::shouldBePooled(this);
29467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth}
30467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth
31d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnothbool operator==(const RelocatableTuple &A, const RelocatableTuple &B) {
3227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // A and B are the same if:
3327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //   (1) they have the same name; and
3427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //   (2) they have the same offset.
3527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //
3627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // (1) is trivial to check, but (2) requires some care.
3727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //
3827fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // For (2):
3927fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //  if A and B have known offsets (i.e., no symbolic references), then
4027fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //     A == B -> A.Offset == B.Offset.
4127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //  else each element i in A.OffsetExpr[i] must be the same (or have the same
4227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  //    value) as B.OffsetExpr[i].
4327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  if (A.Name != B.Name) {
4427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    return false;
4527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
4627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto
4727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  bool BothHaveKnownOffsets = true;
48e82b560e649f8a68bcb252b9b002708e74d962d3John Porto  RelocOffsetT OffsetA = A.Offset;
49e82b560e649f8a68bcb252b9b002708e74d962d3John Porto  RelocOffsetT OffsetB = B.Offset;
5027fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  for (SizeT i = 0; i < A.OffsetExpr.size() && BothHaveKnownOffsets; ++i) {
5127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    BothHaveKnownOffsets = A.OffsetExpr[i]->hasOffset();
5227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    if (BothHaveKnownOffsets) {
5327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      OffsetA += A.OffsetExpr[i]->getOffset();
5427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    }
5527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
5627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  for (SizeT i = 0; i < B.OffsetExpr.size() && BothHaveKnownOffsets; ++i) {
5727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    BothHaveKnownOffsets = B.OffsetExpr[i]->hasOffset();
5827fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    if (BothHaveKnownOffsets) {
5927fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      OffsetB += B.OffsetExpr[i]->getOffset();
6027fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    }
6127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
6227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  if (BothHaveKnownOffsets) {
6327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    // Both have known offsets (i.e., no unresolved symbolic references), so
6427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    // A == B -> A.Offset == B.Offset.
6527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    return OffsetA == OffsetB;
6627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
6727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto
6827fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // Otherwise, A and B are not the same if their OffsetExpr's have different
6927fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // sizes.
7027fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  if (A.OffsetExpr.size() != B.OffsetExpr.size()) {
7127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    return false;
7227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
7327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto
7427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // If the OffsetExprs' sizes are the same, then
7527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  // for each i in OffsetExprSize:
7627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  for (SizeT i = 0; i < A.OffsetExpr.size(); ++i) {
7727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    const auto *const RelocOffsetA = A.OffsetExpr[i];
7827fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    const auto *const RelocOffsetB = B.OffsetExpr[i];
7927fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    if (RelocOffsetA->hasOffset() && RelocOffsetB->hasOffset()) {
8027fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      // A.OffsetExpr[i].Offset == B.OffsetExpr[i].Offset iff they are both
8127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      // defined;
8227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      if (RelocOffsetA->getOffset() != RelocOffsetB->getOffset()) {
8327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto        return false;
8427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      }
8527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    } else if (RelocOffsetA != RelocOffsetB) {
8627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      // or, if they are undefined, then the RelocOffsets must be the same.
8727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      return false;
8827fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    }
8927fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
9027fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto
9127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  return true;
92f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth}
93f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
948aa396610b7baf728631a43ea16ad3d13e38397aJim StichnothRegNumT::BaseType RegNumT::Limit = 0;
958aa396610b7baf728631a43ea16ad3d13e38397aJim Stichnoth
965bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothbool operator<(const RegWeight &A, const RegWeight &B) {
975bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  return A.getWeight() < B.getWeight();
985bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth}
995bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothbool operator<=(const RegWeight &A, const RegWeight &B) { return !(B < A); }
1005bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothbool operator==(const RegWeight &A, const RegWeight &B) {
1015bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  return !(B < A) && !(A < B);
1025bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth}
1035bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
1047cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjeevoid LiveRange::addSegment(InstNumberT Start, InstNumberT End, CfgNode *Node) {
1057cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee  if (getFlags().getSplitGlobalVars()) {
1067cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee    // Disable merging to make sure a live range 'segment' has a single node.
1077cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee    // Might be possible to enable when the target segment has the same node.
1087cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee    assert(NodeMap.find(Start) == NodeMap.end());
1097cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee    NodeMap[Start] = Node;
1107cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee  } else {
1117cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee    if (!Range.empty()) {
1127cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee      // Check for merge opportunity.
1137cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee      InstNumberT CurrentEnd = Range.back().second;
1147cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee      assert(Start >= CurrentEnd);
1157cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee      if (Start == CurrentEnd) {
1167cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee        Range.back().second = End;
1177cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee        return;
1187cd926d6d4f401dd3595e0682f48ede3e04ac7f7Manasij Mukherjee      }
119e5b73e6e3aa4e9f9819494d34662f3f6d928b078Jim Stichnoth    }
120d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  }
121d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  Range.push_back(RangeElementType(Start, End));
122d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
123d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
12457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Returns true if this live range ends before Other's live range starts. This
12557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// means that the highest instruction number in this live range is less than or
12657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// equal to the lowest instruction number of the Other live range.
127d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnothbool LiveRange::endsBefore(const LiveRange &Other) const {
128d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // Neither range should be empty, but let's be graceful.
129d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  if (Range.empty() || Other.Range.empty())
130d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    return true;
131d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  InstNumberT MyEnd = (*Range.rbegin()).second;
132d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  InstNumberT OtherStart = (*Other.Range.begin()).first;
133d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  return MyEnd <= OtherStart;
134d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
135d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
136d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth// Returns true if there is any overlap between the two live ranges.
137037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnothbool LiveRange::overlaps(const LiveRange &Other, bool UseTrimmed) const {
138d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  // Do a two-finger walk through the two sorted lists of segments.
139037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth  auto I1 = (UseTrimmed ? TrimmedBegin : Range.begin()),
140037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth       I2 = (UseTrimmed ? Other.TrimmedBegin : Other.Range.begin());
141037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth  auto E1 = Range.end(), E2 = Other.Range.end();
142d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  while (I1 != E1 && I2 != E2) {
143d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    if (I1->second <= I2->first) {
144d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      ++I1;
145d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      continue;
146d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    }
147d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    if (I2->second <= I1->first) {
148d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      ++I2;
149d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      continue;
150d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    }
151d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth    return true;
152d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  }
153d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  return false;
154d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
155d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
156037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnothbool LiveRange::overlapsInst(InstNumberT OtherBegin, bool UseTrimmed) const {
157c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth  bool Result = false;
158037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth  for (auto I = (UseTrimmed ? TrimmedBegin : Range.begin()), E = Range.end();
159037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth       I != E; ++I) {
160037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth    if (OtherBegin < I->first) {
161c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth      Result = false;
162c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth      break;
163c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth    }
164037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth    if (OtherBegin < I->second) {
165c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth      Result = true;
166c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth      break;
167c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth    }
168c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth  }
16957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // This is an equivalent but less inefficient implementation. It's expensive
17057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // enough that we wouldn't want to run it under any build, but it could be
17157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // enabled if e.g. the LiveRange implementation changes and extra testing is
17257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // needed.
17320b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (BuildDefs::extraValidation()) {
17420b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth    LiveRange Temp;
17520b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth    Temp.addSegment(OtherBegin, OtherBegin + 1);
17620b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth    bool Validation = overlaps(Temp);
17720b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth    (void)Validation;
17820b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth    assert(Result == Validation);
17920b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  }
180c4554d784583d26a02eca8610b43511ade516082Jim Stichnoth  return Result;
181d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
182d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
18357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Returns true if the live range contains the given instruction number. This
18457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// is only used for validating the live range calculation. The IsDest argument
18557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// indicates whether the Variable being tested is used in the Dest position (as
18657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// opposed to a Src position).
1874775255d4244c3425da0a7afd5f2c1ccb3a7dca9Jim Stichnothbool LiveRange::containsValue(InstNumberT Value, bool IsDest) const {
188f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth  for (const RangeElementType &I : Range) {
1894775255d4244c3425da0a7afd5f2c1ccb3a7dca9Jim Stichnoth    if (I.first <= Value &&
1904775255d4244c3425da0a7afd5f2c1ccb3a7dca9Jim Stichnoth        (Value < I.second || (!IsDest && Value == I.second)))
191d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      return true;
192d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  }
193d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  return false;
194d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
195d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
196037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnothvoid LiveRange::trim(InstNumberT Lower) {
197037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth  while (TrimmedBegin != Range.end() && TrimmedBegin->second <= Lower)
198037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth    ++TrimmedBegin;
199037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth}
200037fa1d997307fd68c7e6d9c385e30890d65604dJim Stichnoth
201467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnothconst Variable *Variable::asType(const Cfg *Func, Type Ty,
202467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth                                 RegNumT NewRegNum) const {
20357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // Note: This returns a Variable, even if the "this" object is a subclass of
20457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // Variable.
20520b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (!BuildDefs::dump() || getType() == Ty)
20631c955905a2d861a944f1e0ca60cd9e4c6f1b37dJim Stichnoth    return this;
207e82b560e649f8a68bcb252b9b002708e74d962d3John Porto  static constexpr SizeT One = 1;
208e343e0660aac84a8c6369f67fde19b401ca00104Jim Stichnoth  auto *V = new (CfgLocalAllocator<Variable>().allocate(One))
209467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth      Variable(Func, kVariable, Ty, Number);
210467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth  V->Name = Name;
2115fa0a5f7f730f33e6987527a261de8d833d7585cReed Kotler  V->RegNum = NewRegNum.hasValue() ? NewRegNum : RegNum;
21231c955905a2d861a944f1e0ca60cd9e4c6f1b37dJim Stichnoth  V->StackOffset = StackOffset;
213e343e0660aac84a8c6369f67fde19b401ca00104Jim Stichnoth  V->LinkedTo = LinkedTo;
2145bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  return V;
2155bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth}
2165bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
21711c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew ScullRegWeight Variable::getWeight(const Cfg *Func) const {
218b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth  if (mustHaveReg())
219b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth    return RegWeight(RegWeight::Inf);
220b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth  if (mustNotHaveReg())
221b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth    return RegWeight(RegWeight::Zero);
222b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth  return Func->getVMetadata()->getUseWeight(this);
22311c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull}
22411c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull
225877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnothvoid VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr,
226a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth                               CfgNode *Node, bool IsImplicit) {
227877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  (void)TrackingKind;
22811c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull
229aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  // Increment the use weight depending on the loop nest depth. The weight is
230aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  // exponential in the nest depth as inner loops are expected to be executed
231aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  // an exponentially greater number of times.
232aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  constexpr uint32_t LogLoopTripCountEstimate = 2; // 2^2 = 4
233aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  constexpr SizeT MaxShift = sizeof(uint32_t) * CHAR_BIT - 1;
234aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  constexpr SizeT MaxLoopNestDepth = MaxShift / LogLoopTripCountEstimate;
235aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  const uint32_t LoopNestDepth =
236aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull      std::min(Node->getLoopNestDepth(), MaxLoopNestDepth);
237aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  const uint32_t ThisUseWeight = uint32_t(1)
238aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull                                 << LoopNestDepth * LogLoopTripCountEstimate;
239aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull  UseWeight.addWeight(ThisUseWeight);
24011c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull
2414775255d4244c3425da0a7afd5f2c1ccb3a7dca9Jim Stichnoth  if (MultiBlock == MBS_MultiBlock)
2424775255d4244c3425da0a7afd5f2c1ccb3a7dca9Jim Stichnoth    return;
24357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // TODO(stichnot): If the use occurs as a source operand in the first
24457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // instruction of the block, and its definition is in this block's only
24557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // predecessor, we might consider not marking this as a separate use. This
24657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // may also apply if it's the first instruction of the block that actually
24757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // uses a Variable.
248144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  assert(Node);
249144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  bool MakeMulti = false;
250ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  if (IsImplicit)
251ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    MakeMulti = true;
25257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // A phi source variable conservatively needs to be marked as multi-block,
25357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // even if its definition is in the same block. This is because there can be
25457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // additional control flow before branching back to this node, and the
25557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // variable is live throughout those nodes.
256a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth  if (Instr && llvm::isa<InstPhi>(Instr))
257144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    MakeMulti = true;
258144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
259144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  if (!MakeMulti) {
260144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    switch (MultiBlock) {
261144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    case MBS_Unknown:
262cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    case MBS_NoUses:
263144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      MultiBlock = MBS_SingleBlock;
264144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      SingleUseNode = Node;
265144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      break;
266144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    case MBS_SingleBlock:
267144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      if (SingleUseNode != Node)
268144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth        MakeMulti = true;
269144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      break;
270144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    case MBS_MultiBlock:
271144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      break;
272144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    }
273144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  }
274144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
275144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  if (MakeMulti) {
276144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    MultiBlock = MBS_MultiBlock;
277ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    SingleUseNode = nullptr;
278144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  }
279144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
280144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
281877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnothvoid VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr,
282a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth                               CfgNode *Node) {
28357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // TODO(stichnot): If the definition occurs in the last instruction of the
28457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // block, consider not marking this as a separate use. But be careful not to
28557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // omit all uses of the variable if markDef() and markUse() both use this
28657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull  // optimization.
287ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  assert(Node);
28848e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  // Verify that instructions are added in increasing order.
28948e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  if (BuildDefs::asserts()) {
29048e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth    if (TrackingKind == VMK_All) {
29148e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth      const Inst *LastInstruction =
29248e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth          Definitions.empty() ? FirstOrSingleDefinition : Definitions.back();
29348e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth      (void)LastInstruction;
29448e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth      assert(LastInstruction == nullptr ||
29548e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth             Instr->getNumber() >= LastInstruction->getNumber());
29648e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth    }
297877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  }
298a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth  constexpr bool IsImplicit = false;
299a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth  markUse(TrackingKind, Instr, Node, IsImplicit);
300877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  if (TrackingKind == VMK_Uses)
301877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    return;
302ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth  if (FirstOrSingleDefinition == nullptr)
303877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    FirstOrSingleDefinition = Instr;
304877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  else if (TrackingKind == VMK_All)
305877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    Definitions.push_back(Instr);
306144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  switch (MultiDef) {
307144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  case MDS_Unknown:
308ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    assert(SingleDefNode == nullptr);
309144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    MultiDef = MDS_SingleDef;
310ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    SingleDefNode = Node;
311144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    break;
312144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  case MDS_SingleDef:
313ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    assert(SingleDefNode);
314ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    if (Node == SingleDefNode) {
315ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth      MultiDef = MDS_MultiDefSingleBlock;
316ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    } else {
317ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth      MultiDef = MDS_MultiDefMultiBlock;
318ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth      SingleDefNode = nullptr;
319ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    }
320ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    break;
321ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_MultiDefSingleBlock:
322ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    assert(SingleDefNode);
323ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    if (Node != SingleDefNode) {
324ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth      MultiDef = MDS_MultiDefMultiBlock;
325ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth      SingleDefNode = nullptr;
326ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    }
327144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    break;
328ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_MultiDefMultiBlock:
329ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    assert(SingleDefNode == nullptr);
330144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    break;
331144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  }
332144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
333144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
33448e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnothconst Inst *VariableTracking::getFirstDefinitionSingleBlock() const {
335ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  switch (MultiDef) {
336ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_Unknown:
337ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_MultiDefMultiBlock:
338ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    return nullptr;
339ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_SingleDef:
340ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_MultiDefSingleBlock:
341877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    assert(FirstOrSingleDefinition);
342877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    return FirstOrSingleDefinition;
343ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  }
344ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth  return nullptr;
345ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth}
346ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth
347ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnothconst Inst *VariableTracking::getSingleDefinition() const {
348ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  switch (MultiDef) {
349ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_Unknown:
350ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_MultiDefMultiBlock:
351ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_MultiDefSingleBlock:
352ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    return nullptr;
353ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  case MDS_SingleDef:
354877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    assert(FirstOrSingleDefinition);
355877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth    return FirstOrSingleDefinition;
356ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  }
357ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth  return nullptr;
358ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth}
359ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth
36048e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnothconst Inst *VariableTracking::getFirstDefinition() const {
36148e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  switch (MultiDef) {
36248e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  case MDS_Unknown:
36348e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth    return nullptr;
36448e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  case MDS_MultiDefMultiBlock:
36548e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  case MDS_SingleDef:
36648e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  case MDS_MultiDefSingleBlock:
36748e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth    assert(FirstOrSingleDefinition);
36848e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth    return FirstOrSingleDefinition;
36948e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  }
37048e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  return nullptr;
37148e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth}
37248e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth
373877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnothvoid VariablesMetadata::init(MetadataKind TrackingKind) {
3748363a0668ce21ea0c2a61f78083b0536dbd89860Jim Stichnoth  TimerMarker T(TimerStack::TT_vmetadata, Func);
375877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  Kind = TrackingKind;
376144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  Metadata.clear();
377cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  Metadata.resize(Func->getNumVariables(), VariableTracking::MBS_NoUses);
378144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
379144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  // Mark implicit args as being used in the entry node.
380f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth  for (Variable *Var : Func->getImplicitArgs()) {
381a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth    constexpr Inst *NoInst = nullptr;
382a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth    CfgNode *EntryNode = Func->getEntryNode();
383a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth    constexpr bool IsImplicit = true;
384a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth    Metadata[Var->getIndex()].markUse(Kind, NoInst, EntryNode, IsImplicit);
385144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  }
386144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
387336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth  for (CfgNode *Node : Func->getNodes())
388336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth    addNode(Node);
389336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth}
390336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth
391336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnothvoid VariablesMetadata::addNode(CfgNode *Node) {
39248e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  if (Func->getNumVariables() > Metadata.size())
393336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth    Metadata.resize(Func->getNumVariables());
394336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth
39529841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth  for (Inst &I : Node->getPhis()) {
39629841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth    if (I.isDeleted())
397336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth      continue;
39829841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth    if (Variable *Dest = I.getDest()) {
399336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth      SizeT DestNum = Dest->getIndex();
400336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth      assert(DestNum < Metadata.size());
40129841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth      Metadata[DestNum].markDef(Kind, &I, Node);
402336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth    }
40329841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth    for (SizeT SrcNum = 0; SrcNum < I.getSrcSize(); ++SrcNum) {
40454f3d518805b04b3f2958b7906a7d07dedb4e1aeJim Stichnoth      if (auto *Var = llvm::dyn_cast<Variable>(I.getSrc(SrcNum))) {
405336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth        SizeT VarNum = Var->getIndex();
406336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth        assert(VarNum < Metadata.size());
407a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth        constexpr bool IsImplicit = false;
408a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim Stichnoth        Metadata[VarNum].markUse(Kind, &I, Node, IsImplicit);
409144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth      }
410336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth    }
411336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth  }
412336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth
41329841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth  for (Inst &I : Node->getInsts()) {
41429841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth    if (I.isDeleted())
415336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth      continue;
416bb8b624e7c2a4fcdf9275bad310df779797e91a8Jim Stichnoth    // Note: The implicit definitions (and uses) from InstFakeKill are
417bb8b624e7c2a4fcdf9275bad310df779797e91a8Jim Stichnoth    // deliberately ignored.
41829841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth    if (Variable *Dest = I.getDest()) {
419336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth      SizeT DestNum = Dest->getIndex();
420336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth      assert(DestNum < Metadata.size());
42129841e84014ccbe7344e00f44ce7695a017de69aJim Stichnoth      Metadata[DestNum].markDef(Kind, &I, Node);
422336f6c4a90e7f5ee156bc9a339d80c7def5ddeffJim Stichnoth    }
423ec3f56532be1792d04ed470221df663bb8ca9c19John Porto    FOREACH_VAR_IN_INST(Var, I) {
424ec3f56532be1792d04ed470221df663bb8ca9c19John Porto      SizeT VarNum = Var->getIndex();
425ec3f56532be1792d04ed470221df663bb8ca9c19John Porto      assert(VarNum < Metadata.size());
426ec3f56532be1792d04ed470221df663bb8ca9c19John Porto      constexpr bool IsImplicit = false;
427ec3f56532be1792d04ed470221df663bb8ca9c19John Porto      Metadata[VarNum].markUse(Kind, &I, Node, IsImplicit);
428144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    }
429144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  }
430144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
431144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
432144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnothbool VariablesMetadata::isMultiDef(const Variable *Var) const {
433877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  assert(Kind != VMK_Uses);
434144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  if (Var->getIsArg())
435144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    return false;
436144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  if (!isTracked(Var))
437144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    return true; // conservative answer
438144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  SizeT VarNum = Var->getIndex();
439144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  // Conservatively return true if the state is unknown.
440144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef;
441144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
442144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
443144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnothbool VariablesMetadata::isMultiBlock(const Variable *Var) const {
444ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  if (Var->getIsArg())
445144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth    return true;
446cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  if (Var->isRematerializable())
447cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return false;
448ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  if (!isTracked(Var))
449ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth    return true; // conservative answer
450144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  SizeT VarNum = Var->getIndex();
451cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  switch (Metadata[VarNum].getMultiBlock()) {
452cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_NoUses:
453cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_SingleBlock:
454cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return false;
455144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  // Conservatively return true if the state is unknown.
456cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_Unknown:
457cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_MultiBlock:
458cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return true;
459cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  }
460cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  assert(0);
461cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  return true;
462cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth}
463cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth
464cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnothbool VariablesMetadata::isSingleBlock(const Variable *Var) const {
465cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  if (Var->getIsArg())
466cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return false;
467cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  if (Var->isRematerializable())
468cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return false;
469cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  if (!isTracked(Var))
470cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return false; // conservative answer
471cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  SizeT VarNum = Var->getIndex();
472cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  switch (Metadata[VarNum].getMultiBlock()) {
473cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_SingleBlock:
474cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return true;
475cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_Unknown:
476cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_NoUses:
477cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  case VariableTracking::MBS_MultiBlock:
478cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth    return false;
479cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  }
480cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  assert(0);
481cc89c959c2f602361488e0fdc0bf62e5d197d15cJim Stichnoth  return false;
482144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
483144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
48448e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnothconst Inst *
48548e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim StichnothVariablesMetadata::getFirstDefinitionSingleBlock(const Variable *Var) const {
486877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  assert(Kind != VMK_Uses);
487ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  if (!isTracked(Var))
488ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    return nullptr; // conservative answer
489ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  SizeT VarNum = Var->getIndex();
49048e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  return Metadata[VarNum].getFirstDefinitionSingleBlock();
491ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth}
492ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth
493ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnothconst Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const {
494877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  assert(Kind != VMK_Uses);
495144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  if (!isTracked(Var))
496ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    return nullptr; // conservative answer
497144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  SizeT VarNum = Var->getIndex();
498ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  return Metadata[VarNum].getSingleDefinition();
499ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth}
500ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth
50148e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnothconst Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const {
50248e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  assert(Kind != VMK_Uses);
50348e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  if (!isTracked(Var))
50448e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth    return nullptr; // conservative answer
50548e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  SizeT VarNum = Var->getIndex();
50648e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth  return Metadata[VarNum].getFirstDefinition();
50748e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth}
50848e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth
509ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnothconst InstDefList &
510877b04e409637216712d3c36fc155b47f8bd8d38Jim StichnothVariablesMetadata::getLatterDefinitions(const Variable *Var) const {
511877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  assert(Kind == VMK_All);
51286e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens  if (!isTracked(Var)) {
51386e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    // NoDefinitions has to be initialized after we've had a chance to set the
51486e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    // CfgAllocator, so it can't be a static global object. Also, while C++11
51586e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    // guarantees the initialization of static local objects to be thread-safe,
51686e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    // we use a pointer to it so we can avoid frequent  mutex locking overhead.
51786e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    if (NoDefinitions == nullptr) {
51886e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens      static const InstDefList NoDefinitionsInstance;
51986e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens      NoDefinitions = &NoDefinitionsInstance;
52086e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    }
52186e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens    return *NoDefinitions;
52286e5d883047328790dd7e1931c3cd112765560d7Nicolas Capens  }
523ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth  SizeT VarNum = Var->getIndex();
524877b04e409637216712d3c36fc155b47f8bd8d38Jim Stichnoth  return Metadata[VarNum].getLatterDefinitions();
525144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
526144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
527a3f57b9a6c7dbd3be7bf86dba697e9219c3413b2Jim StichnothCfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const {
528144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  if (!isTracked(Var))
529ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth    return nullptr; // conservative answer
530144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  SizeT VarNum = Var->getIndex();
531144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth  return Metadata[VarNum].getNode();
532144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth}
533144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth
534aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew ScullRegWeight VariablesMetadata::getUseWeight(const Variable *Var) const {
53511c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull  if (!isTracked(Var))
536aa6c109366408d066c4ac9e22c8c0ded6d18092fAndrew Scull    return RegWeight(1); // conservative answer
53711c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull  SizeT VarNum = Var->getIndex();
53811c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull  return Metadata[VarNum].getUseWeight();
53911c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull}
54011c9a325399b282cb4ea7d1d24d42fceeec2a09aAndrew Scull
54186e5d883047328790dd7e1931c3cd112765560d7Nicolas Capensconst InstDefList *VariablesMetadata::NoDefinitions = nullptr;
542ad4035397bdf3484dbc12ade5f9ebd87fb5f037dJim Stichnoth
543f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth// ======================== dump routines ======================== //
544f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
5455bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnothvoid Variable::emit(const Cfg *Func) const {
54620b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (BuildDefs::dump())
547b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf    Func->getTarget()->emitVariable(this);
5485bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth}
5495bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
5502e8bfbb9e2a5be0271d771f197d629e6f7d3568eJim Stichnothvoid Variable::dump(const Cfg *Func, Ostream &Str) const {
55120b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (!BuildDefs::dump())
552b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf    return;
553ae953202e3a647dde1c0778432a3e92dd2eff3f2Jim Stichnoth  if (Func == nullptr) {
554a91c34118294efbf08ebd11eed96fce83bf35f3cJim Stichnoth    Str << "%" << getName();
5552e8bfbb9e2a5be0271d771f197d629e6f7d3568eJim Stichnoth    return;
5562e8bfbb9e2a5be0271d771f197d629e6f7d3568eJim Stichnoth  }
557fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth  if (Func->isVerbose(IceV_RegOrigins) ||
558e343e0660aac84a8c6369f67fde19b401ca00104Jim Stichnoth      (!hasReg() && !Func->getTarget()->hasComputedFrame())) {
559a91c34118294efbf08ebd11eed96fce83bf35f3cJim Stichnoth    Str << "%" << getName();
560b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth    for (Variable *Link = getLinkedTo(); Link != nullptr;
561b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth         Link = Link->getLinkedTo()) {
562b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth      Str << ":%" << Link->getName();
563b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth    }
564e343e0660aac84a8c6369f67fde19b401ca00104Jim Stichnoth  }
5655bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  if (hasReg()) {
566fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth    if (Func->isVerbose(IceV_RegOrigins))
5675bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth      Str << ":";
5685bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    Str << Func->getTarget()->getRegName(RegNum, getType());
5695bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  } else if (Func->getTarget()->hasComputedFrame()) {
570fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth    if (Func->isVerbose(IceV_RegOrigins))
5715bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth      Str << ":";
5728aa396610b7baf728631a43ea16ad3d13e38397aJim Stichnoth    const auto BaseRegisterNumber =
5738aa396610b7baf728631a43ea16ad3d13e38397aJim Stichnoth        hasReg() ? getBaseRegNum() : Func->getTarget()->getFrameOrStackReg();
574dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth    Str << "["
57528068adbf34a4602090efddc18b4dd123ffdeb6aJan Voung        << Func->getTarget()->getRegName(BaseRegisterNumber, IceType_i32);
576b9a847280e4486e566dabdd5b0d571309b4ad628Jim Stichnoth    if (hasKnownStackOffset()) {
577fe62f0a229a7b2bc910eb8b7cb83d2534ed39343Jim Stichnoth      int32_t Offset = getStackOffset();
578fe62f0a229a7b2bc910eb8b7cb83d2534ed39343Jim Stichnoth      if (Offset) {
579fe62f0a229a7b2bc910eb8b7cb83d2534ed39343Jim Stichnoth        if (Offset > 0)
580fe62f0a229a7b2bc910eb8b7cb83d2534ed39343Jim Stichnoth          Str << "+";
581fe62f0a229a7b2bc910eb8b7cb83d2534ed39343Jim Stichnoth        Str << Offset;
582fe62f0a229a7b2bc910eb8b7cb83d2534ed39343Jim Stichnoth      }
5835bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    }
5845bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    Str << "]";
5855bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  }
586f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth}
587f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
58876bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voungtemplate <> void ConstantInteger32::emit(TargetLowering *Target) const {
58976bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung  Target->emit(this);
590f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth}
591f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
59276bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voungtemplate <> void ConstantInteger64::emit(TargetLowering *Target) const {
59376bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung  Target->emit(this);
59476bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung}
59576bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung
59676bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voungtemplate <> void ConstantFloat::emit(TargetLowering *Target) const {
59776bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung  Target->emit(this);
59876bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung}
59976bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung
60076bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voungtemplate <> void ConstantDouble::emit(TargetLowering *Target) const {
60176bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung  Target->emit(this);
60276bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung}
60376bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung
60476bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voungvoid ConstantRelocatable::emit(TargetLowering *Target) const {
60576bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung  Target->emit(this);
60676bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung}
60776bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung
6088ff4b2819944bc4f02fb29204a1fa5ba7dea5682Jim Stichnothvoid ConstantRelocatable::emitWithoutPrefix(const TargetLowering *Target,
6098ff4b2819944bc4f02fb29204a1fa5ba7dea5682Jim Stichnoth                                            const char *Suffix) const {
6108ff4b2819944bc4f02fb29204a1fa5ba7dea5682Jim Stichnoth  Target->emitWithoutPrefix(this, Suffix);
611bca2f65551c65fdc18278bf88025c11d8af18579Jim Stichnoth}
612bca2f65551c65fdc18278bf88025c11d8af18579Jim Stichnoth
61398ba00666271be1bdcd45b72b3dec04419efe61bJim Stichnothvoid ConstantRelocatable::dump(const Cfg *, Ostream &Str) const {
61420b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (!BuildDefs::dump())
615b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf    return;
616dc61925cf9de3cba7f310c9e8855c56b8e5b3edcJohn Porto  if (!EmitString.empty()) {
617dc61925cf9de3cba7f310c9e8855c56b8e5b3edcJohn Porto    Str << EmitString;
618dc61925cf9de3cba7f310c9e8855c56b8e5b3edcJohn Porto    return;
619dc61925cf9de3cba7f310c9e8855c56b8e5b3edcJohn Porto  }
62098ba00666271be1bdcd45b72b3dec04419efe61bJim Stichnoth  Str << "@" << Name;
62127fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  const RelocOffsetT Offset = getOffset();
62227fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  if (Offset) {
62327fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    if (Offset >= 0) {
62427fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto      Str << "+";
62527fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    }
62627fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto    Str << Offset;
62727fddcc36ad3f0c7531e481f9b249bd36ef83057John Porto  }
628f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth}
629f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth
63076bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voungvoid ConstantUndef::emit(TargetLowering *Target) const { Target->emit(this); }
63176bb0bec94b99765be86525fa1ae2c607e66d9b6Jan Voung
632d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnothvoid LiveRange::dump(Ostream &Str) const {
63320b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (!BuildDefs::dump())
634b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf    return;
635f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth  bool First = true;
636f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth  for (const RangeElementType &I : Range) {
6378363a0668ce21ea0c2a61f78083b0536dbd89860Jim Stichnoth    if (!First)
638d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth      Str << ", ";
639f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth    First = false;
640f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth    Str << "[" << I.first << ":" << I.second << ")";
641d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  }
642d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
643d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
644d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim StichnothOstream &operator<<(Ostream &Str, const LiveRange &L) {
64520b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (!BuildDefs::dump())
646b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf    return Str;
647d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  L.dump(Str);
648d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth  return Str;
649d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth}
650d97c7df5a3c94fc0d1ad42acbf79756f15682919Jim Stichnoth
6515bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim StichnothOstream &operator<<(Ostream &Str, const RegWeight &W) {
65220b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth  if (!BuildDefs::dump())
653b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf    return Str;
6545bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  if (W.getWeight() == RegWeight::Inf)
6555bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    Str << "Inf";
6565bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  else
6575bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth    Str << W.getWeight();
6585bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth  return Str;
6595bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth}
6605bc2b1d163123ef17e0a14f50aae3bc8e4cd243eJim Stichnoth
661f7c9a14151ecfc9c642bf3e1dba9341d49e9ec67Jim Stichnoth} // end of namespace Ice
662