Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4a1ba97
Refactor call argument representation
jakobbotsch Mar 26, 2022
8b82719
Run jit-format
jakobbotsch Mar 28, 2022
e6d9776
Value number arg fix
jakobbotsch Mar 28, 2022
3b83e3c
Undo clang-format change
jakobbotsch Mar 28, 2022
5fd50ed
Reorder
jakobbotsch Mar 28, 2022
80e4136
Use helper
jakobbotsch Mar 28, 2022
eb938a5
Fix build
jakobbotsch Mar 28, 2022
53e9e3c
Increase space before nodes to fit call arg names
jakobbotsch Mar 28, 2022
922f9d8
Rename memory kind, fix Unix x86 build, remove occurences of fgArgInfo
jakobbotsch Mar 28, 2022
c360a4f
Remove some more mentions of outdated names
jakobbotsch Mar 28, 2022
44e22cc
Fix assert on macOS arm64
jakobbotsch Mar 28, 2022
421f21f
Fixes for NativeAOT
jakobbotsch Mar 28, 2022
ece3b59
Another fix
jakobbotsch Mar 28, 2022
51c7454
Run jit-format
jakobbotsch Mar 28, 2022
820650c
Small cleanup
jakobbotsch Mar 28, 2022
7235c64
Another small cleanup
jakobbotsch Mar 28, 2022
a337083
More cleanup
jakobbotsch Mar 28, 2022
12819b0
Cleanup
jakobbotsch Mar 28, 2022
053cf9f
Remove some commented code
jakobbotsch Mar 28, 2022
b5ab444
Cleanup
jakobbotsch Mar 28, 2022
6e228d3
Remove unnecessary ctor call
jakobbotsch Mar 28, 2022
42bd8c1
Remove unused declaration
jakobbotsch Mar 28, 2022
dbf30a8
Fix a comment
jakobbotsch Mar 28, 2022
a353013
Fix CFG validator
jakobbotsch Mar 29, 2022
0cf3fc7
Run jit-format
jakobbotsch Mar 29, 2022
3d2261c
Remove unnecessary Clear method
jakobbotsch Mar 30, 2022
fe0f942
Rename CallArg::*Node* -> CallArg::*EarlyNode*
jakobbotsch Mar 30, 2022
0fa91b9
Remove LateArg
jakobbotsch Mar 30, 2022
db1902f
Rename CallArg::GetArgNode -> CallArg::GetNode
jakobbotsch Mar 30, 2022
9875a51
Run jit-format
jakobbotsch Mar 30, 2022
c1e50ad
Fix build
jakobbotsch Mar 30, 2022
bf82eee
Fix unix x86 build
jakobbotsch Mar 30, 2022
43f1d6b
Merge remote-tracking branch 'upstream/main' into refactor-call-args
jakobbotsch Apr 3, 2022
a9af455
Small simplification using new function
jakobbotsch Apr 3, 2022
00ccc70
Small cleanup
jakobbotsch Apr 3, 2022
b3f2851
Write some documentation
jakobbotsch Apr 3, 2022
cd40bf8
Small fix for potential incompatibility
jakobbotsch Apr 3, 2022
bd11bea
Small cleanups and improve documentation
jakobbotsch Apr 3, 2022
997cade
Run jit-format
jakobbotsch Apr 3, 2022
6fb43d1
Assertion fix
jakobbotsch Apr 3, 2022
6dae1f6
Fix for reordered parameters
jakobbotsch Apr 3, 2022
9a3eeff
Fix silly mistake
jakobbotsch Apr 3, 2022
d0d8e28
Merge branch 'main' of github.com:dotnet/runtime into refactor-call-args
jakobbotsch Apr 9, 2022
51061a4
Fix build
jakobbotsch Apr 9, 2022
b79f2f7
Fix LA64
jakobbotsch Apr 10, 2022
c08c4f1
Minor formatting changes
jakobbotsch Apr 10, 2022
e5e0e15
Rename DetermineArgABIInformation and friends
jakobbotsch Apr 10, 2022
64c0ec1
Run jit-format
jakobbotsch Apr 10, 2022
518300f
Merge branch 'main' of github.com:dotnet/runtime into refactor-call-args
jakobbotsch Apr 10, 2022
9b4003d
Small documentation clean up
jakobbotsch Apr 11, 2022
b190869
Reformat
jakobbotsch Apr 11, 2022
ff75346
Address feedback, propagate arg flags properly
jakobbotsch Apr 13, 2022
c53434c
Minor change and rerun failing CI
jakobbotsch Apr 13, 2022
8e38f26
Address feedback
jakobbotsch Apr 14, 2022
722c5d7
Revert check for this needing temp on early expanded calls
jakobbotsch Apr 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ struct CORINFO_SIG_INFO
CorInfoCallConv getCallConv() { return CorInfoCallConv((callConv & CORINFO_CALLCONV_MASK)); }
bool hasThis() { return ((callConv & CORINFO_CALLCONV_HASTHIS) != 0); }
bool hasExplicitThis() { return ((callConv & CORINFO_CALLCONV_EXPLICITTHIS) != 0); }
unsigned totalILArgs() { return (numArgs + hasThis()); }
unsigned totalILArgs() { return (numArgs + (hasThis() ? 1 : 0)); }
bool isVarArg() { return ((getCallConv() == CORINFO_CALLCONV_VARARG) || (getCallConv() == CORINFO_CALLCONV_NATIVEVARARG)); }
bool hasTypeArg() { return ((callConv & CORINFO_CALLCONV_PARAMTYPE) != 0); }
};
Expand Down
13 changes: 6 additions & 7 deletions src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2548,9 +2548,8 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
(call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFCLASS)) ||
(call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFANY)))
{
fgArgInfo* const argInfo = call->fgArgInfo;
GenTree* objectNode = argInfo->GetArgNode(1);
GenTree* methodTableNode = argInfo->GetArgNode(0);
GenTree* objectNode = call->gtArgs.GetArgByIndex(1)->GetArgNode();
GenTree* methodTableNode = call->gtArgs.GetArgByIndex(0)->GetArgNode();

assert(objectNode->TypeGet() == TYP_REF);
assert(methodTableNode->TypeGet() == TYP_I_IMPL);
Expand Down Expand Up @@ -2697,7 +2696,7 @@ void Compiler::optAssertionGen(GenTree* tree)
if (call->NeedsNullCheck() || (call->IsVirtual() && !call->IsTailCall()))
{
// Retrieve the 'this' arg.
GenTree* thisArg = gtGetThisArg(call);
GenTree* thisArg = call->gtArgs.GetThisArg()->GetArgNode();
assert(thisArg != nullptr);
assertionInfo = optCreateAssertion(thisArg, nullptr, OAK_NOT_EQUAL);
}
Expand Down Expand Up @@ -4496,7 +4495,7 @@ GenTree* Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, Gen
{
return nullptr;
}
GenTree* op1 = gtGetThisArg(call);
GenTree* op1 = call->gtArgs.GetThisArg()->GetArgNode();
noway_assert(op1 != nullptr);
if (op1->gtOper != GT_LCL_VAR)
{
Expand Down Expand Up @@ -4555,13 +4554,13 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTANY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS_SPECIAL))
{
GenTree* arg1 = gtArgEntryByArgNum(call, 1)->GetNode();
GenTree* arg1 = call->gtArgs.GetArgByIndex(1)->GetArgNode();
if (arg1->gtOper != GT_LCL_VAR)
{
return nullptr;
}

GenTree* arg2 = gtArgEntryByArgNum(call, 0)->GetNode();
GenTree* arg2 = call->gtArgs.GetArgByIndex(0)->GetArgNode();

unsigned index = optAssertionIsSubtype(arg1, arg2, assertions);
if (index != NO_ASSERTION_INDEX)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1327,7 +1327,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
instruction genGetInsForOper(genTreeOps oper, var_types type);
bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data);
GenTree* getCallTarget(const GenTreeCall* call, CORINFO_METHOD_HANDLE* methHnd);
regNumber getCallIndirectionCellReg(const GenTreeCall* call);
regNumber getCallIndirectionCellReg(GenTreeCall* call);
void genCall(GenTreeCall* call);
void genCallInstruction(GenTreeCall* call X86_ARG(target_ssize_t stackArgBytes));
void genJmpMethod(GenTree* jmp);
Expand Down
35 changes: 16 additions & 19 deletions src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,9 +762,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
unsigned argOffsetOut = treeNode->getArgOffset();

#ifdef DEBUG
fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(treeNode->gtCall, treeNode);
assert(curArgTabEntry != nullptr);
DEBUG_ARG_SLOTS_ASSERT(argOffsetOut == (curArgTabEntry->slotNum * TARGET_POINTER_SIZE));
CallArg* callArg = treeNode->gtCall->gtArgs.FindByNode(treeNode);
assert(callArg != nullptr);
DEBUG_ARG_SLOTS_ASSERT(argOffsetOut == (callArg->AbiInfo.SlotNum * TARGET_POINTER_SIZE));
#endif // DEBUG

// Whether to setup stk arg in incoming or out-going arg area?
Expand Down Expand Up @@ -3120,23 +3120,21 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode)
void CodeGen::genCall(GenTreeCall* call)
{
// Consume all the arg regs
for (GenTreeCall::Use& use : call->LateArgs())
for (LateArg arg : call->gtArgs.LateArgs())
{
GenTree* argNode = use.GetNode();

fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
assert(curArgTabEntry);
CallArgABIInformation& abiInfo = arg.GetArg()->AbiInfo;
GenTree* argNode = arg.GetNode();

// GT_RELOAD/GT_COPY use the child node
argNode = argNode->gtSkipReloadOrCopy();

if (curArgTabEntry->GetRegNum() == REG_STK)
if (abiInfo.GetRegNum() == REG_STK)
continue;

// Deal with multi register passed struct args.
if (argNode->OperGet() == GT_FIELD_LIST)
{
regNumber argReg = curArgTabEntry->GetRegNum();
regNumber argReg = abiInfo.GetRegNum();
for (GenTreeFieldList::Use& use : argNode->AsFieldList()->Uses())
{
GenTree* putArgRegNode = use.GetNode();
Expand All @@ -3157,22 +3155,22 @@ void CodeGen::genCall(GenTreeCall* call)
#endif // TARGET_ARM
}
}
else if (curArgTabEntry->IsSplit())
else if (abiInfo.IsSplit())
{
assert(compFeatureArgSplit());
assert(curArgTabEntry->numRegs >= 1);
assert(abiInfo.NumRegs >= 1);
genConsumeArgSplitStruct(argNode->AsPutArgSplit());
for (unsigned idx = 0; idx < curArgTabEntry->numRegs; idx++)
for (unsigned idx = 0; idx < abiInfo.NumRegs; idx++)
{
regNumber argReg = (regNumber)((unsigned)curArgTabEntry->GetRegNum() + idx);
regNumber argReg = (regNumber)((unsigned)abiInfo.GetRegNum() + idx);
regNumber allocReg = argNode->AsPutArgSplit()->GetRegNumByIdx(idx);
inst_Mov_Extend(argNode->TypeGet(), /* srcInReg */ true, argReg, allocReg, /* canSkip */ true,
emitActualTypeSize(TYP_I_IMPL));
}
}
else
{
regNumber argReg = curArgTabEntry->GetRegNum();
regNumber argReg = abiInfo.GetRegNum();
genConsumeReg(argNode);
inst_Mov_Extend(argNode->TypeGet(), /* srcInReg */ true, argReg, argNode->GetRegNum(), /* canSkip */ true,
emitActualTypeSize(TYP_I_IMPL));
Expand Down Expand Up @@ -3404,12 +3402,11 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
trashedByEpilog |= genRegMask(REG_GSCOOKIE_TMP_1);
}

for (unsigned i = 0; i < call->fgArgInfo->ArgCount(); i++)
for (CallArg& arg : call->gtArgs.Args())
{
fgArgTabEntry* entry = call->fgArgInfo->GetArgEntry(i);
for (unsigned j = 0; j < entry->numRegs; j++)
for (unsigned j = 0; j < arg.AbiInfo.NumRegs; j++)
{
regNumber reg = entry->GetRegNum(j);
regNumber reg = arg.AbiInfo.GetRegNum(j);
if ((trashedByEpilog & genRegMask(reg)) != 0)
{
JITDUMP("Tail call node:\n");
Expand Down
20 changes: 9 additions & 11 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6434,33 +6434,31 @@ GenTree* CodeGen::getCallTarget(const GenTreeCall* call, CORINFO_METHOD_HANDLE*
// Notes:
// We currently use indirection cells for VSD on all platforms and for R2R calls on ARM architectures.
//
regNumber CodeGen::getCallIndirectionCellReg(const GenTreeCall* call)
regNumber CodeGen::getCallIndirectionCellReg(GenTreeCall* call)
{
regNumber result = REG_NA;
switch (call->GetIndirectionCellArgKind())
{
case NonStandardArgKind::None:
case WellKnownArg::None:
break;
case NonStandardArgKind::R2RIndirectionCell:
case WellKnownArg::R2RIndirectionCell:
result = REG_R2R_INDIRECT_PARAM;
break;
case NonStandardArgKind::VirtualStubCell:
case WellKnownArg::VirtualStubCell:
result = compiler->virtualStubParamInfo->GetReg();
break;
default:
unreached();
}

#ifdef DEBUG
regNumber foundReg = REG_NA;
unsigned argCount = call->fgArgInfo->ArgCount();
fgArgTabEntry** argTable = call->fgArgInfo->ArgTable();
for (unsigned i = 0; i < argCount; i++)
regNumber foundReg = REG_NA;
for (CallArg& arg : call->gtArgs.Args())
{
NonStandardArgKind kind = argTable[i]->nonStandardArgKind;
if ((kind == NonStandardArgKind::R2RIndirectionCell) || (kind == NonStandardArgKind::VirtualStubCell))
WellKnownArg kind = arg.GetWellKnownArg();
if ((kind == WellKnownArg::R2RIndirectionCell) || (kind == WellKnownArg::VirtualStubCell))
{
foundReg = argTable[i]->GetRegNum();
foundReg = arg.AbiInfo.GetRegNum();
break;
}
}
Expand Down
38 changes: 17 additions & 21 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5322,14 +5322,12 @@ void CodeGen::genCall(GenTreeCall* call)
}

// Consume all the arg regs
for (GenTreeCall::Use& use : call->LateArgs())
for (LateArg arg : call->gtArgs.LateArgs())
{
GenTree* argNode = use.GetNode();
CallArgABIInformation& abiInfo = arg.GetArg()->AbiInfo;
GenTree* argNode = arg.GetNode();

fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(call, argNode->gtSkipReloadOrCopy());
assert(curArgTabEntry);

if (curArgTabEntry->GetRegNum() == REG_STK)
if (abiInfo.GetRegNum() == REG_STK)
{
continue;
}
Expand All @@ -5343,7 +5341,7 @@ void CodeGen::genCall(GenTreeCall* call)
{
GenTree* putArgRegNode = use.GetNode();
assert(putArgRegNode->gtOper == GT_PUTARG_REG);
regNumber argReg = curArgTabEntry->GetRegNum(regIndex++);
regNumber argReg = abiInfo.GetRegNum(regIndex++);

genConsumeReg(putArgRegNode);

Expand All @@ -5356,7 +5354,7 @@ void CodeGen::genCall(GenTreeCall* call)
else
#endif // UNIX_AMD64_ABI
{
regNumber argReg = curArgTabEntry->GetRegNum();
regNumber argReg = abiInfo.GetRegNum();
genConsumeReg(argNode);
inst_Mov_Extend(argNode->TypeGet(), /* srcInReg */ false, argReg, argNode->GetRegNum(), /* canSkip */ true,
emitActualTypeSize(TYP_I_IMPL));
Expand All @@ -5378,18 +5376,16 @@ void CodeGen::genCall(GenTreeCall* call)
// The call will pop its arguments.
// for each putarg_stk:
target_ssize_t stackArgBytes = 0;
for (GenTreeCall::Use& use : call->Args())
for (CallArg& arg : call->gtArgs.Args())
{
GenTree* arg = use.GetNode();
if (arg->OperIs(GT_PUTARG_STK) && ((arg->gtFlags & GTF_LATE_ARG) == 0))
GenTree* argNode = arg.GetNode();
if (argNode->OperIs(GT_PUTARG_STK) && ((argNode->gtFlags & GTF_LATE_ARG) == 0))
{
GenTree* source = arg->AsPutArgStk()->gtGetOp1();
unsigned size = arg->AsPutArgStk()->GetStackByteSize();
GenTree* source = argNode->AsPutArgStk()->gtGetOp1();
unsigned size = argNode->AsPutArgStk()->GetStackByteSize();
stackArgBytes += size;
#ifdef DEBUG
fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
assert(curArgTabEntry != nullptr);
assert(size == (curArgTabEntry->numSlots * TARGET_POINTER_SIZE));
assert(size == (arg.AbiInfo.NumSlots * TARGET_POINTER_SIZE));
#ifdef FEATURE_PUT_STRUCT_ARG_STK
if (!source->OperIs(GT_FIELD_LIST) && (source->TypeGet() == TYP_STRUCT))
{
Expand All @@ -5401,7 +5397,7 @@ void CodeGen::genCall(GenTreeCall* call)
// Note that on x64/ux this will be handled by unrolling in genStructPutArgUnroll.
assert((argBytes == obj->GetLayout()->GetSize()) || obj->Addr()->IsLocalAddrExpr());
#endif // TARGET_X86
assert((curArgTabEntry->numSlots * TARGET_POINTER_SIZE) == argBytes);
assert((arg.AbiInfo.NumSlots * TARGET_POINTER_SIZE) == argBytes);
}
#endif // FEATURE_PUT_STRUCT_ARG_STK
#endif // DEBUG
Expand Down Expand Up @@ -7992,12 +7988,12 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
// Get argument offset on stack.
// Here we cross check that argument offset hasn't changed from lowering to codegen since
// we are storing arg slot number in GT_PUTARG_STK node in lowering phase.
unsigned argOffset = putArgStk->getArgOffset();
unsigned argOffset = putArgStk->getArgOffset();

#ifdef DEBUG
fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(putArgStk->gtCall, putArgStk);
assert(curArgTabEntry != nullptr);
assert(argOffset == curArgTabEntry->slotNum * TARGET_POINTER_SIZE);
CallArg* callArg = putArgStk->gtCall->gtArgs.FindByNode(putArgStk);
assert(callArg != nullptr);
assert(argOffset == callArg->AbiInfo.SlotNum * TARGET_POINTER_SIZE);
#endif

if (data->isContainedIntOrIImmed())
Expand Down
21 changes: 6 additions & 15 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4463,9 +4463,8 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
if (lvaGetDesc(i)->TypeGet() == TYP_REF)
{
// confirm that the argument is a GC pointer (for debugging (GC stress))
GenTree* op = gtNewLclvNode(i, TYP_REF);
GenTreeCall::Use* args = gtNewCallArgs(op);
op = gtNewHelperCallNode(CORINFO_HELP_CHECK_OBJ, TYP_VOID, args);
GenTree* op = gtNewLclvNode(i, TYP_REF);
op = gtNewHelperCallNode(CORINFO_HELP_CHECK_OBJ, TYP_VOID, op);

fgEnsureFirstBBisScratch();
fgNewStmtAtEnd(fgFirstBB, op);
Expand Down Expand Up @@ -7454,16 +7453,12 @@ Compiler::NodeToIntMap* Compiler::FindReachableNodesInNodeTestData()
{
GenTreeCall* call = tree->AsCall();
unsigned i = 0;
for (GenTreeCall::Use& use : call->Args())
for (CallArg& arg : call->gtArgs.Args())
{
if ((use.GetNode()->gtFlags & GTF_LATE_ARG) != 0)
GenTree* argNode = arg.GetArgNode();
if (GetNodeTestData()->Lookup(argNode, &tlAndN))
{
// Find the corresponding late arg.
GenTree* lateArg = call->fgArgInfo->GetArgNode(i);
if (GetNodeTestData()->Lookup(lateArg, &tlAndN))
{
reachable->Set(lateArg, 0);
}
reachable->Set(argNode, 0);
}
i++;
}
Expand Down Expand Up @@ -9477,10 +9472,6 @@ void cTreeFlags(Compiler* comp, GenTree* tree)
{
chars += printf("[CALL_M_TAILCALL]");
}
if (call->gtCallMoreFlags & GTF_CALL_M_VARARGS)
{
chars += printf("[CALL_M_VARARGS]");
}
if (call->gtCallMoreFlags & GTF_CALL_M_RETBUFFARG)
{
chars += printf("[CALL_M_RETBUFFARG]");
Expand Down
Loading