bool isContainedLclField() const { return isContained() && isLclField(); }
- bool isContainedLclVar() const { return isContained() && (OperGet() == GT_LCL_VAR); }
+ bool isContainedLclVar() const { return isContained() && (OperGet() == GT_LCL_VAR); }
+
+ bool isContainedSpillTemp() const;
// Indicates whether it is a memory op.
// Right now it includes Indir and LclField ops.
bool isContainedMemoryOp() const
{
- return (isContained() && isMemoryOp()) || isContainedLclVar();
+ return (isContained() && isMemoryOp()) || isContainedLclVar() || isContainedSpillTemp();
}
regNumber GetRegNum() const
#define GTF_REVERSE_OPS 0x00000020 // operand op2 should be evaluated before op1 (normally, op1 is evaluated first and op2 is evaluated second)
#define GTF_REG_VAL 0x00000040 // operand is sitting in a register (or part of a TYP_LONG operand is sitting in a register)
- #define GTF_SPILLED 0x00000080 // the value has been spilled
- #define GTF_SPILLED_OPER 0x00000100 // op1 has been spilled
+ #define GTF_SPILLED 0x00000080 // the value has been spilled
#ifdef LEGACY_BACKEND
- #define GTF_SPILLED_OP2 0x00000200 // op2 has been spilled
+ #define GTF_SPILLED_OPER 0x00000100 // op1 has been spilled
+ #define GTF_SPILLED_OP2 0x00000200 // op2 has been spilled
+#else
+ #define GTF_NOREG_AT_USE 0x00000100 // tree node is in memory at the point of use
#endif // LEGACY_BACKEND
#define GTF_REDINDEX_CHECK 0x00000100 // Used for redundant range checks. Disjoint from GTF_SPILLED_OPER
static
bool OperIsIndir(genTreeOps gtOper)
{
- return gtOper == GT_IND || gtOper == GT_STOREIND || gtOper == GT_NULLCHECK;
+ return gtOper == GT_IND || gtOper == GT_STOREIND || gtOper == GT_NULLCHECK || gtOper == GT_OBJ;
}
bool OperIsIndir() const
#endif // DEBUGGABLE_GENTREE
};
-// gtObj -- 'object' (GT_OBJ). */
-
-struct GenTreeObj: public GenTreeUnOp
-{
- // The address of the block.
- GenTreePtr& Addr() { return gtOp1; }
-
- CORINFO_CLASS_HANDLE gtClass; // the class of the object
-
- GenTreeObj(var_types type, GenTreePtr addr, CORINFO_CLASS_HANDLE cls) :
- GenTreeUnOp(GT_OBJ, type, addr),
- gtClass(cls)
- {
- // By default, an OBJ is assumed to be a global reference.
- gtFlags |= GTF_GLOB_REF;
- }
-
-#if DEBUGGABLE_GENTREE
- GenTreeObj() : GenTreeUnOp() {}
-#endif
-};
-
// Represents a CpObj MSIL Node.
struct GenTreeCpObj : public GenTreeBlkOp
{
#endif
};
+// gtObj -- 'object' (GT_OBJ). */
+
+struct GenTreeObj: public GenTreeIndir
+{
+ CORINFO_CLASS_HANDLE gtClass; // the class of the object
+
+ GenTreeObj(var_types type, GenTreePtr addr, CORINFO_CLASS_HANDLE cls) :
+ GenTreeIndir(GT_OBJ, type, addr, nullptr),
+ gtClass(cls)
+ {
+ // By default, an OBJ is assumed to be a global reference.
+ gtFlags |= GTF_GLOB_REF;
+ }
+
+#if DEBUGGABLE_GENTREE
+ GenTreeObj() : GenTreeIndir() {}
+#endif
+};
+
// Read-modify-write status of a RMW memory op rooted at a storeInd
enum RMWStatus {
STOREIND_RMW_STATUS_UNKNOWN, // RMW status of storeInd unknown
return false;
}
+inline bool GenTree::isContainedSpillTemp() const
+{
+#if !defined(LEGACY_BACKEND)
+ // If spilled and no reg at use, then it is treated as contained.
+ if (((gtFlags & GTF_SPILLED) != 0) &&
+ ((gtFlags & GTF_NOREG_AT_USE) != 0))
+ {
+ return true;
+ }
+#endif //!LEGACY_BACKEND
+
+ return false;
+}
/*****************************************************************************/