Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: [experiment] Add an explicit IR representation for parameter definitions #92026

Closed
wants to merge 13 commits into from
4 changes: 4 additions & 0 deletions src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
genCodeForStoreLclVar(treeNode->AsLclVar());
break;

case GT_GETPARAM_REG:
// Handled in genConsumeReg.
break;

case GT_RETFILT:
case GT_RETURN:
genReturn(treeNode);
Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2939,6 +2939,18 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere
continue;
}

if (varDsc->lvExplicitParamInit)
{
regState->rsCalleeRegArgMaskLiveIn &= ~genRegMask(varDsc->GetArgReg());
#if FEATURE_MULTIREG_ARGS
if (varDsc->GetOtherArgReg() != REG_NA)
{
regState->rsCalleeRegArgMaskLiveIn &= ~genRegMask(varDsc->GetOtherArgReg());
}
#endif
continue;
}

// When we have a promoted struct we have two possible LclVars that can represent the incoming argument
// in the regArgTab[], either the original TYP_STRUCT argument or the introduced lvStructField.
// We will use the lvStructField if we have a TYPE_INDEPENDENT promoted struct field otherwise
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1512,6 +1512,15 @@ regNumber CodeGen::genConsumeReg(GenTree* tree)
inst_Mov(regType, tree->GetRegNum(), varDsc->GetRegNum(), /* canSkip */ true);
}
}
else if (tree->OperIs(GT_GETPARAM_REG))
{
var_types targetType = tree->TypeGet();
regNumber targetReg = tree->GetRegNum();

regNumber srcReg = tree->AsGetParamReg()->GetArgReg(compiler);

inst_Mov(targetType, targetReg, srcReg, /* canSkip */ true);
}

genUnspillRegIfNeeded(tree);

Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,10 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
genCodeForStoreLclVar(treeNode->AsLclVar());
break;

case GT_GETPARAM_REG:
// Handled in genConsumeReg.
break;

case GT_RETFILT:
case GT_RETURN:
genReturn(treeNode);
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,8 @@ class LclVarDsc

unsigned char lvRedefinedInEmbeddedStatement : 1; // Local has redefinitions inside embedded statements that
// disqualify it from local copy prop.

unsigned char lvExplicitParamInit : 1; // This parameter has explicit IR to initialize it from registers.
private:
unsigned char lvIsNeverNegative : 1; // The local is known to be never negative

Expand Down Expand Up @@ -2477,6 +2479,8 @@ class Compiler

GenTree* gtNewPhysRegNode(regNumber reg, var_types type);

GenTreeGetParamReg* gtNewGetParamRegNode(unsigned lclNum, int regIndex, var_types type);

GenTree* gtNewJmpTableNode();

GenTree* gtNewIndOfIconHandleNode(var_types indType, size_t value, GenTreeFlags iconFlags, bool isInvariant);
Expand Down Expand Up @@ -11182,6 +11186,7 @@ class GenTreeVisitor
case GT_JMPTABLE:
case GT_CLS_VAR_ADDR:
case GT_PHYSREG:
case GT_GETPARAM_REG:
case GT_EMITNOP:
case GT_PINVOKE_PROLOG:
case GT_PINVOKE_EPILOG:
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4479,6 +4479,7 @@ void GenTree::VisitOperands(TVisitor visitor)
case GT_JMPTABLE:
case GT_CLS_VAR_ADDR:
case GT_PHYSREG:
case GT_GETPARAM_REG:
case GT_EMITNOP:
case GT_PINVOKE_PROLOG:
case GT_PINVOKE_EPILOG:
Expand Down
23 changes: 23 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6419,6 +6419,7 @@ bool GenTree::TryGetUse(GenTree* operand, GenTree*** pUse)
case GT_JMPTABLE:
case GT_CLS_VAR_ADDR:
case GT_PHYSREG:
case GT_GETPARAM_REG:
case GT_EMITNOP:
case GT_PINVOKE_PROLOG:
case GT_PINVOKE_EPILOG:
Expand Down Expand Up @@ -7256,6 +7257,12 @@ GenTree* Compiler::gtNewPhysRegNode(regNumber reg, var_types type)
return result;
}

GenTreeGetParamReg* Compiler::gtNewGetParamRegNode(unsigned lclNum, int regIndex, var_types type)
{
GenTreeGetParamReg* result = new (this, GT_GETPARAM_REG) GenTreeGetParamReg(lclNum, regIndex, type);
return result;
}

GenTree* Compiler::gtNewJmpTableNode()
{
return new (this, GT_JMPTABLE) GenTree(GT_JMPTABLE, TYP_I_IMPL);
Expand Down Expand Up @@ -8555,6 +8562,17 @@ void GenTreeOp::CheckDivideByConstOptimized(Compiler* comp)
}
}

regNumber GenTreeGetParamReg::GetArgReg(Compiler* comp)
{
#if FEATURE_MULTIREG_ARGS
LclVarDsc* argDsc = comp->lvaGetDesc(gtArgNum);
return gtRegIndex == 0 ? argDsc->GetArgReg() : argDsc->GetOtherArgReg();
#endif

unreached();
return REG_NA;
}

//------------------------------------------------------------------------
// gtNewPutArgReg: Creates a new PutArgReg node.
//
Expand Down Expand Up @@ -9878,6 +9896,7 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node)
case GT_JMPTABLE:
case GT_CLS_VAR_ADDR:
case GT_PHYSREG:
case GT_GETPARAM_REG:
case GT_EMITNOP:
case GT_PINVOKE_PROLOG:
case GT_PINVOKE_EPILOG:
Expand Down Expand Up @@ -11946,6 +11965,10 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack)
printf(" %s", getRegName(tree->AsPhysReg()->gtSrcReg));
break;

case GT_GETPARAM_REG:
printf(" %s", getRegName(tree->AsGetParamReg()->GetArgReg(this)));
break;

case GT_IL_OFFSET:
printf(" ");
tree->AsILOffset()->gtStmtDI.Dump(true);
Expand Down
19 changes: 19 additions & 0 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3085,6 +3085,25 @@ struct GenTreePhysReg : public GenTree
#endif
};

struct GenTreeGetParamReg : public GenTree
{
unsigned gtArgNum;
int gtRegIndex;

GenTreeGetParamReg(unsigned argNum, int regIndex, var_types type)
: GenTree(GT_GETPARAM_REG, type), gtArgNum(argNum), gtRegIndex(regIndex)
{
}

#if DEBUGGABLE_GENTREE
GenTreeGetParamReg() : GenTree()
{
}
#endif

regNumber GetArgReg(Compiler* comp);
};

/* gtIntCon -- integer constant (GT_CNS_INT) */
struct GenTreeIntCon : public GenTreeIntConCommon
{
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/gtlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ GTNODE(PUTARG_STK , GenTreePutArgStk ,0,0,GTK_UNOP|GTK_NOVALUE|DBK_NOTHI
#if FEATURE_ARG_SPLIT
GTNODE(PUTARG_SPLIT , GenTreePutArgSplit ,0,0,GTK_UNOP|DBK_NOTHIR) // operator that places outgoing arg in registers with stack (split struct in ARM32)
#endif // FEATURE_ARG_SPLIT
GTNODE(GETPARAM_REG , GenTreeGetParamReg ,0,0,GTK_LEAF|DBK_NOTHIR) // use of parameter; only expected at the beginning of the first BB.
GTNODE(SWAP , GenTreeOp ,0,0,GTK_BINOP|GTK_NOVALUE|DBK_NOTHIR) // op1 and op2 swap (registers)
GTNODE(COPY , GenTreeCopyOrReload,0,0,GTK_UNOP|DBK_NOTHIR) // Copies a variable from its current location to a register that satisfies
GTNODE(RELOAD , GenTreeCopyOrReload,0,0,GTK_UNOP|DBK_NOTHIR) // code generation constraints. The operand is the actual lclVar node.
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/gtstructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ GTSTRUCT_1(PutArgSplit , GT_PUTARG_SPLIT)
GTSTRUCT_1(PutArgStk , GT_PUTARG_STK)
#endif // !FEATURE_ARG_SPLIT
GTSTRUCT_1(PhysReg , GT_PHYSREG)
GTSTRUCT_1(GetParamReg , GT_GETPARAM_REG)
#ifdef FEATURE_HW_INTRINSICS
GTSTRUCT_1(HWIntrinsic , GT_HWINTRINSIC)
#endif // FEATURE_HW_INTRINSICS
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,9 @@ CONFIG_STRING(JitStressRange, W("JitStressRange")) // Internal Jit
/// JIT Hardware Intrinsics
///
CONFIG_INTEGER(EnableIncompleteISAClass, W("EnableIncompleteISAClass"), 0) // Enable testing not-yet-implemented
#endif // defined(DEBUG)

CONFIG_INTEGER(JitExplicitParameterDefs, W("JitExplicitParameterDefs"), 1)
#endif // defined(DEBUG)

CONFIG_METHODSET(JitDisasm, W("JitDisasm")) // Print codegen for given methods
CONFIG_INTEGER(JitDisasmTesting, W("JitDisasmTesting"), 0) // Display BEGIN METHOD/END METHOD anchors for disasm testing
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/liveness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1998,6 +1998,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR
case GT_CNS_VEC:
case GT_CLS_VAR_ADDR:
case GT_PHYSREG:
case GT_GETPARAM_REG:
// These are all side-effect-free leaf nodes.
if (node->IsUnusedValue())
{
Expand Down
Loading
Loading