if (tree->gtFlags != 0)
{
- if (!comp->dumpIRNodes)
- {
- if ((tree->gtFlags & (~(GTF_NODE_LARGE|GTF_NODE_SMALL))) == 0)
- {
- return chars;
- }
- }
-
chars += printf("flags=");
// Node flags
-#if defined(DEBUG) && SMALL_TREE_NODES
+#if defined(DEBUG)
+#if SMALL_TREE_NODES
if (comp->dumpIRNodes)
{
- if (tree->gtFlags & GTF_NODE_LARGE)
+ if (tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE)
{
chars += printf("[NODE_LARGE]");
}
- if (tree->gtFlags & GTF_NODE_SMALL)
+ if (tree->gtDebugFlags & GTF_DEBUG_NODE_SMALL)
{
chars += printf("[NODE_SMALL]");
}
}
-#endif
- if (tree->gtFlags & GTF_MORPHED)
+#endif // SMALL_TREE_NODES
+ if (tree->gtDebugFlags & GTF_DEBUG_MORPHED)
{
chars += printf("[MORPHED]");
}
+#endif // defined(DEBUG)
+
if (tree->gtFlags & GTF_COLON_COND)
{
chars += printf("[COLON_COND]");
{
chars += printf("[VAR_ARR_INDEX]");
}
- if (tree->gtFlags & GTFD_VAR_CSE_REF)
+#if defined(DEBUG)
+ if (tree->gtDebugFlags & GTF_DEBUG_VAR_CSE_REF)
{
chars += printf("[VAR_CSE_REF]");
}
+#endif
if (op == GT_REG_VAR)
{
if (tree->gtFlags & GTF_REG_BIRTH)
gtOper = oper;
gtType = type;
gtFlags = 0;
+#ifdef DEBUG
+ gtDebugFlags = 0;
+#endif // DEBUG
#ifdef LEGACY_BACKEND
gtUsedRegs = 0;
#endif // LEGACY_BACKEND
size_t size = GenTree::s_gtNodeSizes[oper];
if (size == TREE_NODE_SZ_SMALL && !largeNode)
{
- gtFlags |= GTF_NODE_SMALL;
+ gtDebugFlags |= GTF_DEBUG_NODE_SMALL;
}
else if (size == TREE_NODE_SZ_LARGE || largeNode)
{
- gtFlags |= GTF_NODE_LARGE;
+ gtDebugFlags |= GTF_DEBUG_NODE_LARGE;
}
else
{
inline
void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
{
- assert(((gtFlags & GTF_NODE_SMALL) != 0) !=
- ((gtFlags & GTF_NODE_LARGE) != 0));
+ assert(((gtDebugFlags & GTF_DEBUG_NODE_SMALL) != 0) !=
+ ((gtDebugFlags & GTF_DEBUG_NODE_LARGE) != 0));
/* Make sure the node isn't too small for the new operator */
assert(GenTree::s_gtNodeSizes[ oper] == TREE_NODE_SZ_SMALL ||
GenTree::s_gtNodeSizes[ oper] == TREE_NODE_SZ_LARGE);
- assert(GenTree::s_gtNodeSizes[ oper] == TREE_NODE_SZ_SMALL || (gtFlags & GTF_NODE_LARGE));
+ assert(GenTree::s_gtNodeSizes[ oper] == TREE_NODE_SZ_SMALL || (gtDebugFlags & GTF_DEBUG_NODE_LARGE));
gtOper = oper;
{
/* The source may be big only if the target is also a big node */
- assert((gtFlags & GTF_NODE_LARGE) || GenTree::s_gtNodeSizes[src->gtOper] == TREE_NODE_SZ_SMALL);
+ assert((gtDebugFlags & GTF_DEBUG_NODE_LARGE) || GenTree::s_gtNodeSizes[src->gtOper] == TREE_NODE_SZ_SMALL);
GenTreePtr prev = gtPrev;
GenTreePtr next = gtNext;
// The VTable pointer is copied intentionally here
{
// Print the tree so we can see it in the log.
printf("Missing flags on tree [%X]: ", tree);
- GenTree::gtDispFlags(chkFlags & ~treeFlags);
+ GenTree::gtDispFlags(chkFlags & ~treeFlags, 0);
printf("\n");
gtDispTree(tree);
// Print the tree again so we can see it right after we hook up the debugger.
printf("Missing flags on tree [%X]: ", tree);
- GenTree::gtDispFlags(chkFlags & ~treeFlags);
+ GenTree::gtDispFlags(chkFlags & ~treeFlags, 0);
printf("\n");
gtDispTree(tree);
}
{
// Print the tree so we can see it in the log.
printf("Extra GTF_CALL flags on parent tree [%X]: ", tree);
- GenTree::gtDispFlags(treeFlags & ~chkFlags);
+ GenTree::gtDispFlags(treeFlags & ~chkFlags, 0);
printf("\n");
gtDispTree(tree);
// Print the tree again so we can see it right after we hook up the debugger.
printf("Extra GTF_CALL flags on parent tree [%X]: ", tree);
- GenTree::gtDispFlags(treeFlags & ~chkFlags);
+ GenTree::gtDispFlags(treeFlags & ~chkFlags, 0);
printf("\n");
gtDispTree(tree);
}
/*****************************************************************************
*
* When 'SMALL_TREE_NODES' is enabled, we allocate tree nodes in 2 different
- * sizes: 'GTF_NODE_SMALL' for most nodes and 'GTF_NODE_LARGE' for the few
- * nodes (such as calls and statement list nodes) that have more fields and
- * take up a lot more space.
+ * sizes: 'GTF_DEBUG_NODE_SMALL' for most nodes and 'GTF_DEBUG_NODE_LARGE' for
+ * the few nodes (such as calls and statement list nodes) that have more fields
+ * and take up a lot more space.
*/
#if SMALL_TREE_NODES
#ifdef DEBUG
bool GenTree::IsNodeProperlySized() const
{
- size_t size;
+ size_t size;
- if (gtFlags & GTF_NODE_SMALL)
+ if (gtDebugFlags & GTF_DEBUG_NODE_SMALL)
{
size = TREE_NODE_SZ_SMALL;
}
else
{
- assert (gtFlags & GTF_NODE_LARGE);
+ assert(gtDebugFlags & GTF_DEBUG_NODE_LARGE);
size = TREE_NODE_SZ_LARGE;
}
* of operands the tree will push on the x87 (coprocessor) stack. Also sets
* genFPstkLevel, tmpDoubleSpillMax, and possibly gtFPstLvlRedo.
* 5. Sometimes sets GTF_ADDRMODE_NO_CSE on nodes in the tree.
- * 6. DEBUG-only: clears GTF_MORPHED.
+ * 6. DEBUG-only: clears GTF_DEBUG_MORPHED.
*/
#ifdef _PREFAST_
assert(tree->gtOper != GT_STMT);
#ifdef DEBUG
- /* Clear the GTF_MORPHED flag as well */
- tree->gtFlags &= ~GTF_MORPHED;
+ /* Clear the GTF_DEBUG_MORPHED flag as well */
+ tree->gtDebugFlags &= ~GTF_DEBUG_MORPHED;
#endif
/* Is this a FP value? */
}
// We can call gtCloneExpr() before we have called fgMorph when we expand a GT_INDEX node in fgMorphArrayIndex()
- // The method gtFoldExpr() expects to be run after fgMorph so it will set the GTF_MORPHED
+ // The method gtFoldExpr() expects to be run after fgMorph so it will set the GTF_DEBUG_MORPHED
// flag on nodes that it adds/modifies. Then when we call fgMorph we will assert.
// We really only will need to fold when this method is used to replace references to
// local variable with an integer.
#ifdef DEBUG
-/* static */ int GenTree::gtDispFlags(unsigned flags)
+/* static */ int GenTree::gtDispFlags(unsigned flags, unsigned debugFlags)
{
printf("%c", (flags & GTF_ASG ) ? 'A' : '-');
printf("%c", (flags & GTF_CALL ) ? 'C' : '-');
printf("%c", (flags & GTF_EXCEPT ) ? 'X' : '-');
printf("%c", (flags & GTF_GLOB_REF ) ? 'G' : '-');
- printf("%c", (flags & GTF_MORPHED ) ? '+' : // First print '+' if GTF_MORPHED is set
+ printf("%c", (debugFlags & GTF_DEBUG_MORPHED) ? '+' : // First print '+' if GTF_DEBUG_MORPHED is set
(flags & GTF_ORDER_SIDEEFF ) ? 'O' : '-'); // otherwise print 'O' or '-'
printf("%c", (flags & GTF_COLON_COND ) ? '?' : '-');
printf("%c", (flags & GTF_DONT_CSE ) ? 'N' : // N is for No cse
flags &= ~GTF_REVERSE_OPS; // we use this value for GTF_VAR_ARR_INDEX above
}
- msgLength -= GenTree::gtDispFlags(flags);
+ msgLength -= GenTree::gtDispFlags(flags, tree->gtDebugFlags);
/*
printf("%c", (flags & GTF_ASG ) ? 'A' : '-');
printf("%c", (flags & GTF_CALL ) ? 'C' : '-');
}
#endif
assert ((GenTree::s_gtNodeSizes[GT_CNS_NATIVELONG] == TREE_NODE_SZ_SMALL) ||
- (tree->gtFlags & GTF_NODE_LARGE) );
+ (tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE) );
tree->ChangeOperConst(GT_CNS_NATIVELONG);
tree->gtIntConCommon.SetLngValue(lval1);
#endif
assert ((GenTree::s_gtNodeSizes[GT_CNS_DBL] == TREE_NODE_SZ_SMALL) ||
- (tree->gtFlags & GTF_NODE_LARGE) );
+ (tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE) );
tree->ChangeOperConst(GT_CNS_DBL);
tree->gtDblCon.gtDconVal = d1;
regMaskTP gtGetRegMask() const;
unsigned gtFlags; // see GTF_xxxx below
-
+
+#if defined(DEBUG)
+ unsigned gtDebugFlags; // see GTF_DEBUG_xxx below
+#endif // defined(DEBUG)
+
ValueNumPair gtVNPair;
regMaskSmall gtRsvdRegs; // set of fixed trashed registers
#define GTF_SPILLED_OP2 0x00000200 // op2 has been spilled
#endif // LEGACY_BACKEND
-#ifdef DEBUG
-#ifndef LEGACY_BACKEND
- #define GTF_MORPHED 0x00000200 // the node has been morphed (in the global morphing phase)
-#else // LEGACY_BACKEND
- // For LEGACY_BACKEND, 0x00000200 is in use, but we can use the same value as GTF_SPILLED since we
- // don't call gtSetEvalOrder(), which clears GTF_MORPHED, after GTF_SPILLED has been set.
- #define GTF_MORPHED 0x00000080 // the node has been morphed (in the global morphing phase)
-#endif // LEGACY_BACKEND
-#endif // DEBUG
-
#define GTF_REDINDEX_CHECK 0x00000100 // Used for redundant range checks. Disjoint from GTF_SPILLED_OPER
#define GTF_ZSF_SET 0x00000400 // the zero(ZF) and sign(SF) flags set to the operand
#define GTF_DONT_CSE 0x00004000 // don't bother CSE'ing this expr
#define GTF_COLON_COND 0x00008000 // this node is conditionally executed (part of ? :)
-#if defined(DEBUG) && SMALL_TREE_NODES
- #define GTF_NODE_LARGE 0x00010000
- #define GTF_NODE_SMALL 0x00020000
-
- // Property of the node itself, not the gtOper
- #define GTF_NODE_MASK (GTF_COLON_COND | GTF_MORPHED | GTF_NODE_SMALL | GTF_NODE_LARGE )
-#else
#define GTF_NODE_MASK (GTF_COLON_COND)
-#endif
#define GTF_BOOLEAN 0x00040000 // value is known to be 0/1
// code to produce the value.
// It is currently used only on constant nodes.
// It CANNOT be set on var (GT_LCL*) nodes, or on indir (GT_IND or GT_STOREIND) nodes, since
- // 1) it is not needed for lclVars and is highly unlikely to be useful for indir nodes, and
- // 2) it conflicts with GTFD_VAR_CSE_REF for lclVars (though this is debug only, and
- // GTF_IND_ARR_INDEX for indirs.
+ // it is not needed for lclVars and is highly unlikely to be useful for indir nodes
//---------------------------------------------------------------------
// The following flags can be used only with a small set of nodes, and
#define GTF_CALL_REG_SAVE 0x01000000 // GT_CALL -- This call preserves all integer regs
// For additional flags for GT_CALL node see GTF_CALL_M_
-#ifdef DEBUG
- #define GTFD_VAR_CSE_REF 0x00800000 // GT_LCL_VAR -- This is a CSE LCL_VAR node
-#endif
-
#define GTF_NOP_DEATH 0x40000000 // GT_NOP -- operand dies here
#define GTF_FLD_NULLCHECK 0x80000000 // GT_FIELD -- need to nullcheck the "this" pointer
#define GTF_IND_UNALIGNED 0x02000000 // GT_IND -- the load or store is unaligned (we assume worst case alignment of 1 byte)
#define GTF_IND_INVARIANT 0x01000000 // GT_IND -- the target is invariant (a prejit indirection)
#define GTF_IND_ARR_LEN 0x80000000 // GT_IND -- the indirection represents an array length (of the REF contribution to its argument).
- #define GTF_IND_ARR_INDEX 0x00800000 // GT_IND -- the indirection represents an (SZ) array index (this shares the same value as GTFD_VAR_CSE_REF,
- // but is disjoint because a GT_LCL_VAR is never an ind (GT_IND or GT_STOREIND)
+ #define GTF_IND_ARR_INDEX 0x00800000 // GT_IND -- the indirection represents an (SZ) array index
#define GTF_IND_FLAGS (GTF_IND_VOLATILE|GTF_IND_REFARR_LAYOUT|GTF_IND_TGTANYWHERE|GTF_IND_NONFAULTING|\
GTF_IND_TLS_REF|GTF_IND_UNALIGNED|GTF_IND_INVARIANT|GTF_IND_ARR_INDEX)
//----------------------------------------------------------------
+#if defined(DEBUG)
+ #define GTF_DEBUG_MORPHED 0x00000001 // the node has been morphed (in the global morphing phase)
+ #define GTF_DEBUG_NODE_SMALL 0x00000002
+ #define GTF_DEBUG_NODE_LARGE 0x00000004
+
+ #define GTF_DEBUG_VAR_CSE_REF 0x00800000 // GT_LCL_VAR -- This is a CSE LCL_VAR node
+#endif // defined(DEBUG)
+
GenTreePtr gtNext;
GenTreePtr gtPrev;
bool gtRequestSetFlags ();
#ifdef DEBUG
bool gtIsValid64RsltMul ();
- static int gtDispFlags (unsigned flags);
+ static int gtDispFlags (unsigned flags, unsigned debugFlags);
#endif
// cast operations
addr = gtNewOperNode(GT_ADD, TYP_BYREF, addr, cns);
#if SMALL_TREE_NODES
- assert(tree->gtFlags & GTF_NODE_LARGE);
+ assert(tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE);
#endif
// Change the orginal GT_INDEX node into a GT_IND node
}
}
- assert(!fgGlobalMorph || (arrElem->gtFlags & GTF_MORPHED));
+ assert(!fgGlobalMorph || (arrElem->gtDebugFlags & GTF_DEBUG_MORPHED));
addr = arrElem->gtOp.gtOp1;
copyBlk = fgMorphTree(copyBlk);
GenTree* result = gtNewOperNode(GT_COMMA, TYP_VOID, call, copyBlk);
#ifdef DEBUG
- result->gtFlags |= GTF_MORPHED;
+ result->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
return result;
}
}
#ifdef DEBUG
- tree->gtFlags |= GTF_MORPHED;
+ tree->gtDebugFlags |= GTF_DEBUG_MORPHED;
if (verbose)
{
}
#ifdef DEBUG
- tree->gtFlags |= GTF_MORPHED;
+ tree->gtDebugFlags |= GTF_DEBUG_MORPHED;
if (verbose)
{
GenTree* op2 = gtNewIconNode(index);
tree = gtNewSIMDNode(baseType, simdStructNode, op2, SIMDIntrinsicGetItem, baseType, simdSize);
#ifdef DEBUG
- tree->gtFlags |= GTF_MORPHED;
+ tree->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
}
return tree;
gtNewIconNode(simdSize),
false);
#ifdef DEBUG
- tree->gtFlags |= GTF_MORPHED;
+ tree->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
}
{
GenTreePtr zeroNode = gtNewZeroConNode(typ);
#ifdef DEBUG
- zeroNode->gtFlags |= GTF_MORPHED;
+ zeroNode->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
DEBUG_DESTROY_NODE(tree);
return zeroNode;
commaNode->gtType = typ;
commaNode->gtFlags = (treeFlags & ~GTF_REVERSE_OPS); // Bashing the GT_COMMA flags here is dangerous, clear the GTF_REVERSE_OPS at least.
#ifdef DEBUG
- commaNode->gtFlags |= GTF_MORPHED;
+ commaNode->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
while (commaNode->gtOp.gtOp2->gtOper == GT_COMMA)
{
commaNode->gtType = typ;
commaNode->gtFlags = (treeFlags & ~GTF_REVERSE_OPS); // Bashing the GT_COMMA flags here is dangerous, clear the GTF_REVERSE_OPS at least.
#ifdef DEBUG
- commaNode->gtFlags |= GTF_MORPHED;
+ commaNode->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
}
bool wasArrIndex = (tree->gtFlags & GTF_IND_ARR_INDEX) != 0;
GetArrayInfoMap()->Set(op1, arrInfo);
}
#ifdef DEBUG
- op1->gtFlags |= GTF_MORPHED;
+ op1->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
commaNode->gtOp.gtOp2 = op1;
return tree;
{
commaNode->gtType = op1->gtType; commaNode->gtFlags |= op1->gtFlags;
#ifdef DEBUG
- commaNode->gtFlags |= GTF_MORPHED;
+ commaNode->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
commaNode = commaNode->gtOp.gtOp2;
}
GenTree* sub = gtNewOperNode(GT_SUB, type, numerator, mul);
#ifdef DEBUG
- sub->gtFlags |= GTF_MORPHED;
+ sub->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
return sub;
GenTree* sub = gtNewOperNode(GT_SUB, type, gtCloneExpr(numerator), mul);
#ifdef DEBUG
- sub->gtFlags |= GTF_MORPHED;
+ sub->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
return sub;
DISPTREE(result);
#ifdef DEBUG
- result->gtFlags |= GTF_MORPHED;
+ result->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
return result;
if (fgGlobalMorph)
{
/* Ensure that we haven't morphed this node already */
- assert(((tree->gtFlags & GTF_MORPHED) == 0) && "ERROR: Already morphed this node!");
+ assert(((tree->gtDebugFlags & GTF_DEBUG_MORPHED) == 0) && "ERROR: Already morphed this node!");
#if LOCAL_ASSERTION_PROP
/* Before morphing the tree, we try to propagate any active assertions */
*
* This function is called to complete the morphing of a tree node
* It should only be called once for each node.
- * If DEBUG is defined the flag GTF_MORPHED is checked and updated,
+ * If DEBUG is defined the flag GTF_DEBUG_MORPHED is checked and updated,
* to enforce the invariant that each node is only morphed once.
* If LOCAL_ASSERTION_PROP is enabled the result tree may be replaced
* by an equivalent tree.
if ((oldTree != NULL) && (oldTree != tree))
{
/* Ensure that we have morphed this node */
- assert((tree->gtFlags & GTF_MORPHED) && "ERROR: Did not morph this node!");
+ assert((tree->gtDebugFlags & GTF_DEBUG_MORPHED) && "ERROR: Did not morph this node!");
#ifdef DEBUG
TransferTestDataToNode(oldTree, tree);
else
{
// Ensure that we haven't morphed this node already
- assert(((tree->gtFlags & GTF_MORPHED) == 0) && "ERROR: Already morphed this node!");
+ assert(((tree->gtDebugFlags & GTF_DEBUG_MORPHED) == 0) && "ERROR: Already morphed this node!");
}
if (tree->OperKind() & GTK_CONST)
#ifdef DEBUG
/* Mark this node as being morphed */
- tree->gtFlags |= GTF_MORPHED;
+ tree->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
}
but the flag still got set, clear it here... */
#ifdef DEBUG
- tree->gtFlags &= ~GTF_MORPHED;
+ tree->gtDebugFlags &= ~GTF_DEBUG_MORPHED;
#endif
noway_assert(compTailCallUsed);
noway_assert((tree->gtOper == GT_CALL) && tree->AsCall()->IsTailCall());
cse = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp);
cse->gtVNPair = exp->gtVNPair; // assign the proper Value Numbers
#ifdef DEBUG
- cse->gtFlags |= GTFD_VAR_CSE_REF;
+ cse->gtDebugFlags |= GTF_DEBUG_VAR_CSE_REF;
#endif // DEBUG
// If we have side effects then we need to create a GT_COMMA tree instead
assert(tree->gtType == TYP_INT);
op1 = gtNewCastNode(TYP_INT, op1, TYP_INT);
#ifdef DEBUG
- op1->gtFlags |= GTF_MORPHED;
+ op1->gtDebugFlags |= GTF_DEBUG_MORPHED;
#endif
tree->gtOp.gtOp1 = op1;
}