// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #ifndef _NODEINFO_H_ #define _NODEINFO_H_ struct GenTree; class LinearScan; typedef unsigned int LsraLocation; class TreeNodeInfo { public: TreeNodeInfo() { _dstCount = 0; _srcCount = 0; _internalIntCount = 0; _internalFloatCount = 0; srcCandsIndex = 0; dstCandsIndex = 0; internalCandsIndex = 0; isLocalDefUse = false; isDelayFree = false; hasDelayFreeSrc = false; isTgtPref = false; isInternalRegDelayFree = false; #ifdef DEBUG isInitialized = false; #endif } // dst __declspec(property(put = setDstCount, get = getDstCount)) int dstCount; void setDstCount(int count) { assert(count <= MAX_RET_REG_COUNT); _dstCount = (char)count; } int getDstCount() { return _dstCount; } // src __declspec(property(put = setSrcCount, get = getSrcCount)) int srcCount; void setSrcCount(int count) { _srcCount = (char)count; assert(_srcCount == count); } int getSrcCount() { return _srcCount; } // internalInt __declspec(property(put = setInternalIntCount, get = getInternalIntCount)) int internalIntCount; void setInternalIntCount(int count) { _internalIntCount = (char)count; assert(_internalIntCount == count); } int getInternalIntCount() { return _internalIntCount; } // internalFloat __declspec(property(put = setInternalFloatCount, get = getInternalFloatCount)) int internalFloatCount; void setInternalFloatCount(int count) { _internalFloatCount = (char)count; assert(_internalFloatCount == count); } int getInternalFloatCount() { return _internalFloatCount; } // SrcCandidates are constraints of the consuming (parent) operation applied to this node // (i.e. what registers it is constrained to consume). regMaskTP getSrcCandidates(LinearScan* lsra); void setSrcCandidates(LinearScan* lsra, regMaskTP mask); // DstCandidates are constraints of this node (i.e. what registers it is constrained to produce). regMaskTP getDstCandidates(LinearScan* lsra); void setDstCandidates(LinearScan* lsra, regMaskTP mask); // InternalCandidates are constraints of the registers used as temps in the evaluation of this node. regMaskTP getInternalCandidates(LinearScan* lsra); void setInternalCandidates(LinearScan* lsra, regMaskTP mask); void addInternalCandidates(LinearScan* lsra, regMaskTP mask); public: unsigned char srcCandsIndex; unsigned char dstCandsIndex; unsigned char internalCandsIndex; private: unsigned char _srcCount : 5; unsigned char _dstCount : 3; unsigned char _internalIntCount : 3; unsigned char _internalFloatCount : 3; public: // isLocalDefUse identifies trees that produce a value that is not consumed elsewhere. // Examples include stack arguments to a call (they are immediately stored), lhs of comma // nodes, or top-level nodes that are non-void. unsigned char isLocalDefUse : 1; // isDelayFree is set when the register defined by this node will interfere with the destination // of the consuming node, and therefore it must not be freed immediately after use. unsigned char isDelayFree : 1; // hasDelayFreeSrc is set when this node has sources that are marked "isDelayFree". This is because, // we may eventually "contain" this node, in which case we don't want it's children (which have // already been marked "isDelayFree" to be handled that way when allocating. unsigned char hasDelayFreeSrc : 1; // isTgtPref is set to true when we have a rmw op, where we would like the result to be allocated // in the same register as op1. unsigned char isTgtPref : 1; // Whether internal register needs to be different from targetReg // in which result is produced. unsigned char isInternalRegDelayFree : 1; #ifdef DEBUG // isInitialized is set when the tree node is handled. unsigned char isInitialized : 1; #endif public: // Initializes the TreeNodeInfo value with the given values. void Initialize(LinearScan* lsra, GenTree* node); #ifdef DEBUG void dump(LinearScan* lsra); // This method checks to see whether the information has been initialized, // and is in a consistent state bool IsValid(LinearScan* lsra) { return (isInitialized && ((getSrcCandidates(lsra) | getInternalCandidates(lsra) | getDstCandidates(lsra)) & ~(RBM_ALLFLOAT | RBM_ALLINT)) == 0); } #endif // DEBUG }; #endif // _NODEINFO_H_