summaryrefslogtreecommitdiff
path: root/src/jit/flowgraph.cpp
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2018-03-19 14:19:10 -0700
committerBrian Sullivan <briansul@microsoft.com>2018-03-19 14:19:10 -0700
commit9835d0508fc3a30cce3566f35e6d19e2f29668bb (patch)
tree7895500ddcdacb2919907b58ef9d1f9c9bc68a24 /src/jit/flowgraph.cpp
parent4b4611b9dd8001de7748878734ee4926c262af5d (diff)
downloadcoreclr-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.cpp41
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));