static LONG jitNestingLevel;
#endif // DEBUG
- static BOOL impIsAddressInLocal(GenTree* tree, GenTree** lclVarTreeOut);
+ static BOOL impIsAddressInLocal(const GenTree* tree, GenTree** lclVarTreeOut);
void impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo, InlineResult* inlineResult);
GenTree* fgMorphMultiregStructArg(GenTree* arg, fgArgTabEntry* fgEntryPtr);
bool killGCRefs(GenTree* tree);
-
}; // end of class Compiler
//---------------------------------------------------------------------------------------------------------------------
if (firstNode->gtFlags & strictEffects & GTF_PERSISTENT_SIDE_EFFECTS)
{
// We have to be conservative - can swap iff op2 is constant.
- if (!secondNode->OperIsConst())
+ if (!secondNode->IsInvariant())
{
canSwap = false;
}
return false;
}
#endif // TARGET_ARM
+
+bool GenTree::IsInvariant() const
+{
+ GenTree* lclVarTree = nullptr;
+ return OperIsConst() || Compiler::impIsAddressInLocal(this, &lclVarTree);
+}
public:
bool Precedes(GenTree* other);
+ bool IsInvariant() const;
+
bool IsReuseRegVal() const
{
// This can be extended to non-constant nodes, but not to local or indir nodes.
- if (OperIsConst() && ((gtFlags & GTF_REUSE_REG_VAL) != 0))
+ if (IsInvariant() && ((gtFlags & GTF_REUSE_REG_VAL) != 0))
{
return true;
}
}
void SetReuseRegVal()
{
- assert(OperIsConst());
+ assert(IsInvariant());
gtFlags |= GTF_REUSE_REG_VAL;
}
void ResetReuseRegVal()
{
- assert(OperIsConst());
+ assert(IsInvariant());
gtFlags &= ~GTF_REUSE_REG_VAL;
}
*/
-BOOL Compiler::impIsAddressInLocal(GenTree* tree, GenTree** lclVarTreeOut)
+BOOL Compiler::impIsAddressInLocal(const GenTree* tree, GenTree** lclVarTreeOut)
{
if (tree->gtOper != GT_ADDR)
{
INDEBUG(curArgVal->AsLclVar()->gtLclILoffs = argNum;)
}
- if ((curArgVal->OperKind() & GTK_CONST) || isAddressInLocal)
+ if (curArgVal->IsInvariant())
{
inlCurArgInfo->argIsInvariant = true;
if (inlCurArgInfo->argIsThis && (curArgVal->gtOper == GT_CNS_INT) && (curArgVal->AsIntCon()->gtIconVal == 0))
fgArgTabEntry* prevArgTabEntry = argTable[prevInx];
assert(prevArgTabEntry->argNum < curArgTabEntry->argNum);
- // TODO-CQ: We should also allow LCL_VAR_ADDR and LCL_FLD_ADDR here, they're
- // side effect free leaf nodes that like constant can be evaluated at any point.
- if (prevArgTabEntry->GetNode()->gtOper != GT_CNS_INT)
+ if (!prevArgTabEntry->GetNode()->IsInvariant())
{
prevArgTabEntry->needTmp = true;
needsTemps = true;