diff options
author | Brian Sullivan <briansul@microsoft.com> | 2018-03-19 14:19:10 -0700 |
---|---|---|
committer | Brian Sullivan <briansul@microsoft.com> | 2018-03-19 14:19:10 -0700 |
commit | 9835d0508fc3a30cce3566f35e6d19e2f29668bb (patch) | |
tree | 7895500ddcdacb2919907b58ef9d1f9c9bc68a24 /src/jit/flowgraph.cpp | |
parent | 4b4611b9dd8001de7748878734ee4926c262af5d (diff) | |
download | coreclr-9835d0508fc3a30cce3566f35e6d19e2f29668bb.tar.gz coreclr-9835d0508fc3a30cce3566f35e6d19e2f29668bb.tar.bz2 coreclr-9835d0508fc3a30cce3566f35e6d19e2f29668bb.zip |
Fix for fgInstrumentMethod
There was a bug creating profiling images using /Tuning
We computed the wrong value for addrOfBlockCount at the end of this method
This would result in method having proper block counts,
but still not getting marked as being executed.
This regressed in PR #14640
Diffstat (limited to 'src/jit/flowgraph.cpp')
-rw-r--r-- | src/jit/flowgraph.cpp | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index b1a4fef8e2..17ef00f305 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -261,7 +261,7 @@ void Compiler::fgInstrumentMethod() int countOfBlocks = 0; BasicBlock* block; - for (block = fgFirstBB; block; block = block->bbNext) + for (block = fgFirstBB; (block != nullptr); block = block->bbNext) { if (!(block->bbFlags & BBF_IMPORTED) || (block->bbFlags & BBF_INTERNAL)) { @@ -272,11 +272,9 @@ void Compiler::fgInstrumentMethod() // Allocate the profile buffer - ICorJitInfo::ProfileBuffer* bbProfileBuffer; - - HRESULT res = info.compCompHnd->allocBBProfileBuffer(countOfBlocks, &bbProfileBuffer); + ICorJitInfo::ProfileBuffer* bbProfileBufferStart; - ICorJitInfo::ProfileBuffer* bbProfileBufferStart = bbProfileBuffer; + HRESULT res = info.compCompHnd->allocBBProfileBuffer(countOfBlocks, &bbProfileBufferStart); GenTree* stmt; @@ -300,9 +298,16 @@ void Compiler::fgInstrumentMethod() } else { - // Assign a buffer entry for each basic block + // For each BasicBlock (non-Internal) + // 1. Assign the blocks bbCodeOffs to the ILOffset field of this blocks profile data. + // 2. Add an operation that increments the ExecutionCount field at the beginning of the block. - for (block = fgFirstBB; block; block = block->bbNext) + // Each (non-Internal) block has it own ProfileBuffer tuple [ILOffset, ExecutionCount] + // To start we initialize our current one with the first one that we allocated + // + ICorJitInfo::ProfileBuffer* bbCurrentBlockProfileBuffer = bbProfileBufferStart; + + for (block = fgFirstBB; (block != nullptr); block = block->bbNext) { if (!(block->bbFlags & BBF_IMPORTED) || (block->bbFlags & BBF_INTERNAL)) { @@ -310,25 +315,30 @@ void Compiler::fgInstrumentMethod() } // Assign the current block's IL offset into the profile data - bbProfileBuffer->ILOffset = block->bbCodeOffs; + bbCurrentBlockProfileBuffer->ILOffset = block->bbCodeOffs; + assert(bbCurrentBlockProfileBuffer->ExecutionCount == 0); // This value should already be zero-ed out - size_t addrOfBlockCount = (size_t)&bbProfileBuffer->ExecutionCount; + size_t addrOfCurrentExecutionCount = (size_t)&bbCurrentBlockProfileBuffer->ExecutionCount; // Read Basic-Block count value - GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfBlockCount, GTF_ICON_BBC_PTR, false); + GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR, false); // Increment value by 1 GenTree* rhsNode = gtNewOperNode(GT_ADD, TYP_INT, valueNode, gtNewIconNode(1)); // Write new Basic-Block count value - GenTree* lhsNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfBlockCount, GTF_ICON_BBC_PTR, false); + GenTree* lhsNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfCurrentExecutionCount, GTF_ICON_BBC_PTR, false); GenTree* asgNode = gtNewAssignNode(lhsNode, rhsNode); - fgInsertStmtAtBeg(block, asgNode); + fgInsertStmtAtBeg(block, asgNode); + + // Advance to the next ProfileBuffer tuple [ILOffset, ExecutionCount] + bbCurrentBlockProfileBuffer++; + // One less block countOfBlocks--; - bbProfileBuffer++; } + // Check that we allocated and initialized the same number of ProfileBuffer tuples noway_assert(countOfBlocks == 0); // Add the method entry callback node @@ -359,10 +369,11 @@ void Compiler::fgInstrumentMethod() GenTreeArgList* args = gtNewArgList(arg); GenTree* call = gtNewHelperCallNode(CORINFO_HELP_BBT_FCN_ENTER, TYP_VOID, args); - size_t addrOfBlockCount = (size_t)&bbProfileBuffer->ExecutionCount; + // Get the address of the first blocks ExecutionCount + size_t addrOfFirstExecutionCount = (size_t)&bbProfileBufferStart->ExecutionCount; // Read Basic-Block count value - GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfBlockCount, GTF_ICON_BBC_PTR, false); + GenTree* valueNode = gtNewIndOfIconHandleNode(TYP_INT, addrOfFirstExecutionCount, GTF_ICON_BBC_PTR, false); // Compare Basic-Block count value against zero GenTree* relop = gtNewOperNode(GT_NE, TYP_INT, valueNode, gtNewIconNode(0, TYP_INT)); |