Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 10 additions & 2 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7017,8 +7017,16 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
#ifdef DEBUG
if (JitConfig.JitInstrumentIfOptimizing() && opts.OptimizationEnabled() && !IsReadyToRun())
{
JITDUMP("\nForcibly enabling instrumentation\n");
opts.jitFlags->Set(JitFlags::JIT_FLAG_BBINSTR);
// Optionally disable by range
//
static ConfigMethodRange JitInstrumentIfOptimizingRange;
JitInstrumentIfOptimizingRange.EnsureInit(JitConfig.JitInstrumentIfOptimizingRange());
const unsigned hash = impInlineRoot()->info.compMethodHash();
if (JitInstrumentIfOptimizingRange.Contains(hash))
{
JITDUMP("\nEnabling instrumentation\n");
opts.jitFlags->Set(JitFlags::JIT_FLAG_BBINSTR);
}
}
#endif

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ RELEASE_CONFIG_INTEGER(JitCollect64BitCounts, "JitCollect64BitCounts", 0) // Col

CONFIG_INTEGER(JitInstrumentIfOptimizing, "JitInstrumentIfOptimizing", 0) // 1: Always add instrumentation if optimizing
// and not prejitting
CONFIG_STRING(JitInstrumentIfOptimizingRange, "JitInstrumentIfOptimizingRange")

RELEASE_CONFIG_INTEGER(JitInstrumentInlinees, "JitInstrumentInlinees", 1) // Add instrumentation to inlined methods

Expand Down
65 changes: 30 additions & 35 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2127,7 +2127,7 @@ void Lowering::InsertSpecialCopyArg(GenTreePutArgStk* putArgStk, CORINFO_CLASS_H

// Finally move all GT_PUTARG_* nodes
// Re-use the existing logic for CFG call args here
MoveCFGCallArgs(call);
MovePutArgNodesUpToCall(call);

BlockRange().Remove(destPlaceholder);
BlockRange().Remove(srcPlaceholder);
Expand Down Expand Up @@ -2899,13 +2899,24 @@ GenTree* Lowering::LowerCall(GenTree* node)
if (call->IsTailCallViaJitHelper())
{
// Either controlExpr or gtCallAddr must contain real call target.
if (controlExpr == nullptr)
if (controlExpr != nullptr)
{
// Link controlExpr into the IR before the call.
// The callTarget tree needs to be sequenced.
LIR::Range callTargetRange = LIR::SeqTree(comp, controlExpr);
ContainCheckRange(callTargetRange);
BlockRange().InsertBefore(call, std::move(callTargetRange));
}
else
{
// gtCallAddr is already sequenced and just before the call.
assert(call->gtCallType == CT_INDIRECT);
assert(call->gtCallAddr != nullptr);
controlExpr = call->gtCallAddr;
}

// LowerTailCallViaJitHelper will turn the control expr
// into an arg and produce a new control expr for the helper call.
controlExpr = LowerTailCallViaJitHelper(call, controlExpr);
}

Expand Down Expand Up @@ -3468,21 +3479,6 @@ GenTree* Lowering::LowerTailCallViaJitHelper(GenTreeCall* call, GenTree* callTar
InsertPInvokeMethodEpilog(comp->compCurBB DEBUGARG(call));
}

// Remove gtCallAddr from execution order if present.
if (call->gtCallType == CT_INDIRECT)
{
assert(call->gtCallAddr != nullptr);

bool isClosed;
LIR::ReadOnlyRange callAddrRange = BlockRange().GetTreeRange(call->gtCallAddr, &isClosed);
assert(isClosed);

BlockRange().Remove(std::move(callAddrRange));
}

// The callTarget tree needs to be sequenced.
LIR::Range callTargetRange = LIR::SeqTree(comp, callTarget);

// Verify the special args are what we expect, and replace the dummy args with real values.
// We need to figure out the size of the outgoing stack arguments, not including the special args.
// The number of 4-byte words is passed to the helper for the incoming and outgoing argument sizes.
Expand All @@ -3500,9 +3496,6 @@ GenTree* Lowering::LowerTailCallViaJitHelper(GenTreeCall* call, GenTree* callTar
assert(argEntry != nullptr);
GenTree* arg0 = argEntry->GetEarlyNode()->AsPutArgStk()->gtGetOp1();

ContainCheckRange(callTargetRange);
BlockRange().InsertAfter(arg0, std::move(callTargetRange));

bool isClosed;
LIR::ReadOnlyRange secondArgRange = BlockRange().GetTreeRange(arg0, &isClosed);
assert(isClosed);
Expand Down Expand Up @@ -3536,6 +3529,9 @@ GenTree* Lowering::LowerTailCallViaJitHelper(GenTreeCall* call, GenTree* callTar
assert(arg3->OperIs(GT_CNS_INT));
#endif // DEBUG

// Now reorder so all the putargs are just before the call.
MovePutArgNodesUpToCall(call);

// Transform this call node into a call to Jit tail call helper.
call->gtCallType = CT_HELPER;
call->gtCallMethHnd = comp->eeFindHelper(CORINFO_HELP_TAILCALL);
Expand Down Expand Up @@ -3704,7 +3700,7 @@ void Lowering::LowerCFGCall(GenTreeCall* call)
LowerNode(regNode);

// Finally move all GT_PUTARG_* nodes
MoveCFGCallArgs(call);
MovePutArgNodesUpToCall(call);
break;
}
case CFGCallKind::Dispatch:
Expand Down Expand Up @@ -3800,12 +3796,12 @@ bool Lowering::IsCFGCallArgInvariantInRange(GenTree* node, GenTree* endExclusive
}

//------------------------------------------------------------------------
// MoveCFGCallArg: Given a call that will be CFG transformed using the
// validate+call scheme, and an argument GT_PUTARG_* or GT_FIELD_LIST node,
// MovePutArgUpToCall: Given a call that will be transformed using the
// CFG validate+call or similar scheme, and an argument GT_PUTARG_* or GT_FIELD_LIST node,
// move that node right before the call.
//
// Arguments:
// call - The call that is being CFG transformed
// call - The call that is being transformed
// node - The argument node
//
// Remarks:
Expand All @@ -3814,7 +3810,7 @@ bool Lowering::IsCFGCallArgInvariantInRange(GenTree* node, GenTree* endExclusive
// are not always safe to move further ahead; for invariant operands, we
// move them ahead as well to shorten the lifetime of these values.
//
void Lowering::MoveCFGCallArg(GenTreeCall* call, GenTree* node)
void Lowering::MovePutArgUpToCall(GenTreeCall* call, GenTree* node)
{
assert(node->OperIsPutArg() || node->OperIsFieldList());

Expand All @@ -3824,7 +3820,7 @@ void Lowering::MoveCFGCallArg(GenTreeCall* call, GenTree* node)
for (GenTreeFieldList::Use& operand : node->AsFieldList()->Uses())
{
assert(operand.GetNode()->OperIsPutArg());
MoveCFGCallArg(call, operand.GetNode());
MovePutArgUpToCall(call, operand.GetNode());
}
}
else
Expand Down Expand Up @@ -3852,30 +3848,29 @@ void Lowering::MoveCFGCallArg(GenTreeCall* call, GenTree* node)
}

//------------------------------------------------------------------------
// MoveCFGCallArgs: Given a call that will be CFG transformed using the
// validate+call scheme, move all GT_PUTARG_* or GT_FIELD_LIST nodes right before the call.
// MovePutArgNodesUpToCall: Move all GT_PUTARG_* or GT_FIELD_LIST nodes right before the call.
//
// Arguments:
// call - The call that is being CFG transformed
// call - The call that is being transformed
//
// Remarks:
// See comments in MoveCFGCallArg for more details.
// See comments in MovePutArgUpToCall for more details.
//
void Lowering::MoveCFGCallArgs(GenTreeCall* call)
void Lowering::MovePutArgNodesUpToCall(GenTreeCall* call)
{
// Finally move all GT_PUTARG_* nodes
for (CallArg& arg : call->gtArgs.EarlyArgs())
{
GenTree* node = arg.GetEarlyNode();
assert(node->OperIsPutArg() || node->OperIsFieldList());
MoveCFGCallArg(call, node);
MovePutArgUpToCall(call, node);
}

for (CallArg& arg : call->gtArgs.LateArgs())
{
GenTree* node = arg.GetLateNode();
assert(node->OperIsPutArg() || node->OperIsFieldList());
MoveCFGCallArg(call, node);
MovePutArgUpToCall(call, node);
}
}

Expand Down Expand Up @@ -9786,7 +9781,7 @@ bool Lowering::TryLowerBlockStoreAsGcBulkCopyCall(GenTreeBlk* blk)

// Finally move all GT_PUTARG_* nodes
// Re-use the existing logic for CFG call args here
MoveCFGCallArgs(call);
MovePutArgNodesUpToCall(call);

BlockRange().Remove(destPlaceholder);
BlockRange().Remove(sizePlaceholder);
Expand Down Expand Up @@ -9922,7 +9917,7 @@ void Lowering::LowerBlockStoreAsHelperCall(GenTreeBlk* blkNode)

// Finally move all GT_PUTARG_* nodes
// Re-use the existing logic for CFG call args here
MoveCFGCallArgs(call);
MovePutArgNodesUpToCall(call);

BlockRange().Remove(destPlaceholder);
BlockRange().Remove(sizePlaceholder);
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ class Lowering final : public Phase
bool LowerCallMemcmp(GenTreeCall* call, GenTree** next);
bool LowerCallMemset(GenTreeCall* call, GenTree** next);
void LowerCFGCall(GenTreeCall* call);
void MoveCFGCallArgs(GenTreeCall* call);
void MoveCFGCallArg(GenTreeCall* call, GenTree* node);
void MovePutArgNodesUpToCall(GenTreeCall* call);
void MovePutArgUpToCall(GenTreeCall* call, GenTree* node);
#ifndef TARGET_64BIT
GenTree* DecomposeLongCompare(GenTree* cmp);
#endif
Expand Down
Loading