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