Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/infra/J9Cfg.cpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include <algorithm>
24
#include <limits.h>
25
#include <stdio.h>
26
#include <stdint.h>
27
#include <string.h>
28
#include "compile/Compilation.hpp"
29
#include "control/Options.hpp"
30
#include "control/Options_inlines.hpp"
31
#include "control/Recompilation.hpp"
32
#include "control/RecompilationInfo.hpp"
33
#include "cs2/arrayof.h"
34
#include "cs2/bitvectr.h"
35
#include "cs2/listof.h"
36
#include "env/TRMemory.hpp"
37
#include "env/PersistentInfo.hpp"
38
#include "env/VMJ9.h"
39
#include "il/Block.hpp"
40
#include "il/ILOpCodes.hpp"
41
#include "il/ILOps.hpp"
42
#include "il/LabelSymbol.hpp"
43
#include "il/Node.hpp"
44
#include "il/Node_inlines.hpp"
45
#include "il/ResolvedMethodSymbol.hpp"
46
#include "il/Symbol.hpp"
47
#include "il/SymbolReference.hpp"
48
#include "il/TreeTop.hpp"
49
#include "il/TreeTop_inlines.hpp"
50
#include "infra/Assert.hpp"
51
#include "infra/Cfg.hpp"
52
#include "infra/Link.hpp"
53
#include "infra/List.hpp"
54
#include "infra/Stack.hpp"
55
#include "infra/TRCfgEdge.hpp"
56
#include "infra/TRCfgNode.hpp"
57
#include "optimizer/Optimizer.hpp"
58
#include "optimizer/Structure.hpp"
59
#include "optimizer/StructuralAnalysis.hpp"
60
#include "ras/Debug.hpp"
61
#include "runtime/ExternalProfiler.hpp"
62
#include "runtime/J9Profiler.hpp"
63
64
#ifdef __MVS__
65
#include <stdlib.h>
66
#endif
67
68
69
static TR_PersistentProfileInfo *getProfilingInfoForCFG(TR::Compilation *comp, TR::CFG *cfg)
70
{
71
TR_PersistentProfileInfo *info = TR_PersistentProfileInfo::get(comp);
72
if (cfg == comp->getFlowGraph()
73
&& comp->getRecompilationInfo())
74
return info;
75
76
if ((*(TR_BlockFrequencyInfo::getEnableJProfilingRecompilation())) == -1
77
&& cfg->getMethodSymbol()
78
&& cfg->getMethodSymbol()->getResolvedMethod()
79
&& info
80
&& info->getBlockFrequencyInfo()
81
&& info->getBlockFrequencyInfo()->isJProfilingData())
82
{
83
return info;
84
}
85
return NULL;
86
}
87
88
static bool hasBlockFrequencyInfo(TR::Compilation *comp, TR::CFG *cfg)
89
{
90
TR_PersistentProfileInfo *profileInfo = getProfilingInfoForCFG(comp, cfg);
91
return profileInfo && profileInfo->getBlockFrequencyInfo();
92
}
93
94
static bool hasJProfilingInfo(TR::Compilation *comp, TR::CFG *cfg)
95
{
96
static char *disableJProfilingForInner = feGetEnv("TR_disableJProfilingForInner");
97
TR_PersistentProfileInfo *profileInfo = getProfilingInfoForCFG(comp, cfg);
98
if (disableJProfilingForInner == NULL
99
&& profileInfo
100
&& profileInfo->getBlockFrequencyInfo()
101
&& profileInfo->getBlockFrequencyInfo()->isJProfilingData()
102
&& ((*(TR_BlockFrequencyInfo::getEnableJProfilingRecompilation())) == -1))
103
{
104
TR_ByteCodeInfo toCheck;
105
toCheck.setByteCodeIndex(0);
106
toCheck.setCallerIndex(comp->getCurrentInlinedSiteIndex());
107
int32_t entryFrequency = profileInfo->getBlockFrequencyInfo()->getFrequencyInfo(toCheck, comp, false, false);
108
if (entryFrequency > -1)
109
{
110
return true;
111
}
112
}
113
return false;
114
}
115
116
bool
117
J9::CFG::setFrequencies()
118
{
119
if (this == comp()->getFlowGraph())
120
{
121
resetFrequencies();
122
}
123
_max_edge_freq = MAX_PROF_EDGE_FREQ;
124
125
TR_ExternalProfiler *profiler;
126
127
// Do not use JIT profiler info for estimate code size.
128
bool externFreq = ! comp()->getOption(TR_EnableScorchInterpBlockFrequencyProfiling);
129
bool hasJPI = hasJProfilingInfo(comp(), self());
130
if (externFreq
131
&& comp()->hasBlockFrequencyInfo()
132
&& (
133
(!hasJPI && (this == comp()->getFlowGraph()))
134
|| (hasJPI && ((*(TR_BlockFrequencyInfo::getEnableJProfilingRecompilation())) == -1))
135
)
136
)
137
{
138
if (!self()->consumePseudoRandomFrequencies())
139
{
140
_externalProfiler = comp()->fej9()->hasIProfilerBlockFrequencyInfo(*comp());
141
TR_BitVector *nodesToBeNormalized = self()->setBlockAndEdgeFrequenciesBasedOnJITProfiler();
142
self()->normalizeFrequencies(nodesToBeNormalized);
143
if (comp()->getOption(TR_TraceBFGeneration))
144
{
145
traceMsg(comp(), "CFG of %s after setting frequencies using JITProfiling\n", self()->getMethodSymbol()->signature(comp()->trMemory()));
146
comp()->dumpFlowGraph(self());
147
}
148
if (this == comp()->getFlowGraph() && comp()->getInlinedCalls() > 0)
149
{
150
for (TR::Block *block = comp()->getStartBlock(); block; block = block->getNextBlock())
151
{
152
if (!block->getEntry() || !block->getEntry()->getNode())
153
{
154
continue;
155
}
156
TR_ByteCodeInfo &bci = block->getEntry()->getNode()->getByteCodeInfo();
157
TR::ResolvedMethodSymbol *inlinedMethod = bci.getCallerIndex() == -1 ? comp()->getMethodSymbol() : comp()->getInlinedResolvedMethodSymbol(bci.getCallerIndex());
158
}
159
}
160
}
161
162
if (comp()->getOption(TR_VerbosePseudoRandom))
163
emitVerbosePseudoRandomFrequencies();
164
165
return true;
166
}
167
else if ((profiler = comp()->fej9()->hasIProfilerBlockFrequencyInfo(*comp())))
168
{
169
if (!self()->consumePseudoRandomFrequencies())
170
{
171
profiler->setBlockAndEdgeFrequencies(self(), comp());
172
if (self()->getMethodSymbol())
173
{
174
TR::CFGNode *nextNode = self()->getFirstNode();
175
for (; nextNode != NULL; nextNode = nextNode->getNext())
176
{
177
if (nextNode->asBlock()->getEntry()
178
&& self()->getMethodSymbol()->getProfilerFrequency(nextNode->asBlock()->getEntry()->getNode()->getByteCodeIndex()) < 0)
179
self()->getMethodSymbol()->setProfilerFrequency(nextNode->asBlock()->getEntry()->getNode()->getByteCodeIndex(), nextNode->asBlock()->getFrequency());
180
}
181
}
182
}
183
184
if (comp()->getOption(TR_VerbosePseudoRandom))
185
emitVerbosePseudoRandomFrequencies();
186
187
return true;
188
}
189
else if (comp()->getFlowGraph()->getStructure() && (comp()->getFlowGraph() == self()))
190
{
191
if (!self()->consumePseudoRandomFrequencies())
192
{
193
_max_edge_freq = MAX_STATIC_EDGE_FREQ;
194
self()->setBlockAndEdgeFrequenciesBasedOnStructure();
195
if (comp()->getOption(TR_TraceBFGeneration))
196
comp()->dumpMethodTrees("Trees after setting frequencies from structures", comp()->getMethodSymbol());
197
}
198
199
if (comp()->getOption(TR_VerbosePseudoRandom))
200
emitVerbosePseudoRandomFrequencies();
201
202
return true;
203
}
204
205
return false;
206
}
207
208
209
#define GUESS_THRESHOLD 100
210
211
static bool isVirtualGuard(TR::Node *ifNode)
212
{
213
return (ifNode->isTheVirtualGuardForAGuardedInlinedCall() || ifNode->isProfiledGuard());
214
}
215
216
217
TR_BitVector *
218
J9::CFG::setBlockAndEdgeFrequenciesBasedOnJITProfiler()
219
{
220
TR_PersistentProfileInfo *profileInfo = getProfilingInfoForCFG(comp(), self());
221
222
if (!profileInfo)
223
return NULL;
224
225
TR_BlockFrequencyInfo *blockFrequencyInfo = profileInfo->getBlockFrequencyInfo();
226
227
int32_t maxCount = profileInfo->getMaxCount();
228
229
TR_BitVector *nodesToBeNormalized = NULL;
230
TR::CFGNode *node;
231
232
int32_t *nodeFrequencies = NULL;
233
if (_maxFrequency < 0)
234
{
235
nodeFrequencies = (int32_t*) trMemory()->allocateStackMemory(sizeof(int32_t) * self()->getNextNodeNumber());
236
for (node = getFirstNode(); node; node = node->getNext())
237
{
238
int32_t nodeNumber = toBlock(node)->getNumber();
239
nodeFrequencies[nodeNumber] = blockFrequencyInfo->getFrequencyInfo(toBlock(node), comp());
240
if ((nodeFrequencies[nodeNumber] >= _maxFrequency) && (nodeFrequencies[nodeNumber] >= 0))
241
_maxFrequency = nodeFrequencies[nodeNumber];
242
}
243
}
244
245
int32_t origMaxFrequency = _maxFrequency;
246
247
createTraversalOrder(true, stackAlloc);
248
249
TR::CFGNode *nextNode = getFirstNode();
250
for (; nextNode != NULL; nextNode = nextNode->getNext())
251
{
252
TR_SuccessorIterator sit(nextNode);
253
TR::CFGEdge * edge = sit.getFirst();
254
for(; edge != NULL; edge=sit.getNext())
255
{
256
if (comp()->getOption(TR_TraceBFGeneration))
257
traceMsg(comp(), "edge visit count = %d\n", edge->getVisitCount());
258
edge->setVisitCount(1);
259
}
260
}
261
262
for (int32_t traversalIndex = 0; traversalIndex < getForwardTraversalLength(); traversalIndex++)
263
{
264
node = getForwardTraversalElement(traversalIndex);
265
int32_t frequency = node->getFrequency();
266
if (frequency < 0)
267
{
268
frequency = nodeFrequencies ? nodeFrequencies[toBlock(node)->getNumber()] : blockFrequencyInfo->getFrequencyInfo(toBlock(node), comp());
269
//frequency = nodeFrequencies[toBlock(node)->getNumber()];
270
271
bool isGuardedBlock = false;
272
bool isProfiledGuard = false;
273
bool isGuardedBlockFallThrough = false;
274
int32_t combinedPredRawFrequency = 0;
275
TR_PredecessorIterator pit(node);
276
TR::CFGEdge *edge;
277
for (edge = pit.getFirst(); edge; edge = pit.getNext())
278
{
279
TR::Block *block = edge->getFrom()->asBlock();
280
TR::TreeTop *lastTree = NULL;
281
if (block->getExit())
282
lastTree = block->getLastRealTreeTop();
283
if (lastTree &&
284
lastTree->getNode()->getOpCode().isIf() &&
285
isVirtualGuard(lastTree->getNode()))
286
{
287
if (lastTree->getNode()->getBranchDestination() == node->asBlock()->getEntry())
288
{
289
isGuardedBlock = true;
290
if (lastTree->getNode()->isProfiledGuard())
291
isProfiledGuard = true;
292
}
293
else
294
isGuardedBlockFallThrough = true;
295
}
296
}
297
298
// Infer a frequency based on frequencies of predecessors.
299
// We can use this if we have nothing better.
300
//
301
for (edge = pit.getFirst(); edge; edge = pit.getNext())
302
{
303
TR::Block *pred = edge->getFrom()->asBlock();
304
305
// Compute this predecessor's raw frequency
306
//
307
int32_t predRawFrequency = pred->getFrequency();
308
if (predRawFrequency < 0)
309
{
310
// This should be unusual. Getting here means we haven't
311
// processed a predecessor, which (due to our reverse postorder
312
// traversal) means we're in a loop. Even then, loops usually
313
// have pretty good raw profiling info, so we still usually don't
314
// see -1. However, it can happen, so let's make some attempt to
315
// get a decent guess at a frequency.
316
//
317
predRawFrequency = blockFrequencyInfo->getFrequencyInfo(pred, comp());
318
predRawFrequency = std::max(predRawFrequency, 0);
319
predRawFrequency = std::min(predRawFrequency, maxCount);
320
}
321
else if (nodesToBeNormalized && nodesToBeNormalized->isSet(pred->getNumber()))
322
{
323
// Frequency is already raw; leave it alone
324
}
325
else
326
{
327
predRawFrequency = TR::CFGNode::denormalizedFrequency(predRawFrequency, origMaxFrequency);
328
}
329
330
bool effectiveSingleton = false;
331
TR::TreeTop *lastTree = NULL;
332
if (pred && pred->getExit())
333
lastTree = pred->getLastRealTreeTop();
334
if (lastTree &&
335
lastTree->getNode()->getOpCode().isIf())
336
{
337
TR::Block *fallThrough = pred->getNextBlock();
338
TR::Block *branchTarget = lastTree->getNode()->getBranchDestination()->getEnclosingBlock();
339
if (fallThrough && branchTarget)
340
{
341
if (comp()->getOption(TR_TraceBFGeneration))
342
traceMsg(comp(), " checking effective singleton on block_%d with fallthrough block_%d and branchTarget block_%d\n", pred->getNumber(), fallThrough->getNumber(), branchTarget->getNumber());
343
if (fallThrough == node && !fallThrough->isCold() && branchTarget->isCold())
344
effectiveSingleton = true;
345
else if (branchTarget == node && !branchTarget->isCold() && fallThrough->isCold())
346
effectiveSingleton = true;
347
}
348
}
349
350
if (comp()->getOption(TR_TraceBFGeneration) && pred)
351
traceMsg(comp(), " block_%d's pred block_%d has normalized frequency %d and %s\n",
352
node->getNumber(),
353
pred->getNumber(),
354
predRawFrequency,
355
(pred->getSuccessors().size() == 1)? "one successor" : (effectiveSingleton ? "one effective successor" : "multiple successors"));
356
357
// Use predecessor's frequency as appropriate
358
//
359
if (((pred->getSuccessors().size() == 1) && pred->hasSuccessor(node)) || effectiveSingleton)
360
{
361
combinedPredRawFrequency += predRawFrequency;
362
if (comp()->getOption(TR_TraceBFGeneration))
363
traceMsg(comp(), " combinedPredRawFrequency is now %d\n", combinedPredRawFrequency);
364
}
365
else if (isGuardedBlock)
366
{
367
if (comp()->getOption(TR_TraceBFGeneration))
368
traceMsg(comp(), " %d is a guarded block; ignoring predecessor\n", node->getNumber());
369
}
370
else if (pred && pred->hasSuccessor(node) && (frequency < 0 || (!blockFrequencyInfo->isJProfilingData() && pred->getFrequency() <= GUESS_THRESHOLD)))
371
{
372
int32_t succCount = 0;
373
for (auto edge = pred->getSuccessors().begin(); edge != pred->getSuccessors().end(); ++edge)
374
{
375
if ((*edge)->getTo() && (*edge)->getTo()->asBlock() && node->asBlock()
376
&& (*edge)->getTo()->asBlock() != node->asBlock()
377
&& (*edge)->getTo()->getFrequency() > -1)
378
predRawFrequency -= (*edge)->getTo()->getFrequency();
379
else
380
succCount++;
381
}
382
if (predRawFrequency > 0)
383
{
384
combinedPredRawFrequency += succCount ? (predRawFrequency / succCount) : predRawFrequency;
385
if (comp()->getOption(TR_TraceBFGeneration))
386
traceMsg(comp(), " combinedPredRawFrequency is now %d based on succCount %d and predRawFrequency %d\n", combinedPredRawFrequency, succCount, predRawFrequency);
387
}
388
else
389
{
390
// Can't figure out how often we get here from this pred, and can't ignore it.
391
// Fall back on old wild-guess heuristic.
392
// NOTE: this uses a normalized frequency where it should be a
393
// raw one, but this bug has been in Java6 for ages, so we don't
394
// want to change in an SR.
395
//
396
combinedPredRawFrequency += origMaxFrequency / 4; // probably intended something like denormalizedFrequency(25,100)
397
if (comp()->getOption(TR_TraceBFGeneration))
398
traceMsg(comp(), " can't figure out frequency; defaulting to wild guess %d\n", combinedPredRawFrequency);
399
}
400
}
401
else if (frequency < 0 || (!blockFrequencyInfo->isJProfilingData() && pred->getFrequency() <= GUESS_THRESHOLD))
402
{
403
// Can't figure out how often we get here from this pred, and can't ignore it.
404
// Fall back on old wild-guess heuristic.
405
// NOTE: this uses a normalized frequency where it should be a
406
// raw one, but this bug has been in Java6 for ages, so we don't
407
// want to change in an SR.
408
//
409
combinedPredRawFrequency = origMaxFrequency / 4; // probably intended something like denormalizedFrequency(25,100)
410
if (comp()->getOption(TR_TraceBFGeneration))
411
traceMsg(comp(), " can't figure out frequency; defaulting to wild guess %d\n", combinedPredRawFrequency);
412
break;
413
}
414
}
415
416
combinedPredRawFrequency = std::min(maxCount, combinedPredRawFrequency);
417
418
if (_compilation->getOption(TR_TraceBFGeneration))
419
traceMsg(comp(), "Raw frequency for block_%d is %d (maxCount %d origMax %d combinedPredRawFrequency %d)\n", node->getNumber(), frequency, maxCount, origMaxFrequency, combinedPredRawFrequency);
420
421
if (frequency <= 0)
422
frequency = combinedPredRawFrequency;
423
424
if (frequency > maxCount)
425
frequency = maxCount;
426
427
if (isGuardedBlock)
428
{
429
if (isProfiledGuard)
430
frequency = MAX_COLD_BLOCK_COUNT+1;
431
else
432
frequency = VERSIONED_COLD_BLOCK_COUNT;
433
}
434
435
436
//if (!isGuardedBlock)
437
{
438
if (comp()->getOption(TR_TraceBFGeneration))
439
traceMsg(comp(), " Setting block_%d frequency %d (origMaxFrequency %d)\n", node->getNumber(), frequency, origMaxFrequency);
440
if ((frequency > origMaxFrequency) &&
441
(origMaxFrequency > -1))
442
{
443
if (!isGuardedBlock)
444
{
445
if (!nodesToBeNormalized)
446
nodesToBeNormalized = new (trStackMemory()) TR_BitVector(getNextNodeNumber(), trMemory(), stackAlloc);
447
448
nodesToBeNormalized->set(node->getNumber());
449
//dumpOptDetails(comp(),"NOT normalized %d freq %d\n", node->getNumber(), frequency);
450
}
451
node->setFrequency(frequency);
452
}
453
else
454
{
455
node->setFrequency(frequency);
456
if (!isGuardedBlock)
457
node->normalizeFrequency(frequency, origMaxFrequency);
458
//dumpOptDetails(comp(),"Normalized %d freq %d\n", node->getNumber(), node->getFrequency());
459
}
460
}
461
//else
462
// node->setFrequency(frequency);
463
}
464
465
// DORIT: node->frequency is finalized and set. See if can infer anything about edge frequency:
466
// visitCount>1 indicates that a final frequency for the edge had been set.
467
frequency = node->getFrequency();
468
if (frequency >= 0 && (node->getSuccessors().size() == 1) && (node->getSuccessors().front()->getTo()->getPredecessors().size() == 1))
469
{
470
TR::CFGEdge *edge = node->getSuccessors().front();
471
TR::Block *succ = edge->getTo()->asBlock();
472
473
if (comp()->getOption(TR_TraceBFGeneration))
474
traceMsg(comp(), "node %d has single succ. set Frequency for edge %d->%d to %d final.\n", node->getNumber(), node->getNumber(), succ->getNumber(), frequency);
475
476
if (edge->getVisitCount()>1)
477
{
478
if (comp()->getOption(TR_TraceBFGeneration))
479
traceMsg(comp(), "edge visitCount=%d.\n",edge->getVisitCount());
480
}
481
else
482
{
483
edge->setFrequency(frequency);
484
edge->setVisitCount(2);
485
}
486
}
487
488
if (frequency >= 0 && (node->getPredecessors().size() == 1) && (node->getPredecessors().front()->getFrom()->getSuccessors().size() == 1))
489
{
490
TR::CFGEdge *edge = node->getPredecessors().front();
491
TR::Block *pred = edge->getFrom()->asBlock();
492
493
if (comp()->getOption(TR_TraceBFGeneration))
494
traceMsg(comp(), "node %d has single pred. set Frequency for edge %d->%d to %d final.\n", node->getNumber(), pred->getNumber(), node->getNumber(), frequency);
495
496
if (edge->getVisitCount()>1)
497
{
498
if (comp()->getOption(TR_TraceBFGeneration))
499
traceMsg(comp(), "edge visitCount=%d.\n",edge->getVisitCount());
500
}
501
else
502
{
503
edge->setFrequency(frequency);
504
edge->setVisitCount(2);
505
}
506
}
507
}
508
509
if (nodesToBeNormalized)
510
{
511
for (node = getFirstNode(); node; node = node->getNext())
512
{
513
int32_t frequency = node->getFrequency();
514
if (!nodesToBeNormalized->get(node->getNumber()) &&
515
!node->asBlock()->isCold())
516
{
517
nodesToBeNormalized->set(node->getNumber());
518
//dumpOptDetails(comp(),"denormalizing node %d (BEFORE) with freq %d\n", node->getNumber(), frequency);
519
frequency = node->denormalizeFrequency(origMaxFrequency);
520
//dumpOptDetails(comp(),"denormalizing node %d (AFTER) with freq %d\n", node->getNumber(), frequency);
521
}
522
523
if (frequency > _maxFrequency)
524
_maxFrequency = frequency;
525
//dumpOptDetails(comp(), "_maxFrequency = %d\n", _maxFrequency);
526
}
527
}
528
529
//dumpOptDetails(comp(), "_maxFrequency = %d\n", _maxFrequency);
530
531
_maxEdgeFrequency = -1;
532
533
// Turn off this loop code below when propagation is
534
// fixed
535
//
536
for (node = getFirstNode(); node; node = node->getNext())
537
{
538
int32_t frequency = node->getFrequency();
539
if (frequency >= 0)
540
{
541
int32_t successorFrequency = 0;
542
for (auto e = node->getSuccessors().begin(); e != node->getSuccessors().end(); ++e)
543
{
544
int32_t normalizedFrequency = (*e)->getTo()->getFrequency();
545
546
// DORIT: try to infer about edge frequencies
547
// visitCount>1 indicates that a final frequency for the edge had been set.
548
if ((*e)->getVisitCount() > 1)
549
{
550
// don't add to successorFrequency sum;
551
// peek at "cousin" blocks to see if frequency of other edges can be determined.
552
// step1: if this successor has only one other predecessor...:
553
TR::Block *succ = (*e)->getTo()->asBlock();
554
if (succ->getPredecessors().size() == 2) //succ has only one other predecessor
555
{
556
TR::CFGEdge *ee = succ->getPredecessors().front();
557
if (ee->getFrom() == node)
558
ee = *(++(succ->getPredecessors().begin()));
559
if ((succ->getFrequency() >= 0) && (succ->getFrequency() >= (*e)->getFrequency()))
560
{
561
int32_t ff = succ->getFrequency() - (*e)->getFrequency();
562
if (comp()->getOption(TR_TraceBFGeneration))
563
traceMsg(comp(), "\t\tedge(%d->%d) frequency can be set to succ_%d(%d) - e_freq(%d->%d)(%d) = ee_freq(%d)\n",
564
ee->getFrom()->getNumber(), ee->getTo()->getNumber(), succ->getNumber(), succ->getFrequency(), (*e)->getFrom()->getNumber(), (*e)->getTo()->getNumber(),(*e)->getFrequency(), ff);
565
if (ee->getVisitCount()>1)
566
{
567
if (comp()->getOption(TR_TraceBFGeneration))
568
traceMsg(comp(), "\t\tedge frequency = %d already final\n", ee->getFrequency());
569
}
570
else
571
{
572
ee->setFrequency(ff);
573
ee->setVisitCount(2);
574
if (comp()->getOption(TR_TraceBFGeneration))
575
traceMsg(comp(), "\t\tset edge frequency = %d as final\n", ff);
576
}
577
578
//TODO: can continue to check the other successors of this predecessor
579
}
580
}
581
}
582
else
583
successorFrequency = successorFrequency + normalizedFrequency;
584
585
//dumpOptDetails("normalizedFreq %d succFreq %d node %d succ %d\n", normalizedFrequency, successorFrequency, node->getNumber(), e->getTo()->getNumber());
586
}
587
588
//if (successorFrequency > 0)
589
{
590
for (auto e = node->getSuccessors().begin(); e != node->getSuccessors().end(); ++e)
591
{
592
//if (e->getFrequency() <= 0)
593
{
594
int32_t toFrequency = (*e)->getTo()->getFrequency();
595
int32_t edgeFrequency;
596
if ((toFrequency > MAX_COLD_BLOCK_COUNT) && (frequency > MAX_COLD_BLOCK_COUNT))
597
{
598
if (successorFrequency > 0)
599
{
600
edgeFrequency = (frequency*toFrequency)/successorFrequency;
601
if (edgeFrequency <= MAX_COLD_BLOCK_COUNT)
602
edgeFrequency = MAX_COLD_BLOCK_COUNT+1;
603
}
604
else
605
edgeFrequency = 0;
606
}
607
else
608
{
609
if (toFrequency < frequency)
610
edgeFrequency = toFrequency;
611
else
612
edgeFrequency = frequency;
613
}
614
615
//dumpOptDetails("edgeFrequency %d frequency %d toFrequency %d succFrequency %d max %d\n", edgeFrequency, frequency, toFrequency, successorFrequency, SHRT_MAX);
616
if ((*e)->getVisitCount() > 1)
617
{
618
if (comp()->getOption(TR_TraceBFGeneration))
619
traceMsg(comp(), "\t\tedge frequency = %d is final, don't change\n", (*e)->getFrequency());
620
edgeFrequency = (*e)->getFrequency();
621
}
622
else
623
(*e)->setFrequency(edgeFrequency);
624
625
if (edgeFrequency > _maxEdgeFrequency)
626
_maxEdgeFrequency = edgeFrequency;
627
//dumpOptDetails("Edge %p between %d and %d has freq %d max %d\n", e, e->getFrom()->getNumber(), e->getTo()->getNumber(), e->getFrequency(), _maxEdgeFrequency);
628
}
629
}
630
}
631
632
if (_externalProfiler && (node->getSuccessors().size() == 2))
633
{
634
bool frequencyIsIdentical = true;
635
int32_t deFrq = node->getSuccessors().front()->getFrequency();
636
if(deFrq != (*(++node->getSuccessors().begin()))->getFrequency())
637
frequencyIsIdentical = false;
638
// if both edges have same frequency then break the tie
639
// using interpreter frequencies
640
if (frequencyIsIdentical)
641
{
642
TR::Block *block = node->asBlock();
643
if (!block->isCold() && block->getEntry()!=NULL && block->getLastRealTreeTop()->getNode()->getOpCode().isBranch())
644
{
645
TR::Node *ifNode = block->getLastRealTreeTop()->getNode();
646
int32_t fallThroughCount = 0;
647
int32_t branchToCount = 0;
648
649
_externalProfiler->getBranchCounters(ifNode, block->getNextBlock()->getEntry(), &branchToCount, &fallThroughCount, comp());
650
651
if (branchToCount > fallThroughCount)
652
{
653
TR::Block *branchToBlock = ifNode->getBranchDestination()->getNode()->getBlock();
654
655
for (auto e = node->getSuccessors().begin(); e != node->getSuccessors().end(); ++e)
656
{
657
if ((*e)->getTo()->asBlock() == branchToBlock)
658
{
659
//dumpOptDetails(comp(), "\tadjusting branch to frequency to %d in order to break the tie\n", deFrq+1);
660
(*e)->setFrequency(deFrq+1);
661
branchToBlock->setFrequency(branchToBlock->getFrequency()+1);
662
break;
663
}
664
}
665
}
666
}
667
}
668
}
669
670
int32_t predecessorFrequency = 0;
671
for (auto e = node->getPredecessors().begin(); e != node->getPredecessors().end(); ++e)
672
{
673
int32_t normalizedFrequency = (*e)->getFrom()->getFrequency();
674
675
// DORIT: try to infer about edge frequencies
676
if ((*e)->getVisitCount() > 1)
677
{
678
// don't add to successorFrequency sum;
679
// peek at cousin blocks to see if frequency of other edges can be determined.
680
// step1: if this successor has only one other predecessor...:
681
TR::Block *pred = (*e)->getFrom()->asBlock();
682
if (pred->getSuccessors().size() == 2) //pred has only one other successor
683
{
684
TR::CFGEdge *ee = pred->getSuccessors().front();
685
if (ee->getTo() == node)
686
ee = *(++pred->getSuccessors().begin());
687
if ((pred->getFrequency() >= 0) &&
688
(pred->getFrequency() >= (*e)->getFrequency()))
689
{
690
int32_t ff = pred->getFrequency() - (*e)->getFrequency();
691
if (comp()->getOption(TR_TraceBFGeneration))
692
traceMsg(comp(), "\t\tedge(%d->%d) frequency can be set to pred_%d(%d) - e_freq(%d->%d)(%d) = ee_freq(%d)\n",
693
ee->getFrom()->getNumber(), ee->getTo()->getNumber(), pred->getNumber(), pred->getFrequency(), (*e)->getFrom()->getNumber(), (*e)->getTo()->getNumber(), (*e)->getFrequency(), ff);
694
695
if (ee->getVisitCount()>1)
696
{
697
if (comp()->getOption(TR_TraceBFGeneration))
698
traceMsg(comp(), "\t\tedge frequency = %d already final\n", ee->getFrequency());
699
}
700
else
701
{
702
ee->setFrequency(ff);
703
ee->setVisitCount(2);
704
if (comp()->getOption(TR_TraceBFGeneration))
705
traceMsg(comp(), "\t\tset edge frequency = %d as final\n", ff);
706
}
707
708
//TODO: can continue to check the other successors of this predecessor
709
}
710
}
711
}
712
else
713
predecessorFrequency = predecessorFrequency + normalizedFrequency;
714
715
//dumpOptDetails("normalizedFreq %d succFreq %d node %d succ %d\n", normalizedFrequency, successorFrequency, node->getNumber(), e->getTo()->getNumber());
716
}
717
718
//if (predecessorFrequency > 0)
719
{
720
for (auto e = node->getPredecessors().begin(); e != node->getPredecessors().end(); ++e)
721
{
722
//if (e->getFrequency() <= 0)
723
{
724
int32_t fromFrequency = (*e)->getFrom()->getFrequency();
725
int32_t edgeFrequency;
726
if ((fromFrequency > MAX_COLD_BLOCK_COUNT) && (frequency > MAX_COLD_BLOCK_COUNT))
727
{
728
if (predecessorFrequency > 0)
729
{
730
edgeFrequency = (frequency*fromFrequency)/predecessorFrequency;
731
if (edgeFrequency <= MAX_COLD_BLOCK_COUNT)
732
edgeFrequency = MAX_COLD_BLOCK_COUNT+1;
733
}
734
else
735
edgeFrequency = 0;
736
}
737
else
738
{
739
if (fromFrequency < frequency)
740
edgeFrequency = fromFrequency;
741
else
742
edgeFrequency = frequency;
743
}
744
745
//dumpOptDetails("edgeFrequency %d frequency %d toFrequency %d succFrequency %d max %d\n", edgeFrequency, frequency, toFrequency, successorFrequency, SHRT_MAX);
746
747
if ((*e)->getVisitCount() > 1)
748
{
749
if (comp()->getOption(TR_TraceBFGeneration))
750
traceMsg(comp(), "\t\tedge frequency = %d is final, don't change\n", (*e)->getFrequency());
751
edgeFrequency = (*e)->getFrequency();
752
}
753
else
754
(*e)->setFrequency(edgeFrequency);
755
756
if (edgeFrequency > _maxEdgeFrequency)
757
_maxEdgeFrequency = edgeFrequency;
758
//dumpOptDetails("Edge %p between %d and %d has freq %d max %d\n", e, e->getFrom()->getNumber(), e->getTo()->getNumber(), e->getFrequency(), _maxEdgeFrequency);
759
}
760
}
761
}
762
}
763
else
764
{
765
if (frequency > origMaxFrequency)
766
{
767
if (!nodesToBeNormalized)
768
nodesToBeNormalized = new (trStackMemory()) TR_BitVector(getNextNodeNumber(), trMemory(), stackAlloc);
769
770
nodesToBeNormalized->set(node->getNumber());
771
//dumpOptDetails(comp(),"NOT normalized %d freq %d\n", node->getNumber(), frequency);
772
}
773
}
774
}
775
776
777
nextNode = getFirstNode();
778
for (; nextNode != NULL; nextNode = nextNode->getNext())
779
{
780
TR_SuccessorIterator sit(nextNode);
781
TR::CFGEdge * edge = sit.getFirst();
782
for(; edge != NULL; edge=sit.getNext())
783
edge->setVisitCount(0);
784
}
785
786
return nodesToBeNormalized;
787
}
788
789
790
static int32_t summarizeFrequencyFromPredecessors(TR::CFGNode *node, TR::CFG *cfg)
791
{
792
int32_t sum = 0;
793
TR_PredecessorIterator pit(node);
794
795
for (TR::CFGEdge *edge = pit.getFirst(); edge; edge = pit.getNext())
796
{
797
TR::CFGNode *pred = edge->getFrom();
798
799
if (edge->getFrequency()<=0)
800
continue;
801
802
int32_t edgeFreq = edge->getFrequency();
803
804
/*TR_BitVector *frequencySet = cfg->getFrequencySet();
805
806
if (frequencySet)
807
{
808
if (!frequencySet->get(pred->getNumber()))
809
{
810
int32_t rawScalingFactor = cfg->getOldMaxEdgeFrequency();
811
if (rawScalingFactor < 0)
812
rawScalingFactor = cfg->getMaxEdgeFrequency();
813
814
//traceMsg(comp, "raw scaling %d max %d old max %d\n", rawScalingFactor, cfg->getMaxEdgeFrequency(), cfg->getOldMaxEdgeFrequency());
815
816
if (rawScalingFactor > 0)
817
{
818
if (edgeFreq > MAX_COLD_BLOCK_COUNT)
819
{
820
edgeFreq = (rawScalingFactor*edgeFreq)/(MAX_COLD_BLOCK_COUNT+MAX_BLOCK_COUNT);
821
}
822
}
823
}
824
} */
825
826
sum += edgeFreq;
827
}
828
829
return sum;
830
}
831
832
833
void
834
J9::CFG::setBlockFrequenciesBasedOnInterpreterProfiler()
835
{
836
TR::StackMemoryRegion stackMemoryRegion(*trMemory());
837
int32_t numBlocks = getNextNodeNumber();
838
839
TR_BitVector *_seenNodes = new (trStackMemory()) TR_BitVector(numBlocks, trMemory(), stackAlloc, notGrowable);
840
TR_BitVector *_seenNodesInCycle = new (trStackMemory()) TR_BitVector(numBlocks, trMemory(), stackAlloc, notGrowable);
841
_frequencySet = new (trHeapMemory()) TR_BitVector(numBlocks, trMemory(), heapAlloc, notGrowable);
842
int32_t startFrequency = AVG_FREQ;
843
int32_t taken = AVG_FREQ;
844
int32_t nottaken = AVG_FREQ;
845
int32_t initialCallScanFreq = -1;
846
int32_t inlinedSiteIndex = -1;
847
848
// Walk until we find if or switch statement
849
TR::CFGNode *start = getStart();
850
TR::CFGNode *temp = start;
851
TR_ScratchList<TR::CFGNode> upStack(trMemory());
852
853
bool backEdgeExists = false;
854
TR::TreeTop *methodScanEntry = NULL;
855
//_maxFrequency = 0;
856
while ( (temp->getSuccessors().size() == 1) ||
857
!temp->asBlock()->getEntry() ||
858
!((temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch()
859
&& !temp->asBlock()->getLastRealTreeTop()->getNode()->getByteCodeInfo().doNotProfile()) ||
860
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::lookup ||
861
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::table))
862
{
863
if (_seenNodes->isSet(temp->getNumber()))
864
break;
865
866
upStack.add(temp);
867
_seenNodes->set(temp->getNumber());
868
869
if (!backEdgeExists && !temp->getPredecessors().empty() && !(temp->getPredecessors().size() == 1))
870
{
871
if (comp()->getHCRMode() != TR::osr)
872
backEdgeExists = true;
873
else
874
{
875
// Count the number of edges from non OSR blocks
876
int32_t nonOSREdges = 0;
877
for (auto edge = temp->getPredecessors().begin(); edge != temp->getPredecessors().end(); ++edge)
878
{
879
if ((*edge)->getFrom()->asBlock()->isOSRCodeBlock() || (*edge)->getFrom()->asBlock()->isOSRCatchBlock())
880
continue;
881
if (nonOSREdges > 0)
882
{
883
backEdgeExists = true;
884
break;
885
}
886
nonOSREdges++;
887
}
888
}
889
}
890
891
if (temp->asBlock()->getEntry() && initialCallScanFreq < 0)
892
{
893
int32_t methodScanFreq = scanForFrequencyOnSimpleMethod(temp->asBlock()->getEntry(), temp->asBlock()->getExit());
894
if (methodScanFreq > 0)
895
initialCallScanFreq = methodScanFreq;
896
inlinedSiteIndex = temp->asBlock()->getEntry()->getNode()->getInlinedSiteIndex();
897
methodScanEntry = temp->asBlock()->getEntry();
898
}
899
900
if (!temp->getSuccessors().empty())
901
{
902
if ((temp->getSuccessors().size() == 2) && temp->asBlock() && temp->asBlock()->getNextBlock())
903
{
904
temp = temp->asBlock()->getNextBlock();
905
}
906
else
907
temp = temp->getSuccessors().front()->getTo();
908
}
909
else
910
break;
911
}
912
913
if (comp()->getOption(TR_TraceBFGeneration))
914
dumpOptDetails(comp(),"Propagation start block_%d\n", temp->getNumber());
915
916
if (temp->asBlock()->getEntry())
917
inlinedSiteIndex = temp->asBlock()->getEntry()->getNode()->getInlinedSiteIndex();
918
919
if ((temp->getSuccessors().size() == 2) &&
920
temp->asBlock()->getEntry() &&
921
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch() &&
922
!temp->asBlock()->getLastRealTreeTop()->getNode()->getByteCodeInfo().doNotProfile())
923
{
924
getInterpreterProfilerBranchCountersOnDoubleton(temp, &taken, &nottaken);
925
startFrequency = taken + nottaken;
926
self()->setEdgeFrequenciesOnNode( temp, taken, nottaken, comp());
927
}
928
else if (temp->asBlock()->getEntry() &&
929
(temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::lookup ||
930
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::table))
931
{
932
startFrequency = _externalProfiler->getSumSwitchCount(temp->asBlock()->getLastRealTreeTop()->getNode(), comp());
933
if (comp()->getOption(TR_TraceBFGeneration))
934
dumpOptDetails(comp(),"Switch with total frequency of %d\n", startFrequency);
935
setSwitchEdgeFrequenciesOnNode(temp, comp());
936
}
937
else
938
{
939
if (_calledFrequency > 0)
940
startFrequency = _calledFrequency;
941
else if (initialCallScanFreq > 0)
942
startFrequency = initialCallScanFreq;
943
else
944
{
945
startFrequency = AVG_FREQ;
946
}
947
948
if ((temp->getSuccessors().size() == 2) && (startFrequency > 0) && temp->asBlock()->getEntry() && temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch())
949
self()->setEdgeFrequenciesOnNode( temp, 0, startFrequency, comp());
950
else
951
self()->setUniformEdgeFrequenciesOnNode(temp, startFrequency, false, comp());
952
}
953
954
setBlockFrequency (temp, startFrequency);
955
_initialBlockFrequency = startFrequency;
956
957
if (comp()->getOption(TR_TraceBFGeneration))
958
dumpOptDetails(comp(),"Set frequency of %d on block_%d\n", temp->asBlock()->getFrequency(), temp->getNumber());
959
960
start = temp;
961
962
// Walk backwards to the start and propagate this frequency
963
964
if (comp()->getOption(TR_TraceBFGeneration))
965
dumpOptDetails(comp(),"Propagating start frequency backwards...\n");
966
967
ListIterator<TR::CFGNode> upit(&upStack);
968
for (temp = upit.getFirst(); temp; temp = upit.getNext())
969
{
970
if (!temp->asBlock()->getEntry())
971
continue;
972
if ((temp->getSuccessors().size() == 2) && (startFrequency > 0) && temp->asBlock()->getEntry() && temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch())
973
self()->setEdgeFrequenciesOnNode( temp, 0, startFrequency, comp());
974
else
975
self()->setUniformEdgeFrequenciesOnNode( temp, startFrequency, false, comp());
976
setBlockFrequency (temp, startFrequency);
977
_seenNodes->set(temp->getNumber());
978
979
if (comp()->getOption(TR_TraceBFGeneration))
980
dumpOptDetails(comp(),"Set frequency of %d on block_%d\n", temp->asBlock()->getFrequency(), temp->getNumber());
981
}
982
983
if (comp()->getOption(TR_TraceBFGeneration))
984
dumpOptDetails(comp(),"Propagating block frequency forward...\n");
985
986
// Walk reverse post-order
987
// we start at the first if or switch statement
988
TR_ScratchList<TR::CFGNode> stack(trMemory());
989
stack.add(start);
990
991
while (!stack.isEmpty())
992
{
993
TR::CFGNode *node = stack.popHead();
994
995
if (comp()->getOption(TR_TraceBFGeneration))
996
traceMsg(comp(), "Considering block_%d\n", node->getNumber());
997
998
if (_seenNodes->isSet(node->getNumber()))
999
continue;
1000
1001
_seenNodes->set(node->getNumber());
1002
1003
if (!node->asBlock()->getEntry())
1004
continue;
1005
1006
inlinedSiteIndex = node->asBlock()->getEntry()->getNode()->getInlinedSiteIndex();
1007
1008
if (node->asBlock()->isCold())
1009
{
1010
if (comp()->getOption(TR_TraceBFGeneration))
1011
dumpOptDetails(comp(),"Analyzing COLD block_%d\n", node->getNumber());
1012
//node->asBlock()->setFrequency(0);
1013
int32_t freq = node->getFrequency();
1014
if ((node->getSuccessors().size() == 2) && (freq > 0) && node->asBlock()->getEntry() && node->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch())
1015
self()->setEdgeFrequenciesOnNode( node, 0, freq, comp());
1016
else
1017
self()->setUniformEdgeFrequenciesOnNode(node, freq, false, comp());
1018
setBlockFrequency (node, freq);
1019
//continue;
1020
}
1021
1022
// ignore the first node
1023
if (!node->asBlock()->isCold() && (node != start))
1024
{
1025
if ((node->getSuccessors().size() == 2) &&
1026
node->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch())
1027
{
1028
// if it's an if and it's not JIT inserted artificial if then just
1029
// read the outgoing branches and put that as node frequency
1030
// else get frequency from predecessors
1031
if (!isVirtualGuard(node->asBlock()->getLastRealTreeTop()->getNode()) &&
1032
!node->asBlock()->getLastRealTreeTop()->getNode()->getByteCodeInfo().doNotProfile())
1033
{
1034
_seenNodesInCycle->empty();
1035
getInterpreterProfilerBranchCountersOnDoubleton(node, &taken, &nottaken);
1036
1037
if ((taken <= 0) && (nottaken <= 0))
1038
{
1039
taken = LOW_FREQ;
1040
nottaken = LOW_FREQ;
1041
}
1042
1043
self()->setEdgeFrequenciesOnNode( node, taken, nottaken, comp());
1044
setBlockFrequency (node, taken + nottaken);
1045
1046
if (comp()->getOption(TR_TraceBFGeneration))
1047
dumpOptDetails(comp(),"If on node %p is not guard I'm using the taken and nottaken counts for producing block frequency\n", node->asBlock()->getLastRealTreeTop()->getNode());
1048
}
1049
else
1050
{
1051
if (comp()->getOption(TR_TraceBFGeneration))
1052
{
1053
TR_PredecessorIterator pit(node);
1054
for (TR::CFGEdge *edge = pit.getFirst(); edge; edge = pit.getNext())
1055
{
1056
TR::CFGNode *pred = edge->getFrom();
1057
1058
if (edge->getFrequency()<=0)
1059
continue;
1060
1061
int32_t edgeFreq = edge->getFrequency();
1062
1063
if (comp()->getOption(TR_TraceBFGeneration))
1064
traceMsg(comp(), "11Pred %d has freq %d\n", pred->getNumber(), edgeFreq);
1065
}
1066
}
1067
1068
TR::CFGNode *predNotSet = NULL;
1069
TR_PredecessorIterator pit(node);
1070
for (TR::CFGEdge *edge = pit.getFirst(); edge; edge = pit.getNext())
1071
{
1072
TR::CFGNode *pred = edge->getFrom();
1073
1074
if (pred->getFrequency()< 0)
1075
{
1076
predNotSet = pred;
1077
break;
1078
}
1079
}
1080
1081
if (predNotSet &&
1082
!_seenNodesInCycle->get(node->getNumber()))
1083
{
1084
stack.add(predNotSet);
1085
_seenNodesInCycle->set(node->getNumber());
1086
_seenNodes->reset(node->getNumber());
1087
continue;
1088
}
1089
1090
if (!predNotSet)
1091
_seenNodesInCycle->empty();
1092
1093
int32_t sumFreq = summarizeFrequencyFromPredecessors(node, self());
1094
if (sumFreq <= 0)
1095
sumFreq = AVG_FREQ;
1096
self()->setEdgeFrequenciesOnNode( node, 0, sumFreq, comp());
1097
setBlockFrequency (node, sumFreq);
1098
1099
if (comp()->getOption(TR_TraceBFGeneration))
1100
dumpOptDetails(comp(),"If on node %p is guard I'm using the predecessor frequency sum\n", node->asBlock()->getLastRealTreeTop()->getNode());
1101
}
1102
1103
if (comp()->getOption(TR_TraceBFGeneration))
1104
dumpOptDetails(comp(),"Set frequency of %d on block_%d\n", node->asBlock()->getFrequency(), node->getNumber());
1105
}
1106
else if (node->asBlock()->getEntry() &&
1107
(node->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::lookup ||
1108
node->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::table))
1109
{
1110
_seenNodesInCycle->empty();
1111
int32_t sumFreq = _externalProfiler->getSumSwitchCount(node->asBlock()->getLastRealTreeTop()->getNode(), comp());
1112
setSwitchEdgeFrequenciesOnNode(node, comp());
1113
setBlockFrequency (node, sumFreq);
1114
if (comp()->getOption(TR_TraceBFGeneration))
1115
{
1116
dumpOptDetails(comp(),"Found a Switch statement at exit of block_%d\n", node->getNumber());
1117
dumpOptDetails(comp(),"Set frequency of %d on block_%d\n", node->asBlock()->getFrequency(), node->getNumber());
1118
}
1119
}
1120
else
1121
{
1122
TR::CFGNode *predNotSet = NULL;
1123
int32_t sumFreq = 0;
1124
TR_PredecessorIterator pit(node);
1125
for (TR::CFGEdge *edge = pit.getFirst(); edge; edge = pit.getNext())
1126
{
1127
TR::CFGNode *pred = edge->getFrom();
1128
1129
if (pred->getFrequency()< 0)
1130
{
1131
predNotSet = pred;
1132
break;
1133
}
1134
1135
int32_t edgeFreq = edge->getFrequency();
1136
sumFreq += edgeFreq;
1137
}
1138
1139
if (predNotSet &&
1140
!_seenNodesInCycle->get(node->getNumber()))
1141
{
1142
_seenNodesInCycle->set(node->getNumber());
1143
_seenNodes->reset(node->getNumber());
1144
stack.add(predNotSet);
1145
continue;
1146
}
1147
else
1148
{
1149
if (!predNotSet)
1150
_seenNodesInCycle->empty();
1151
1152
if (comp()->getOption(TR_TraceBFGeneration))
1153
traceMsg(comp(), "2Setting block and uniform freqs\n");
1154
1155
if ((node->getSuccessors().size() == 2) && (sumFreq > 0) && node->asBlock()->getEntry() && node->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch())
1156
self()->setEdgeFrequenciesOnNode( node, 0, sumFreq, comp());
1157
else
1158
self()->setUniformEdgeFrequenciesOnNode( node, sumFreq, false, comp());
1159
setBlockFrequency (node, sumFreq);
1160
}
1161
1162
if (comp()->getOption(TR_TraceBFGeneration))
1163
{
1164
dumpOptDetails(comp(),"Not an if (or unknown if) at exit of block %d (isSingleton=%d)\n", node->getNumber(), (node->getSuccessors().size() == 1));
1165
dumpOptDetails(comp(),"Set frequency of %d on block %d\n", node->asBlock()->getFrequency(), node->getNumber());
1166
}
1167
}
1168
}
1169
1170
TR_SuccessorIterator sit(node);
1171
// add the successors on the list
1172
for (TR::CFGEdge *edge = sit.getFirst(); edge; edge = sit.getNext())
1173
{
1174
TR::CFGNode *succ = edge->getTo();
1175
1176
if (!_seenNodes->isSet(succ->getNumber()))
1177
stack.add(succ);
1178
else
1179
{
1180
if (!(((succ->getSuccessors().size() == 2) &&
1181
succ->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch()) ||
1182
(succ->asBlock()->getEntry() &&
1183
(succ->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::lookup ||
1184
succ->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::table))))
1185
{
1186
setBlockFrequency ( succ, edge->getFrequency(), true);
1187
1188
// addup this edge to the frequency of the blocks following it
1189
// propagate downward until you reach a block that doesn't end in
1190
// goto or cycle
1191
if (succ->getSuccessors().size() == 1)
1192
{
1193
TR::CFGNode *tempNode = succ->getSuccessors().front()->getTo();
1194
TR_BitVector *_seenGotoNodes = new (trStackMemory()) TR_BitVector(numBlocks, trMemory(), stackAlloc, notGrowable);
1195
_seenGotoNodes->set(succ->getNumber());
1196
while ((tempNode->getSuccessors().size() == 1) &&
1197
(tempNode != succ) &&
1198
(tempNode != getEnd()) &&
1199
!_seenGotoNodes->isSet(tempNode->getNumber()))
1200
{
1201
TR::CFGNode *nextTempNode = tempNode->getSuccessors().front()->getTo();
1202
1203
if (comp()->getOption(TR_TraceBFGeneration))
1204
traceMsg(comp(), "3Setting block and uniform freqs\n");
1205
1206
self()->setUniformEdgeFrequenciesOnNode( tempNode, edge->getFrequency(), true, comp());
1207
setBlockFrequency (tempNode, edge->getFrequency(), true);
1208
1209
_seenGotoNodes->set(tempNode->getNumber());
1210
tempNode = nextTempNode;
1211
}
1212
}
1213
}
1214
}
1215
}
1216
}
1217
1218
1219
if (backEdgeExists)
1220
{
1221
while (!upStack.isEmpty())
1222
{
1223
TR::CFGNode *temp = upStack.popHead();
1224
if (temp == start)
1225
continue;
1226
1227
if (backEdgeExists)
1228
temp->setFrequency(std::max(MAX_COLD_BLOCK_COUNT+1, startFrequency/10));
1229
}
1230
}
1231
1232
1233
// now set all the blocks that haven't been seen to have 0 frequency
1234
// catch blocks are one example, we don't try to set frequency there to
1235
// save compilation time, since those are most frequently cold. Future might prove
1236
// this otherwise.
1237
1238
TR::CFGNode *node;
1239
start = getStart();
1240
for (node = getFirstNode(); node; node=node->getNext())
1241
{
1242
if ((node == getEnd()) || (node == start))
1243
node->asBlock()->setFrequency(0);
1244
1245
if (_seenNodes->isSet(node->getNumber()))
1246
continue;
1247
1248
if (node->asBlock()->getEntry() &&
1249
(node->asBlock()->getFrequency()<0))
1250
node->asBlock()->setFrequency(0);
1251
}
1252
1253
//scaleEdgeFrequencies();
1254
1255
TR_BitVector *nodesToBeNormalized = new (trStackMemory()) TR_BitVector(numBlocks, trMemory(), stackAlloc, notGrowable);
1256
nodesToBeNormalized->setAll(numBlocks);
1257
_maxFrequency = -1;
1258
_maxEdgeFrequency = -1;
1259
normalizeFrequencies(nodesToBeNormalized);
1260
_oldMaxFrequency = _maxFrequency;
1261
_oldMaxEdgeFrequency = _maxEdgeFrequency;
1262
1263
if (comp()->getOption(TR_TraceBFGeneration))
1264
traceMsg(comp(), "max freq %d max edge freq %d\n", _maxFrequency, _maxEdgeFrequency);
1265
1266
}
1267
1268
1269
void
1270
J9::CFG::computeInitialBlockFrequencyBasedOnExternalProfiler(TR::Compilation *comp)
1271
{
1272
TR_ExternalProfiler* profiler = comp->fej9()->hasIProfilerBlockFrequencyInfo(*comp);
1273
if (!profiler)
1274
{
1275
_initialBlockFrequency = AVG_FREQ;
1276
return;
1277
}
1278
1279
_externalProfiler = profiler;
1280
1281
TR::StackMemoryRegion stackMemoryRegion(*trMemory());
1282
int32_t numBlocks = getNextNodeNumber();
1283
1284
TR_BitVector *_seenNodes = new (trStackMemory()) TR_BitVector(numBlocks, trMemory(), stackAlloc, notGrowable);
1285
_frequencySet = new (trHeapMemory()) TR_BitVector(numBlocks, trMemory(), heapAlloc, notGrowable);
1286
int32_t startFrequency = AVG_FREQ;
1287
int32_t taken = AVG_FREQ;
1288
int32_t nottaken = AVG_FREQ;
1289
int32_t initialCallScanFreq = -1;
1290
int32_t inlinedSiteIndex = -1;
1291
1292
// Walk until we find if or switch statement
1293
TR::CFGNode *start = getStart();
1294
TR::CFGNode *temp = start;
1295
1296
bool backEdgeExists = false;
1297
TR::TreeTop *methodScanEntry = NULL;
1298
1299
while ( (temp->getSuccessors().size() == 1) ||
1300
!temp->asBlock()->getEntry() ||
1301
!((temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch()
1302
&& !temp->asBlock()->getLastRealTreeTop()->getNode()->getByteCodeInfo().doNotProfile()) ||
1303
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::lookup ||
1304
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::table))
1305
{
1306
if (_seenNodes->isSet(temp->getNumber()))
1307
break;
1308
1309
_seenNodes->set(temp->getNumber());
1310
1311
if (!temp->getPredecessors().empty() && !(temp->getPredecessors().size() == 1))
1312
backEdgeExists = true;
1313
1314
if (temp->asBlock()->getEntry() && initialCallScanFreq < 0)
1315
{
1316
int32_t methodScanFreq = scanForFrequencyOnSimpleMethod(temp->asBlock()->getEntry(), temp->asBlock()->getExit());
1317
if (methodScanFreq > 0)
1318
initialCallScanFreq = methodScanFreq;
1319
inlinedSiteIndex = temp->asBlock()->getEntry()->getNode()->getInlinedSiteIndex();
1320
methodScanEntry = temp->asBlock()->getEntry();
1321
}
1322
1323
if (!temp->getSuccessors().empty())
1324
{
1325
if ((temp->getSuccessors().size() == 2) && temp->asBlock() && temp->asBlock()->getNextBlock())
1326
{
1327
temp = temp->asBlock()->getNextBlock();
1328
}
1329
else
1330
temp = temp->getSuccessors().front()->getTo();
1331
}
1332
else
1333
break;
1334
}
1335
1336
if (temp->asBlock()->getEntry())
1337
inlinedSiteIndex = temp->asBlock()->getEntry()->getNode()->getInlinedSiteIndex();
1338
1339
if ((temp->getSuccessors().size() == 2) &&
1340
temp->asBlock()->getEntry() &&
1341
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCode().isBranch() &&
1342
!temp->asBlock()->getLastRealTreeTop()->getNode()->getByteCodeInfo().doNotProfile())
1343
{
1344
getInterpreterProfilerBranchCountersOnDoubleton(temp, &taken, &nottaken);
1345
if ((taken <= 0) && (nottaken <= 0))
1346
{
1347
taken = LOW_FREQ;
1348
nottaken = LOW_FREQ;
1349
}
1350
startFrequency = taken + nottaken;
1351
}
1352
else if (temp->asBlock()->getEntry() &&
1353
(temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::lookup ||
1354
temp->asBlock()->getLastRealTreeTop()->getNode()->getOpCodeValue() == TR::table))
1355
{
1356
startFrequency = _externalProfiler->getSumSwitchCount(temp->asBlock()->getLastRealTreeTop()->getNode(), comp);
1357
}
1358
else
1359
{
1360
if (_calledFrequency > 0)
1361
startFrequency = _calledFrequency;
1362
else if (initialCallScanFreq > 0)
1363
startFrequency = initialCallScanFreq;
1364
else
1365
{
1366
startFrequency = AVG_FREQ;
1367
}
1368
}
1369
1370
if (startFrequency <= 0)
1371
startFrequency = LOW_FREQ;
1372
1373
_initialBlockFrequency = startFrequency;
1374
}
1375
1376
1377
static int32_t
1378
getParentCallCount(TR::CFG *cfg, TR::Node *node)
1379
{
1380
if (node->getByteCodeInfo().getCallerIndex() >=-1)
1381
{
1382
int32_t parentSiteIndex = node->getInlinedSiteIndex();
1383
1384
if (parentSiteIndex >= 0)
1385
{
1386
TR_InlinedCallSite & site = cfg->comp()->getInlinedCallSite(parentSiteIndex);
1387
int32_t callCount = cfg->comp()->fej9()->getIProfilerCallCount(site._byteCodeInfo, cfg->comp());
1388
1389
if (callCount != 0)
1390
return callCount;
1391
}
1392
}
1393
else
1394
{ // It's a dummy block in estimate code size
1395
// The called frequency is set by estimate code size because at that time
1396
// we don't have the final caller information.
1397
int32_t callCount = cfg->_calledFrequency;
1398
1399
if (callCount != 0)
1400
return callCount;
1401
}
1402
1403
return 0;
1404
}
1405
1406
1407
void
1408
J9::CFG::getInterpreterProfilerBranchCountersOnDoubleton(TR::CFGNode *cfgNode, int32_t *taken, int32_t *nottaken)
1409
{
1410
TR::Node *node = cfgNode->asBlock()->getLastRealTreeTop()->getNode();
1411
1412
if (this != comp()->getFlowGraph())
1413
{
1414
TR::TreeTop *entry = (cfgNode->asBlock()->getNextBlock()) ? cfgNode->asBlock()->getNextBlock()->getEntry() : NULL;
1415
_externalProfiler->getBranchCounters(node, entry, taken, nottaken, comp());
1416
}
1417
else
1418
{
1419
getBranchCounters(node, cfgNode->asBlock(), taken, nottaken, comp());
1420
}
1421
1422
if (*taken || *nottaken)
1423
{
1424
if (comp()->getOption(TR_TraceBFGeneration))
1425
dumpOptDetails(comp(),"If on node %p has branch counts: taken=%d, not taken=%d\n", node, *taken, *nottaken);
1426
}
1427
else if (isVirtualGuard(node))
1428
{
1429
*taken = 0;
1430
*nottaken = AVG_FREQ;
1431
int32_t sumFreq = summarizeFrequencyFromPredecessors(cfgNode, self());
1432
1433
if (sumFreq>0)
1434
*nottaken = sumFreq;
1435
1436
if (comp()->getOption(TR_TraceBFGeneration))
1437
dumpOptDetails(comp(),"Guard on node %p has default branch counts: taken=%d, not taken=%d\n", node, *taken, *nottaken);
1438
}
1439
else if (!cfgNode->asBlock()->isCold())
1440
{
1441
if (node->getBranchDestination()->getNode()->getBlock()->isCold())
1442
*taken = 0;
1443
else
1444
*taken = LOW_FREQ;
1445
1446
if (cfgNode->asBlock()->getNextBlock() &&
1447
cfgNode->asBlock()->getNextBlock()->isCold())
1448
*nottaken = 0;
1449
else
1450
*nottaken = LOW_FREQ;
1451
1452
/*int32_t sumFreq = summarizeFrequencyFromPredecessors(cfgNode, this);
1453
1454
if (sumFreq>0)
1455
{
1456
*nottaken = sumFreq>>1;
1457
*taken = *nottaken;
1458
}
1459
else
1460
{
1461
if (node->getByteCodeIndex()==0)
1462
{
1463
int32_t callCount = getParentCallCount(this, node);
1464
1465
// we don't know what the call count is, assign some
1466
// moderate frequency
1467
if (callCount<=0)
1468
callCount = AVG_FREQ;
1469
1470
*taken = 0;
1471
*nottaken = callCount;
1472
}
1473
}
1474
*/
1475
if (comp()->getOption(TR_TraceBFGeneration))
1476
dumpOptDetails(comp(),"If with no profiling information on node %p has low branch counts: taken=%d, not taken=%d\n", node, *taken, *nottaken);
1477
}
1478
}
1479
1480
1481
TR::CFGEdge * getCFGEdgeForNode(TR::CFGNode *node, TR::Node *child)
1482
{
1483
for (auto e = node->getSuccessors().begin(); e != node->getSuccessors().end(); ++e)
1484
{
1485
if ((*e)->getTo()->asBlock() == child->getBranchDestination()->getNode()->getBlock())
1486
return *e;
1487
}
1488
1489
return NULL;
1490
}
1491
1492
1493
void
1494
J9::CFG::setSwitchEdgeFrequenciesOnNode(TR::CFGNode *node, TR::Compilation *comp)
1495
{
1496
TR::Block *block = node->asBlock();
1497
TR::Node *treeNode = node->asBlock()->getLastRealTreeTop()->getNode();
1498
int32_t sumFrequency = _externalProfiler->getSumSwitchCount(treeNode, comp);
1499
1500
if (sumFrequency < 10)
1501
{
1502
if (comp->getOption(TR_TraceBFGeneration))
1503
dumpOptDetails(comp,"Low count switch I'll set frequencies using uniform edge distribution\n");
1504
1505
self()->setUniformEdgeFrequenciesOnNode (node, sumFrequency, false, comp);
1506
return;
1507
}
1508
1509
if (treeNode->getInlinedSiteIndex() < -1)
1510
{
1511
if (comp->getOption(TR_TraceBFGeneration))
1512
dumpOptDetails(comp,"Dummy switch generated in estimate code size I'll set frequencies using uniform edge distribution\n");
1513
1514
self()->setUniformEdgeFrequenciesOnNode (node, sumFrequency, false, comp);
1515
return;
1516
}
1517
1518
if (_externalProfiler->isSwitchProfileFlat(treeNode, comp))
1519
{
1520
if (comp->getOption(TR_TraceBFGeneration))
1521
dumpOptDetails(comp,"Flat profile switch, setting average frequency on each case.\n");
1522
1523
self()->setUniformEdgeFrequenciesOnNode(node, _externalProfiler->getFlatSwitchProfileCounts(treeNode, comp), false, comp);
1524
return;
1525
}
1526
1527
for ( int32_t count=1; count < treeNode->getNumChildren(); count++)
1528
{
1529
TR::Node *child = treeNode->getChild(count);
1530
TR::CFGEdge *e = getCFGEdgeForNode(node, child);
1531
1532
int32_t frequency = _externalProfiler->getSwitchCountForValue (treeNode, (count-1), comp);
1533
e->setFrequency( std::max(frequency,1) );
1534
if (comp->getOption(TR_TraceBFGeneration))
1535
dumpOptDetails(comp,"Edge %p between %d and %d has freq %d (Switch)\n", e, e->getFrom()->getNumber(), e->getTo()->getNumber(), e->getFrequency());
1536
}
1537
}
1538
1539
1540
void
1541
J9::CFG::setBlockFrequency(TR::CFGNode *node, int32_t frequency, bool addFrequency)
1542
{
1543
TR::Block *block = node->asBlock();
1544
if (!block)
1545
return;
1546
1547
if (block->isCold())
1548
{
1549
if (comp()->getOption(TR_TraceBFGeneration))
1550
{
1551
traceMsg(
1552
comp(),
1553
"Leaving cold reason %d on block_%d\n",
1554
block->getFrequency(),
1555
block->getNumber());
1556
}
1557
return;
1558
}
1559
1560
if (comp()->getOption(TR_TraceBFGeneration))
1561
traceMsg(comp(), "Original freq %d on block_%d incoming freq %d\n", block->getFrequency(), block->getNumber(), frequency);
1562
1563
if (_frequencySet)
1564
{
1565
if (!_frequencySet->get(block->getNumber()))
1566
{
1567
_frequencySet->set(block->getNumber());
1568
if (comp()->getOption(TR_TraceBFGeneration))
1569
traceMsg(comp(), "00 Setting freq %d on block_%d added freq %d\n", block->getFrequency(), block->getNumber(), 0);
1570
block->setFrequency(0);
1571
}
1572
}
1573
1574
if ((block->getFrequency() < 0) || block->isCatchBlock())
1575
addFrequency = false;
1576
1577
if (addFrequency)
1578
{
1579
int32_t addedFrequency = block->getFrequency() + frequency;
1580
//if (addedFrequency > _maxFrequency)
1581
// _maxFrequency = addedFrequency;
1582
1583
block->setFrequency(addedFrequency);
1584
if (comp()->getOption(TR_TraceBFGeneration))
1585
traceMsg(comp(), "11 Setting freq %d on block_%d added freq %d\n", block->getFrequency(), block->getNumber(), addedFrequency);
1586
}
1587
else
1588
{
1589
//if (frequency > _maxFrequency)
1590
// _maxFrequency = frequency;
1591
1592
block->setFrequency(frequency);
1593
if (comp()->getOption(TR_TraceBFGeneration))
1594
traceMsg(comp(), "22 Setting freq %d on block_%d\n", block->getFrequency(), block->getNumber());
1595
}
1596
return;
1597
}
1598
1599
1600
// We currently don't handle well straight line methods without branches
1601
// when using interpreter profiler. If there are no branches or calls
1602
// we don't have a frequency to set. The function below tries to find any
1603
// possible interpreter profiling information to continue on.
1604
int32_t
1605
J9::CFG::scanForFrequencyOnSimpleMethod(TR::TreeTop *tt, TR::TreeTop *endTT)
1606
{
1607
if (comp()->getOption(TR_TraceBFGeneration))
1608
traceMsg(comp(), "Starting method scan...\n");
1609
for (; tt && tt!=endTT; tt = tt->getNextTreeTop())
1610
{
1611
if (!tt->getNode()) continue;
1612
1613
TR::Node *node = tt->getNode();
1614
1615
if (node->getOpCode().isTreeTop() && node->getNumChildren()>0 && node->getFirstChild()->getOpCode().isCall())
1616
node = node->getFirstChild();
1617
1618
if (comp()->getOption(TR_TraceBFGeneration))
1619
traceMsg(comp(), "Scanning node %p, isBranch = %d, isCall = %d, isVirtualCall =%d\n",
1620
node, node->getOpCode().isBranch(),
1621
node->getOpCode().isCall(), node->getOpCode().isCallIndirect());
1622
1623
if (node->getOpCode().isBranch()) return -1;
1624
1625
if (node->getOpCode().isCallIndirect())
1626
{
1627
int32_t newFrequency = comp()->fej9()->getIProfilerCallCount(node->getByteCodeInfo(), comp());
1628
1629
if (newFrequency >0)
1630
{
1631
if (comp()->getOption(TR_TraceBFGeneration))
1632
traceMsg(comp(), "Method scan found frequency %d\n", newFrequency);
1633
return newFrequency;
1634
}
1635
}
1636
}
1637
1638
return -1;
1639
}
1640
1641
1642
void
1643
J9::CFG::getBranchCountersFromProfilingData(TR::Node *node, TR::Block *block, int32_t *taken, int32_t *notTaken)
1644
{
1645
TR::Compilation *comp = self()->comp();
1646
TR::Block *branchToBlock = node->getBranchDestination()->getNode()->getBlock();
1647
TR::Block *fallThroughBlock = block->getNextBlock();
1648
1649
if (self() != comp->getFlowGraph())
1650
_externalProfiler->getBranchCounters(node, fallThroughBlock->getEntry(), taken, notTaken, comp);
1651
else
1652
{
1653
TR_BranchProfileInfoManager * branchManager = TR_BranchProfileInfoManager::get(comp);
1654
branchManager->getBranchCounters(node, fallThroughBlock->getEntry(), taken, notTaken, comp);
1655
1656
bool Confirmation = comp->getOption(TR_EnableScorchInterpBlockFrequencyProfiling);
1657
1658
if (Confirmation && ((comp->hasBlockFrequencyInfo() && (self() == comp->getFlowGraph())) /*|| hasJProfilingInfo(comp, self())*/))
1659
{
1660
TR_PersistentProfileInfo *profileInfo = getProfilingInfoForCFG(comp, self());
1661
if (profileInfo)
1662
{
1663
TR_BlockFrequencyInfo *blockFrequencyInfo = profileInfo->getBlockFrequencyInfo();
1664
// This check ensures that the JIT profiling block frequency can be properly correlated to interpreter profiling edge frequency
1665
// This can be only done when no other edge may come in to a block and unnaturally inflate one of the block's counts.
1666
//
1667
if((fallThroughBlock->getPredecessors().size() == 1) && (branchToBlock->getPredecessors().size() == 1))
1668
{
1669
int32_t currentBlockFreq = blockFrequencyInfo->getFrequencyInfo(block, comp);
1670
int32_t fallthruBlockFreq = blockFrequencyInfo->getFrequencyInfo(fallThroughBlock, comp);
1671
int32_t branchBlockFreq = blockFrequencyInfo->getFrequencyInfo(branchToBlock, comp);
1672
1673
if(currentBlockFreq > 0 && fallthruBlockFreq > 0 && branchBlockFreq > 0)
1674
{
1675
if( (*taken > *notTaken && fallthruBlockFreq > branchBlockFreq ) || (*notTaken > *taken && branchBlockFreq > fallthruBlockFreq) )
1676
{
1677
if (comp->getOption(TR_TraceBFGeneration))
1678
traceMsg(comp, "For block %d fallthru block %d and branch block %d iprofiler says taken = %d notTaken = %d jitprofiler says currentBlockfreq = %d "
1679
"taken = %d notTaken = %d. Scaling iprofiler info.\n",block->getNumber(),fallThroughBlock->getNumber(),branchToBlock->getNumber(),*taken,*notTaken,
1680
currentBlockFreq,branchBlockFreq,fallthruBlockFreq);
1681
*taken = ((*taken) * fallthruBlockFreq ) / (fallthruBlockFreq + branchBlockFreq) ;
1682
*notTaken = ((*notTaken) * branchBlockFreq) / (fallthruBlockFreq + branchBlockFreq) ;
1683
if (comp->getOption(TR_TraceBFGeneration))
1684
traceMsg(comp,"New taken = %d notTaken = %d\n",*taken,*notTaken);
1685
1686
}
1687
}
1688
}
1689
}
1690
}
1691
}
1692
1693
}
1694
1695
// OMR TODO:
1696
// This only seems necessary to NULL out the _externalProfiler field.
1697
// Consider eliminating this project specialization altogether.
1698
//
1699
void
1700
J9::CFG::setBlockAndEdgeFrequenciesBasedOnStructure()
1701
{
1702
self()->propagateFrequencyInfoFromExternalProfiler(NULL);
1703
}
1704
1705
1706
void
1707
J9::CFG::propagateFrequencyInfoFromExternalProfiler(TR_ExternalProfiler *profiler)
1708
{
1709
_externalProfiler = profiler;
1710
1711
if (profiler)
1712
{
1713
self()->setBlockFrequenciesBasedOnInterpreterProfiler();
1714
return;
1715
}
1716
1717
// Call super class
1718
//
1719
OMR::CFGConnector::setBlockAndEdgeFrequenciesBasedOnStructure();
1720
}
1721
1722
1723
bool
1724
J9::CFG::emitVerbosePseudoRandomFrequencies()
1725
{
1726
TR::CFGNode *nextNode = getFirstNode();
1727
int32_t count = 1;
1728
int32_t edgeIndex = 0;
1729
comp()->fej9()->emitNewPseudoRandomNumberVerbosePrefix();
1730
for (; nextNode != NULL; nextNode = nextNode->getNext())
1731
{
1732
comp()->fej9()->emitNewPseudoRandomNumberVerbose(nextNode->getFrequency());
1733
TR_SuccessorIterator sit(nextNode);
1734
for (TR::CFGEdge * nextEdge = sit.getFirst(); nextEdge != NULL; nextEdge = sit.getNext())
1735
{
1736
comp()->fej9()->emitNewPseudoRandomNumberVerbose(nextEdge->getFrequency());
1737
if (((count++) % 50) == 0)
1738
{
1739
comp()->fej9()->emitNewPseudoRandomVerboseSuffix();
1740
comp()->fej9()->emitNewPseudoRandomNumberVerbosePrefix();
1741
}
1742
1743
edgeIndex++;
1744
}
1745
1746
if (((count++) % 50) == 0)
1747
{
1748
comp()->fej9()->emitNewPseudoRandomVerboseSuffix();
1749
comp()->fej9()->emitNewPseudoRandomNumberVerbosePrefix();
1750
}
1751
}
1752
1753
_numEdges = edgeIndex;
1754
1755
comp()->fej9()->emitNewPseudoRandomNumberVerbose(getMaxFrequency());
1756
1757
if (((count++) % 50) == 0)
1758
{
1759
comp()->fej9()->emitNewPseudoRandomVerboseSuffix();
1760
comp()->fej9()->emitNewPseudoRandomNumberVerbosePrefix();
1761
}
1762
1763
comp()->fej9()->emitNewPseudoRandomVerboseSuffix();
1764
return true;
1765
}
1766
1767