xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp (revision 6c4b055cfb6bf549e9145dde6454cc6b178c35e4)
10b57cec5SDimitry Andric //===- PGOInstrumentation.cpp - MST-based PGO Instrumentation -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements PGO instrumentation using a minimum spanning tree based
100b57cec5SDimitry Andric // on the following paper:
110b57cec5SDimitry Andric //   [1] Donald E. Knuth, Francis R. Stevenson. Optimal measurement of points
120b57cec5SDimitry Andric //   for program frequency counts. BIT Numerical Mathematics 1973, Volume 13,
130b57cec5SDimitry Andric //   Issue 3, pp 313-322
140b57cec5SDimitry Andric // The idea of the algorithm based on the fact that for each node (except for
150b57cec5SDimitry Andric // the entry and exit), the sum of incoming edge counts equals the sum of
160b57cec5SDimitry Andric // outgoing edge counts. The count of edge on spanning tree can be derived from
170b57cec5SDimitry Andric // those edges not on the spanning tree. Knuth proves this method instruments
180b57cec5SDimitry Andric // the minimum number of edges.
190b57cec5SDimitry Andric //
200b57cec5SDimitry Andric // The minimal spanning tree here is actually a maximum weight tree -- on-tree
210b57cec5SDimitry Andric // edges have higher frequencies (more likely to execute). The idea is to
220b57cec5SDimitry Andric // instrument those less frequently executed edges to reduce the runtime
230b57cec5SDimitry Andric // overhead of instrumented binaries.
240b57cec5SDimitry Andric //
250b57cec5SDimitry Andric // This file contains two passes:
260b57cec5SDimitry Andric // (1) Pass PGOInstrumentationGen which instruments the IR to generate edge
270b57cec5SDimitry Andric // count profile, and generates the instrumentation for indirect call
280b57cec5SDimitry Andric // profiling.
290b57cec5SDimitry Andric // (2) Pass PGOInstrumentationUse which reads the edge count profile and
300b57cec5SDimitry Andric // annotates the branch weights. It also reads the indirect call value
310b57cec5SDimitry Andric // profiling records and annotate the indirect call instructions.
320b57cec5SDimitry Andric //
330b57cec5SDimitry Andric // To get the precise counter information, These two passes need to invoke at
340b57cec5SDimitry Andric // the same compilation point (so they see the same IR). For pass
350b57cec5SDimitry Andric // PGOInstrumentationGen, the real work is done in instrumentOneFunc(). For
360b57cec5SDimitry Andric // pass PGOInstrumentationUse, the real work in done in class PGOUseFunc and
370b57cec5SDimitry Andric // the profile is opened in module level and passed to each PGOUseFunc instance.
380b57cec5SDimitry Andric // The shared code for PGOInstrumentationGen and PGOInstrumentationUse is put
390b57cec5SDimitry Andric // in class FuncPGOInstrumentation.
400b57cec5SDimitry Andric //
410b57cec5SDimitry Andric // Class PGOEdge represents a CFG edge and some auxiliary information. Class
420b57cec5SDimitry Andric // BBInfo contains auxiliary information for each BB. These two classes are used
430b57cec5SDimitry Andric // in pass PGOInstrumentationGen. Class PGOUseEdge and UseBBInfo are the derived
440b57cec5SDimitry Andric // class of PGOEdge and BBInfo, respectively. They contains extra data structure
450b57cec5SDimitry Andric // used in populating profile counters.
460b57cec5SDimitry Andric // The MST implementation is in Class CFGMST (CFGMST.h).
470b57cec5SDimitry Andric //
480b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
490b57cec5SDimitry Andric 
50480093f4SDimitry Andric #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"
518bcb0991SDimitry Andric #include "ValueProfileCollector.h"
520b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
530b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
540b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
550b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
560b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
570b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
580b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
590b57cec5SDimitry Andric #include "llvm/ADT/iterator.h"
600b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
610b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h"
620b57cec5SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h"
630b57cec5SDimitry Andric #include "llvm/Analysis/CFG.h"
640b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
650b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
660b57cec5SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
6781ad6265SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
680b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
690b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
700b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
710b57cec5SDimitry Andric #include "llvm/IR/Comdat.h"
720b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
730b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
740b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
750b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
7606c3fb27SDimitry Andric #include "llvm/IR/EHPersonalities.h"
770b57cec5SDimitry Andric #include "llvm/IR/Function.h"
780b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h"
790b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
800b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
810b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h"
820b57cec5SDimitry Andric #include "llvm/IR/InstVisitor.h"
830b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
840b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
850b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
860b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
870b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
880b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
890b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
900b57cec5SDimitry Andric #include "llvm/IR/Module.h"
910b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
92bdd1243dSDimitry Andric #include "llvm/IR/ProfDataUtils.h"
930b57cec5SDimitry Andric #include "llvm/IR/ProfileSummary.h"
940b57cec5SDimitry Andric #include "llvm/IR/Type.h"
950b57cec5SDimitry Andric #include "llvm/IR/Value.h"
960b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h"
970b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProfReader.h"
980b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h"
998bcb0991SDimitry Andric #include "llvm/Support/CRC.h"
1000b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
1010b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
1020b57cec5SDimitry Andric #include "llvm/Support/DOTGraphTraits.h"
1030b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
1040b57cec5SDimitry Andric #include "llvm/Support/Error.h"
1050b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
1060b57cec5SDimitry Andric #include "llvm/Support/GraphWriter.h"
10706c3fb27SDimitry Andric #include "llvm/Support/VirtualFileSystem.h"
1080b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
10906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
1100b57cec5SDimitry Andric #include "llvm/Transforms/Instrumentation.h"
11106c3fb27SDimitry Andric #include "llvm/Transforms/Instrumentation/BlockCoverageInference.h"
11206c3fb27SDimitry Andric #include "llvm/Transforms/Instrumentation/CFGMST.h"
1130fca6ea1SDimitry Andric #include "llvm/Transforms/Instrumentation/PGOCtxProfLowering.h"
1140b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
11581ad6265SDimitry Andric #include "llvm/Transforms/Utils/MisExpect.h"
116349cc55cSDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h"
1170b57cec5SDimitry Andric #include <algorithm>
1180b57cec5SDimitry Andric #include <cassert>
1190b57cec5SDimitry Andric #include <cstdint>
1200b57cec5SDimitry Andric #include <memory>
1210b57cec5SDimitry Andric #include <numeric>
122bdd1243dSDimitry Andric #include <optional>
1230fca6ea1SDimitry Andric #include <stack>
1240b57cec5SDimitry Andric #include <string>
1250b57cec5SDimitry Andric #include <unordered_map>
1260b57cec5SDimitry Andric #include <utility>
1270b57cec5SDimitry Andric #include <vector>
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric using namespace llvm;
1300b57cec5SDimitry Andric using ProfileCount = Function::ProfileCount;
1318bcb0991SDimitry Andric using VPCandidateInfo = ValueProfileCollector::CandidateInfo;
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric #define DEBUG_TYPE "pgo-instrumentation"
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric STATISTIC(NumOfPGOInstrument, "Number of edges instrumented.");
1360b57cec5SDimitry Andric STATISTIC(NumOfPGOSelectInsts, "Number of select instruction instrumented.");
1370b57cec5SDimitry Andric STATISTIC(NumOfPGOMemIntrinsics, "Number of mem intrinsics instrumented.");
1380b57cec5SDimitry Andric STATISTIC(NumOfPGOEdge, "Number of edges.");
1390b57cec5SDimitry Andric STATISTIC(NumOfPGOBB, "Number of basic-blocks.");
1400b57cec5SDimitry Andric STATISTIC(NumOfPGOSplit, "Number of critical edge splits.");
1410b57cec5SDimitry Andric STATISTIC(NumOfPGOFunc, "Number of functions having valid profile counts.");
1420b57cec5SDimitry Andric STATISTIC(NumOfPGOMismatch, "Number of functions having mismatch profile.");
1430b57cec5SDimitry Andric STATISTIC(NumOfPGOMissing, "Number of functions without profile.");
1440b57cec5SDimitry Andric STATISTIC(NumOfPGOICall, "Number of indirect call value instrumentations.");
1450b57cec5SDimitry Andric STATISTIC(NumOfCSPGOInstrument, "Number of edges instrumented in CSPGO.");
1460b57cec5SDimitry Andric STATISTIC(NumOfCSPGOSelectInsts,
1470b57cec5SDimitry Andric           "Number of select instruction instrumented in CSPGO.");
1480b57cec5SDimitry Andric STATISTIC(NumOfCSPGOMemIntrinsics,
1490b57cec5SDimitry Andric           "Number of mem intrinsics instrumented in CSPGO.");
1500b57cec5SDimitry Andric STATISTIC(NumOfCSPGOEdge, "Number of edges in CSPGO.");
1510b57cec5SDimitry Andric STATISTIC(NumOfCSPGOBB, "Number of basic-blocks in CSPGO.");
1520b57cec5SDimitry Andric STATISTIC(NumOfCSPGOSplit, "Number of critical edge splits in CSPGO.");
1530b57cec5SDimitry Andric STATISTIC(NumOfCSPGOFunc,
1540b57cec5SDimitry Andric           "Number of functions having valid profile counts in CSPGO.");
1550b57cec5SDimitry Andric STATISTIC(NumOfCSPGOMismatch,
1560b57cec5SDimitry Andric           "Number of functions having mismatch profile in CSPGO.");
1570b57cec5SDimitry Andric STATISTIC(NumOfCSPGOMissing, "Number of functions without profile in CSPGO.");
15806c3fb27SDimitry Andric STATISTIC(NumCoveredBlocks, "Number of basic blocks that were executed");
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric // Command line option to specify the file to read profile from. This is
1610b57cec5SDimitry Andric // mainly used for testing.
1620b57cec5SDimitry Andric static cl::opt<std::string>
1630b57cec5SDimitry Andric     PGOTestProfileFile("pgo-test-profile-file", cl::init(""), cl::Hidden,
1640b57cec5SDimitry Andric                        cl::value_desc("filename"),
1650b57cec5SDimitry Andric                        cl::desc("Specify the path of profile data file. This is"
1660b57cec5SDimitry Andric                                 "mainly for test purpose."));
1670b57cec5SDimitry Andric static cl::opt<std::string> PGOTestProfileRemappingFile(
1680b57cec5SDimitry Andric     "pgo-test-profile-remapping-file", cl::init(""), cl::Hidden,
1690b57cec5SDimitry Andric     cl::value_desc("filename"),
1700b57cec5SDimitry Andric     cl::desc("Specify the path of profile remapping file. This is mainly for "
1710b57cec5SDimitry Andric              "test purpose."));
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric // Command line option to disable value profiling. The default is false:
1740b57cec5SDimitry Andric // i.e. value profiling is enabled by default. This is for debug purpose.
1750b57cec5SDimitry Andric static cl::opt<bool> DisableValueProfiling("disable-vp", cl::init(false),
1760b57cec5SDimitry Andric                                            cl::Hidden,
1770b57cec5SDimitry Andric                                            cl::desc("Disable Value Profiling"));
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric // Command line option to set the maximum number of VP annotations to write to
1800b57cec5SDimitry Andric // the metadata for a single indirect call callsite.
1810b57cec5SDimitry Andric static cl::opt<unsigned> MaxNumAnnotations(
18281ad6265SDimitry Andric     "icp-max-annotations", cl::init(3), cl::Hidden,
1830b57cec5SDimitry Andric     cl::desc("Max number of annotations for a single indirect "
1840b57cec5SDimitry Andric              "call callsite"));
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric // Command line option to set the maximum number of value annotations
1870b57cec5SDimitry Andric // to write to the metadata for a single memop intrinsic.
1880b57cec5SDimitry Andric static cl::opt<unsigned> MaxNumMemOPAnnotations(
18981ad6265SDimitry Andric     "memop-max-annotations", cl::init(4), cl::Hidden,
1900b57cec5SDimitry Andric     cl::desc("Max number of preicise value annotations for a single memop"
1910b57cec5SDimitry Andric              "intrinsic"));
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric // Command line option to control appending FunctionHash to the name of a COMDAT
1940b57cec5SDimitry Andric // function. This is to avoid the hash mismatch caused by the preinliner.
1950b57cec5SDimitry Andric static cl::opt<bool> DoComdatRenaming(
1960b57cec5SDimitry Andric     "do-comdat-renaming", cl::init(false), cl::Hidden,
1970b57cec5SDimitry Andric     cl::desc("Append function hash to the name of COMDAT function to avoid "
1980b57cec5SDimitry Andric              "function hash mismatch due to the preinliner"));
1990b57cec5SDimitry Andric 
20006c3fb27SDimitry Andric namespace llvm {
2010b57cec5SDimitry Andric // Command line option to enable/disable the warning about missing profile
2020b57cec5SDimitry Andric // information.
20306c3fb27SDimitry Andric cl::opt<bool> PGOWarnMissing("pgo-warn-missing-function", cl::init(false),
20406c3fb27SDimitry Andric                              cl::Hidden,
2050b57cec5SDimitry Andric                              cl::desc("Use this option to turn on/off "
2060b57cec5SDimitry Andric                                       "warnings about missing profile data for "
2070b57cec5SDimitry Andric                                       "functions."));
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric // Command line option to enable/disable the warning about a hash mismatch in
2100b57cec5SDimitry Andric // the profile data.
211349cc55cSDimitry Andric cl::opt<bool>
2120b57cec5SDimitry Andric     NoPGOWarnMismatch("no-pgo-warn-mismatch", cl::init(false), cl::Hidden,
2130b57cec5SDimitry Andric                       cl::desc("Use this option to turn off/on "
2140b57cec5SDimitry Andric                                "warnings about profile cfg mismatch."));
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric // Command line option to enable/disable the warning about a hash mismatch in
2170b57cec5SDimitry Andric // the profile data for Comdat functions, which often turns out to be false
2180b57cec5SDimitry Andric // positive due to the pre-instrumentation inline.
21906c3fb27SDimitry Andric cl::opt<bool> NoPGOWarnMismatchComdatWeak(
220fcaf7f86SDimitry Andric     "no-pgo-warn-mismatch-comdat-weak", cl::init(true), cl::Hidden,
2210b57cec5SDimitry Andric     cl::desc("The option is used to turn on/off "
2220b57cec5SDimitry Andric              "warnings about hash mismatch for comdat "
223fcaf7f86SDimitry Andric              "or weak functions."));
22406c3fb27SDimitry Andric } // namespace llvm
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric // Command line option to enable/disable select instruction instrumentation.
2270b57cec5SDimitry Andric static cl::opt<bool>
2280b57cec5SDimitry Andric     PGOInstrSelect("pgo-instr-select", cl::init(true), cl::Hidden,
2290b57cec5SDimitry Andric                    cl::desc("Use this option to turn on/off SELECT "
2300b57cec5SDimitry Andric                             "instruction instrumentation. "));
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric // Command line option to turn on CFG dot or text dump of raw profile counts
2330b57cec5SDimitry Andric static cl::opt<PGOViewCountsType> PGOViewRawCounts(
2340b57cec5SDimitry Andric     "pgo-view-raw-counts", cl::Hidden,
2350b57cec5SDimitry Andric     cl::desc("A boolean option to show CFG dag or text "
2360b57cec5SDimitry Andric              "with raw profile counts from "
2370b57cec5SDimitry Andric              "profile data. See also option "
2380b57cec5SDimitry Andric              "-pgo-view-counts. To limit graph "
2390b57cec5SDimitry Andric              "display to only one function, use "
2400b57cec5SDimitry Andric              "filtering option -view-bfi-func-name."),
2410b57cec5SDimitry Andric     cl::values(clEnumValN(PGOVCT_None, "none", "do not show."),
2420b57cec5SDimitry Andric                clEnumValN(PGOVCT_Graph, "graph", "show a graph."),
2430b57cec5SDimitry Andric                clEnumValN(PGOVCT_Text, "text", "show in text.")));
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric // Command line option to enable/disable memop intrinsic call.size profiling.
2460b57cec5SDimitry Andric static cl::opt<bool>
2470b57cec5SDimitry Andric     PGOInstrMemOP("pgo-instr-memop", cl::init(true), cl::Hidden,
2480b57cec5SDimitry Andric                   cl::desc("Use this option to turn on/off "
2490b57cec5SDimitry Andric                            "memory intrinsic size profiling."));
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric // Emit branch probability as optimization remarks.
2520b57cec5SDimitry Andric static cl::opt<bool>
2530b57cec5SDimitry Andric     EmitBranchProbability("pgo-emit-branch-prob", cl::init(false), cl::Hidden,
2540b57cec5SDimitry Andric                           cl::desc("When this option is on, the annotated "
2550b57cec5SDimitry Andric                                    "branch probability will be emitted as "
2560b57cec5SDimitry Andric                                    "optimization remarks: -{Rpass|"
2570b57cec5SDimitry Andric                                    "pass-remarks}=pgo-instrumentation"));
2580b57cec5SDimitry Andric 
259e8d8bef9SDimitry Andric static cl::opt<bool> PGOInstrumentEntry(
260e8d8bef9SDimitry Andric     "pgo-instrument-entry", cl::init(false), cl::Hidden,
261e8d8bef9SDimitry Andric     cl::desc("Force to instrument function entry basicblock."));
262e8d8bef9SDimitry Andric 
2631fd87a68SDimitry Andric static cl::opt<bool> PGOFunctionEntryCoverage(
26481ad6265SDimitry Andric     "pgo-function-entry-coverage", cl::Hidden,
2651fd87a68SDimitry Andric     cl::desc(
2661fd87a68SDimitry Andric         "Use this option to enable function entry coverage instrumentation."));
2671fd87a68SDimitry Andric 
26806c3fb27SDimitry Andric static cl::opt<bool> PGOBlockCoverage(
26906c3fb27SDimitry Andric     "pgo-block-coverage",
27006c3fb27SDimitry Andric     cl::desc("Use this option to enable basic block coverage instrumentation"));
27106c3fb27SDimitry Andric 
27206c3fb27SDimitry Andric static cl::opt<bool>
27306c3fb27SDimitry Andric     PGOViewBlockCoverageGraph("pgo-view-block-coverage-graph",
27406c3fb27SDimitry Andric                               cl::desc("Create a dot file of CFGs with block "
27506c3fb27SDimitry Andric                                        "coverage inference information"));
27606c3fb27SDimitry Andric 
27706c3fb27SDimitry Andric static cl::opt<bool> PGOTemporalInstrumentation(
27806c3fb27SDimitry Andric     "pgo-temporal-instrumentation",
27906c3fb27SDimitry Andric     cl::desc("Use this option to enable temporal instrumentation"));
28006c3fb27SDimitry Andric 
281e8d8bef9SDimitry Andric static cl::opt<bool>
282e8d8bef9SDimitry Andric     PGOFixEntryCount("pgo-fix-entry-count", cl::init(true), cl::Hidden,
283e8d8bef9SDimitry Andric                      cl::desc("Fix function entry count in profile use."));
284e8d8bef9SDimitry Andric 
285e8d8bef9SDimitry Andric static cl::opt<bool> PGOVerifyHotBFI(
286e8d8bef9SDimitry Andric     "pgo-verify-hot-bfi", cl::init(false), cl::Hidden,
287e8d8bef9SDimitry Andric     cl::desc("Print out the non-match BFI count if a hot raw profile count "
288e8d8bef9SDimitry Andric              "becomes non-hot, or a cold raw profile count becomes hot. "
289e8d8bef9SDimitry Andric              "The print is enabled under -Rpass-analysis=pgo, or "
290e8d8bef9SDimitry Andric              "internal option -pass-remakrs-analysis=pgo."));
291e8d8bef9SDimitry Andric 
292e8d8bef9SDimitry Andric static cl::opt<bool> PGOVerifyBFI(
293e8d8bef9SDimitry Andric     "pgo-verify-bfi", cl::init(false), cl::Hidden,
294e8d8bef9SDimitry Andric     cl::desc("Print out mismatched BFI counts after setting profile metadata "
295e8d8bef9SDimitry Andric              "The print is enabled under -Rpass-analysis=pgo, or "
296e8d8bef9SDimitry Andric              "internal option -pass-remakrs-analysis=pgo."));
297e8d8bef9SDimitry Andric 
298e8d8bef9SDimitry Andric static cl::opt<unsigned> PGOVerifyBFIRatio(
2990eae32dcSDimitry Andric     "pgo-verify-bfi-ratio", cl::init(2), cl::Hidden,
3000eae32dcSDimitry Andric     cl::desc("Set the threshold for pgo-verify-bfi:  only print out "
301e8d8bef9SDimitry Andric              "mismatched BFI if the difference percentage is greater than "
302e8d8bef9SDimitry Andric              "this value (in percentage)."));
303e8d8bef9SDimitry Andric 
304e8d8bef9SDimitry Andric static cl::opt<unsigned> PGOVerifyBFICutoff(
3050eae32dcSDimitry Andric     "pgo-verify-bfi-cutoff", cl::init(5), cl::Hidden,
3060eae32dcSDimitry Andric     cl::desc("Set the threshold for pgo-verify-bfi: skip the counts whose "
307e8d8bef9SDimitry Andric              "profile count value is below."));
308e8d8bef9SDimitry Andric 
309fcaf7f86SDimitry Andric static cl::opt<std::string> PGOTraceFuncHash(
310fcaf7f86SDimitry Andric     "pgo-trace-func-hash", cl::init("-"), cl::Hidden,
311fcaf7f86SDimitry Andric     cl::value_desc("function name"),
312fcaf7f86SDimitry Andric     cl::desc("Trace the hash of the function with this name."));
313fcaf7f86SDimitry Andric 
314bdd1243dSDimitry Andric static cl::opt<unsigned> PGOFunctionSizeThreshold(
315bdd1243dSDimitry Andric     "pgo-function-size-threshold", cl::Hidden,
316bdd1243dSDimitry Andric     cl::desc("Do not instrument functions smaller than this threshold."));
317bdd1243dSDimitry Andric 
318bdd1243dSDimitry Andric static cl::opt<unsigned> PGOFunctionCriticalEdgeThreshold(
319bdd1243dSDimitry Andric     "pgo-critical-edge-threshold", cl::init(20000), cl::Hidden,
320bdd1243dSDimitry Andric     cl::desc("Do not instrument functions with the number of critical edges "
321bdd1243dSDimitry Andric              " greater than this threshold."));
322bdd1243dSDimitry Andric 
3230fca6ea1SDimitry Andric extern cl::opt<unsigned> MaxNumVTableAnnotations;
3240fca6ea1SDimitry Andric 
325fe6060f1SDimitry Andric namespace llvm {
3260b57cec5SDimitry Andric // Command line option to turn on CFG dot dump after profile annotation.
3270b57cec5SDimitry Andric // Defined in Analysis/BlockFrequencyInfo.cpp:  -pgo-view-counts
3280b57cec5SDimitry Andric extern cl::opt<PGOViewCountsType> PGOViewCounts;
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric // Command line option to specify the name of the function for CFG dump
3310b57cec5SDimitry Andric // Defined in Analysis/BlockFrequencyInfo.cpp:  -view-bfi-func-name=
3320b57cec5SDimitry Andric extern cl::opt<std::string> ViewBlockFreqFuncName;
3330eae32dcSDimitry Andric 
3340fca6ea1SDimitry Andric // Command line option to enable vtable value profiling. Defined in
3350fca6ea1SDimitry Andric // ProfileData/InstrProf.cpp: -enable-vtable-value-profiling=
3360fca6ea1SDimitry Andric extern cl::opt<bool> EnableVTableValueProfiling;
3370fca6ea1SDimitry Andric extern cl::opt<bool> EnableVTableProfileUse;
3385f757f3fSDimitry Andric extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
339fe6060f1SDimitry Andric } // namespace llvm
3400b57cec5SDimitry Andric 
3410fca6ea1SDimitry Andric bool shouldInstrumentEntryBB() {
3420fca6ea1SDimitry Andric   return PGOInstrumentEntry ||
3430fca6ea1SDimitry Andric          PGOCtxProfLoweringPass::isContextualIRPGOEnabled();
3440fca6ea1SDimitry Andric }
3450fca6ea1SDimitry Andric 
3460fca6ea1SDimitry Andric // FIXME(mtrofin): re-enable this for ctx profiling, for non-indirect calls. Ctx
3470fca6ea1SDimitry Andric // profiling implicitly captures indirect call cases, but not other values.
3480fca6ea1SDimitry Andric // Supporting other values is relatively straight-forward - just another counter
3490fca6ea1SDimitry Andric // range within the context.
3500fca6ea1SDimitry Andric bool isValueProfilingDisabled() {
3510fca6ea1SDimitry Andric   return DisableValueProfiling ||
3520fca6ea1SDimitry Andric          PGOCtxProfLoweringPass::isContextualIRPGOEnabled();
3530fca6ea1SDimitry Andric }
3540fca6ea1SDimitry Andric 
3550b57cec5SDimitry Andric // Return a string describing the branch condition that can be
3560b57cec5SDimitry Andric // used in static branch probability heuristics:
3570b57cec5SDimitry Andric static std::string getBranchCondString(Instruction *TI) {
3580b57cec5SDimitry Andric   BranchInst *BI = dyn_cast<BranchInst>(TI);
3590b57cec5SDimitry Andric   if (!BI || !BI->isConditional())
3600b57cec5SDimitry Andric     return std::string();
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric   Value *Cond = BI->getCondition();
3630b57cec5SDimitry Andric   ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
3640b57cec5SDimitry Andric   if (!CI)
3650b57cec5SDimitry Andric     return std::string();
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   std::string result;
3680b57cec5SDimitry Andric   raw_string_ostream OS(result);
36906c3fb27SDimitry Andric   OS << CI->getPredicate() << "_";
3700b57cec5SDimitry Andric   CI->getOperand(0)->getType()->print(OS, true);
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   Value *RHS = CI->getOperand(1);
3730b57cec5SDimitry Andric   ConstantInt *CV = dyn_cast<ConstantInt>(RHS);
3740b57cec5SDimitry Andric   if (CV) {
3750b57cec5SDimitry Andric     if (CV->isZero())
3760b57cec5SDimitry Andric       OS << "_Zero";
3770b57cec5SDimitry Andric     else if (CV->isOne())
3780b57cec5SDimitry Andric       OS << "_One";
3790b57cec5SDimitry Andric     else if (CV->isMinusOne())
3800b57cec5SDimitry Andric       OS << "_MinusOne";
3810b57cec5SDimitry Andric     else
3820b57cec5SDimitry Andric       OS << "_Const";
3830b57cec5SDimitry Andric   }
3840b57cec5SDimitry Andric   OS.flush();
3850b57cec5SDimitry Andric   return result;
3860b57cec5SDimitry Andric }
3870b57cec5SDimitry Andric 
3888bcb0991SDimitry Andric static const char *ValueProfKindDescr[] = {
3898bcb0991SDimitry Andric #define VALUE_PROF_KIND(Enumerator, Value, Descr) Descr,
3908bcb0991SDimitry Andric #include "llvm/ProfileData/InstrProfData.inc"
3918bcb0991SDimitry Andric };
3928bcb0991SDimitry Andric 
3931fd87a68SDimitry Andric // Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
3941fd87a68SDimitry Andric // aware this is an ir_level profile so it can set the version flag.
3951fd87a68SDimitry Andric static GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS) {
3961fd87a68SDimitry Andric   const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
3971fd87a68SDimitry Andric   Type *IntTy64 = Type::getInt64Ty(M.getContext());
3981fd87a68SDimitry Andric   uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
3991fd87a68SDimitry Andric   if (IsCS)
4001fd87a68SDimitry Andric     ProfileVersion |= VARIANT_MASK_CSIR_PROF;
4010fca6ea1SDimitry Andric   if (shouldInstrumentEntryBB())
4021fd87a68SDimitry Andric     ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
4035f757f3fSDimitry Andric   if (DebugInfoCorrelate || ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO)
4041fd87a68SDimitry Andric     ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
4051fd87a68SDimitry Andric   if (PGOFunctionEntryCoverage)
4061fd87a68SDimitry Andric     ProfileVersion |=
4071fd87a68SDimitry Andric         VARIANT_MASK_BYTE_COVERAGE | VARIANT_MASK_FUNCTION_ENTRY_ONLY;
40806c3fb27SDimitry Andric   if (PGOBlockCoverage)
40906c3fb27SDimitry Andric     ProfileVersion |= VARIANT_MASK_BYTE_COVERAGE;
41006c3fb27SDimitry Andric   if (PGOTemporalInstrumentation)
41106c3fb27SDimitry Andric     ProfileVersion |= VARIANT_MASK_TEMPORAL_PROF;
4121fd87a68SDimitry Andric   auto IRLevelVersionVariable = new GlobalVariable(
4131fd87a68SDimitry Andric       M, IntTy64, true, GlobalValue::WeakAnyLinkage,
4141fd87a68SDimitry Andric       Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName);
415bdd1243dSDimitry Andric   IRLevelVersionVariable->setVisibility(GlobalValue::HiddenVisibility);
4161fd87a68SDimitry Andric   Triple TT(M.getTargetTriple());
4171fd87a68SDimitry Andric   if (TT.supportsCOMDAT()) {
4181fd87a68SDimitry Andric     IRLevelVersionVariable->setLinkage(GlobalValue::ExternalLinkage);
4191fd87a68SDimitry Andric     IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
4201fd87a68SDimitry Andric   }
4211fd87a68SDimitry Andric   return IRLevelVersionVariable;
4221fd87a68SDimitry Andric }
4231fd87a68SDimitry Andric 
4240b57cec5SDimitry Andric namespace {
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric /// The select instruction visitor plays three roles specified
4270b57cec5SDimitry Andric /// by the mode. In \c VM_counting mode, it simply counts the number of
4280b57cec5SDimitry Andric /// select instructions. In \c VM_instrument mode, it inserts code to count
4290b57cec5SDimitry Andric /// the number times TrueValue of select is taken. In \c VM_annotate mode,
4300b57cec5SDimitry Andric /// it reads the profile data and annotate the select instruction with metadata.
4310b57cec5SDimitry Andric enum VisitMode { VM_counting, VM_instrument, VM_annotate };
4320b57cec5SDimitry Andric class PGOUseFunc;
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric /// Instruction Visitor class to visit select instructions.
4350b57cec5SDimitry Andric struct SelectInstVisitor : public InstVisitor<SelectInstVisitor> {
4360b57cec5SDimitry Andric   Function &F;
4370b57cec5SDimitry Andric   unsigned NSIs = 0;             // Number of select instructions instrumented.
4380b57cec5SDimitry Andric   VisitMode Mode = VM_counting;  // Visiting mode.
4390b57cec5SDimitry Andric   unsigned *CurCtrIdx = nullptr; // Pointer to current counter index.
4400b57cec5SDimitry Andric   unsigned TotalNumCtrs = 0;     // Total number of counters
4410b57cec5SDimitry Andric   GlobalVariable *FuncNameVar = nullptr;
4420b57cec5SDimitry Andric   uint64_t FuncHash = 0;
4430b57cec5SDimitry Andric   PGOUseFunc *UseFunc = nullptr;
44406c3fb27SDimitry Andric   bool HasSingleByteCoverage;
4450b57cec5SDimitry Andric 
44606c3fb27SDimitry Andric   SelectInstVisitor(Function &Func, bool HasSingleByteCoverage)
44706c3fb27SDimitry Andric       : F(Func), HasSingleByteCoverage(HasSingleByteCoverage) {}
4480b57cec5SDimitry Andric 
44906c3fb27SDimitry Andric   void countSelects() {
4500b57cec5SDimitry Andric     NSIs = 0;
4510b57cec5SDimitry Andric     Mode = VM_counting;
45206c3fb27SDimitry Andric     visit(F);
4530b57cec5SDimitry Andric   }
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   // Visit the IR stream and instrument all select instructions. \p
4560b57cec5SDimitry Andric   // Ind is a pointer to the counter index variable; \p TotalNC
4570b57cec5SDimitry Andric   // is the total number of counters; \p FNV is the pointer to the
4580b57cec5SDimitry Andric   // PGO function name var; \p FHash is the function hash.
45906c3fb27SDimitry Andric   void instrumentSelects(unsigned *Ind, unsigned TotalNC, GlobalVariable *FNV,
46006c3fb27SDimitry Andric                          uint64_t FHash) {
4610b57cec5SDimitry Andric     Mode = VM_instrument;
4620b57cec5SDimitry Andric     CurCtrIdx = Ind;
4630b57cec5SDimitry Andric     TotalNumCtrs = TotalNC;
4640b57cec5SDimitry Andric     FuncHash = FHash;
4650b57cec5SDimitry Andric     FuncNameVar = FNV;
46606c3fb27SDimitry Andric     visit(F);
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   // Visit the IR stream and annotate all select instructions.
47006c3fb27SDimitry Andric   void annotateSelects(PGOUseFunc *UF, unsigned *Ind) {
4710b57cec5SDimitry Andric     Mode = VM_annotate;
4720b57cec5SDimitry Andric     UseFunc = UF;
4730b57cec5SDimitry Andric     CurCtrIdx = Ind;
47406c3fb27SDimitry Andric     visit(F);
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   void instrumentOneSelectInst(SelectInst &SI);
4780b57cec5SDimitry Andric   void annotateOneSelectInst(SelectInst &SI);
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // Visit \p SI instruction and perform tasks according to visit mode.
4810b57cec5SDimitry Andric   void visitSelectInst(SelectInst &SI);
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   // Return the number of select instructions. This needs be called after
4840b57cec5SDimitry Andric   // countSelects().
4850b57cec5SDimitry Andric   unsigned getNumOfSelectInsts() const { return NSIs; }
4860b57cec5SDimitry Andric };
4870b57cec5SDimitry Andric 
48806c3fb27SDimitry Andric /// This class implements the CFG edges for the Minimum Spanning Tree (MST)
48906c3fb27SDimitry Andric /// based instrumentation.
49006c3fb27SDimitry Andric /// Note that the CFG can be a multi-graph. So there might be multiple edges
49106c3fb27SDimitry Andric /// with the same SrcBB and DestBB.
4920b57cec5SDimitry Andric struct PGOEdge {
49306c3fb27SDimitry Andric   BasicBlock *SrcBB;
49406c3fb27SDimitry Andric   BasicBlock *DestBB;
4950b57cec5SDimitry Andric   uint64_t Weight;
4960b57cec5SDimitry Andric   bool InMST = false;
4970b57cec5SDimitry Andric   bool Removed = false;
4980b57cec5SDimitry Andric   bool IsCritical = false;
4990b57cec5SDimitry Andric 
50006c3fb27SDimitry Andric   PGOEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W = 1)
5010b57cec5SDimitry Andric       : SrcBB(Src), DestBB(Dest), Weight(W) {}
5020b57cec5SDimitry Andric 
50306c3fb27SDimitry Andric   /// Return the information string of an edge.
504fe6060f1SDimitry Andric   std::string infoString() const {
5050b57cec5SDimitry Andric     return (Twine(Removed ? "-" : " ") + (InMST ? " " : "*") +
50606c3fb27SDimitry Andric             (IsCritical ? "c" : " ") + "  W=" + Twine(Weight))
50706c3fb27SDimitry Andric         .str();
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric };
5100b57cec5SDimitry Andric 
51106c3fb27SDimitry Andric /// This class stores the auxiliary information for each BB in the MST.
51206c3fb27SDimitry Andric struct PGOBBInfo {
51306c3fb27SDimitry Andric   PGOBBInfo *Group;
5140b57cec5SDimitry Andric   uint32_t Index;
5150b57cec5SDimitry Andric   uint32_t Rank = 0;
5160b57cec5SDimitry Andric 
51706c3fb27SDimitry Andric   PGOBBInfo(unsigned IX) : Group(this), Index(IX) {}
5180b57cec5SDimitry Andric 
51906c3fb27SDimitry Andric   /// Return the information string of this object.
520fe6060f1SDimitry Andric   std::string infoString() const {
5210b57cec5SDimitry Andric     return (Twine("Index=") + Twine(Index)).str();
5220b57cec5SDimitry Andric   }
5230b57cec5SDimitry Andric };
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric // This class implements the CFG edges. Note the CFG can be a multi-graph.
5260b57cec5SDimitry Andric template <class Edge, class BBInfo> class FuncPGOInstrumentation {
5270b57cec5SDimitry Andric private:
5280b57cec5SDimitry Andric   Function &F;
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric   // Is this is context-sensitive instrumentation.
5310b57cec5SDimitry Andric   bool IsCS;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   // A map that stores the Comdat group in function F.
5340b57cec5SDimitry Andric   std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
5350b57cec5SDimitry Andric 
5368bcb0991SDimitry Andric   ValueProfileCollector VPC;
5378bcb0991SDimitry Andric 
5380b57cec5SDimitry Andric   void computeCFGHash();
5390b57cec5SDimitry Andric   void renameComdatFunction();
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric public:
542bdd1243dSDimitry Andric   const TargetLibraryInfo &TLI;
5438bcb0991SDimitry Andric   std::vector<std::vector<VPCandidateInfo>> ValueSites;
5440b57cec5SDimitry Andric   SelectInstVisitor SIVisitor;
5450b57cec5SDimitry Andric   std::string FuncName;
5465f757f3fSDimitry Andric   std::string DeprecatedFuncName;
5470b57cec5SDimitry Andric   GlobalVariable *FuncNameVar;
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   // CFG hash value for this function.
5500b57cec5SDimitry Andric   uint64_t FunctionHash = 0;
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   // The Minimum Spanning Tree of function CFG.
5530b57cec5SDimitry Andric   CFGMST<Edge, BBInfo> MST;
5540b57cec5SDimitry Andric 
55506c3fb27SDimitry Andric   const std::optional<BlockCoverageInference> BCI;
55606c3fb27SDimitry Andric 
55706c3fb27SDimitry Andric   static std::optional<BlockCoverageInference>
55806c3fb27SDimitry Andric   constructBCI(Function &Func, bool HasSingleByteCoverage,
55906c3fb27SDimitry Andric                bool InstrumentFuncEntry) {
56006c3fb27SDimitry Andric     if (HasSingleByteCoverage)
56106c3fb27SDimitry Andric       return BlockCoverageInference(Func, InstrumentFuncEntry);
56206c3fb27SDimitry Andric     return {};
56306c3fb27SDimitry Andric   }
56406c3fb27SDimitry Andric 
5650b57cec5SDimitry Andric   // Collect all the BBs that will be instrumented, and store them in
5660b57cec5SDimitry Andric   // InstrumentBBs.
5670b57cec5SDimitry Andric   void getInstrumentBBs(std::vector<BasicBlock *> &InstrumentBBs);
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   // Give an edge, find the BB that will be instrumented.
5700b57cec5SDimitry Andric   // Return nullptr if there is no BB to be instrumented.
5710b57cec5SDimitry Andric   BasicBlock *getInstrBB(Edge *E);
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric   // Return the auxiliary BB information.
5740b57cec5SDimitry Andric   BBInfo &getBBInfo(const BasicBlock *BB) const { return MST.getBBInfo(BB); }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   // Return the auxiliary BB information if available.
5770b57cec5SDimitry Andric   BBInfo *findBBInfo(const BasicBlock *BB) const { return MST.findBBInfo(BB); }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   // Dump edges and BB information.
58006c3fb27SDimitry Andric   void dumpInfo(StringRef Str = "") const {
58106c3fb27SDimitry Andric     MST.dumpEdges(dbgs(), Twine("Dump Function ") + FuncName +
58206c3fb27SDimitry Andric                               " Hash: " + Twine(FunctionHash) + "\t" + Str);
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric   FuncPGOInstrumentation(
5865ffd83dbSDimitry Andric       Function &Func, TargetLibraryInfo &TLI,
5870b57cec5SDimitry Andric       std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
5880b57cec5SDimitry Andric       bool CreateGlobalVar = false, BranchProbabilityInfo *BPI = nullptr,
589e8d8bef9SDimitry Andric       BlockFrequencyInfo *BFI = nullptr, bool IsCS = false,
59006c3fb27SDimitry Andric       bool InstrumentFuncEntry = true, bool HasSingleByteCoverage = false)
5915ffd83dbSDimitry Andric       : F(Func), IsCS(IsCS), ComdatMembers(ComdatMembers), VPC(Func, TLI),
59206c3fb27SDimitry Andric         TLI(TLI), ValueSites(IPVK_Last + 1),
59306c3fb27SDimitry Andric         SIVisitor(Func, HasSingleByteCoverage),
59406c3fb27SDimitry Andric         MST(F, InstrumentFuncEntry, BPI, BFI),
59506c3fb27SDimitry Andric         BCI(constructBCI(Func, HasSingleByteCoverage, InstrumentFuncEntry)) {
59606c3fb27SDimitry Andric     if (BCI && PGOViewBlockCoverageGraph)
59706c3fb27SDimitry Andric       BCI->viewBlockCoverageGraph();
5980b57cec5SDimitry Andric     // This should be done before CFG hash computation.
59906c3fb27SDimitry Andric     SIVisitor.countSelects();
6008bcb0991SDimitry Andric     ValueSites[IPVK_MemOPSize] = VPC.get(IPVK_MemOPSize);
6010b57cec5SDimitry Andric     if (!IsCS) {
6020b57cec5SDimitry Andric       NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
6038bcb0991SDimitry Andric       NumOfPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
6045f757f3fSDimitry Andric       NumOfPGOBB += MST.bbInfoSize();
6058bcb0991SDimitry Andric       ValueSites[IPVK_IndirectCallTarget] = VPC.get(IPVK_IndirectCallTarget);
6060fca6ea1SDimitry Andric       if (EnableVTableValueProfiling)
6070fca6ea1SDimitry Andric         ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
6080b57cec5SDimitry Andric     } else {
6090b57cec5SDimitry Andric       NumOfCSPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
6108bcb0991SDimitry Andric       NumOfCSPGOMemIntrinsics += ValueSites[IPVK_MemOPSize].size();
6115f757f3fSDimitry Andric       NumOfCSPGOBB += MST.bbInfoSize();
6120b57cec5SDimitry Andric     }
6130b57cec5SDimitry Andric 
6145f757f3fSDimitry Andric     FuncName = getIRPGOFuncName(F);
6155f757f3fSDimitry Andric     DeprecatedFuncName = getPGOFuncName(F);
6160b57cec5SDimitry Andric     computeCFGHash();
6170b57cec5SDimitry Andric     if (!ComdatMembers.empty())
6180b57cec5SDimitry Andric       renameComdatFunction();
6190b57cec5SDimitry Andric     LLVM_DEBUG(dumpInfo("after CFGMST"));
6200b57cec5SDimitry Andric 
6215f757f3fSDimitry Andric     for (const auto &E : MST.allEdges()) {
6220b57cec5SDimitry Andric       if (E->Removed)
6230b57cec5SDimitry Andric         continue;
6240b57cec5SDimitry Andric       IsCS ? NumOfCSPGOEdge++ : NumOfPGOEdge++;
6250b57cec5SDimitry Andric       if (!E->InMST)
6260b57cec5SDimitry Andric         IsCS ? NumOfCSPGOInstrument++ : NumOfPGOInstrument++;
6270b57cec5SDimitry Andric     }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric     if (CreateGlobalVar)
6300b57cec5SDimitry Andric       FuncNameVar = createPGOFuncNameVar(F, FuncName);
6310b57cec5SDimitry Andric   }
6320b57cec5SDimitry Andric };
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric } // end anonymous namespace
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric // Compute Hash value for the CFG: the lower 32 bits are CRC32 of the index
637e8d8bef9SDimitry Andric // value of each BB in the CFG. The higher 32 bits are the CRC32 of the numbers
638e8d8bef9SDimitry Andric // of selects, indirect calls, mem ops and edges.
6390b57cec5SDimitry Andric template <class Edge, class BBInfo>
6400b57cec5SDimitry Andric void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() {
6418bcb0991SDimitry Andric   std::vector<uint8_t> Indexes;
6420b57cec5SDimitry Andric   JamCRC JC;
6430b57cec5SDimitry Andric   for (auto &BB : F) {
644297eecfbSDimitry Andric     for (BasicBlock *Succ : successors(&BB)) {
6450b57cec5SDimitry Andric       auto BI = findBBInfo(Succ);
6460b57cec5SDimitry Andric       if (BI == nullptr)
6470b57cec5SDimitry Andric         continue;
6480b57cec5SDimitry Andric       uint32_t Index = BI->Index;
6490b57cec5SDimitry Andric       for (int J = 0; J < 4; J++)
6508bcb0991SDimitry Andric         Indexes.push_back((uint8_t)(Index >> (J * 8)));
6510b57cec5SDimitry Andric     }
6520b57cec5SDimitry Andric   }
6530b57cec5SDimitry Andric   JC.update(Indexes);
6540b57cec5SDimitry Andric 
655e8d8bef9SDimitry Andric   JamCRC JCH;
656e8d8bef9SDimitry Andric   // The higher 32 bits.
657e8d8bef9SDimitry Andric   auto updateJCH = [&JCH](uint64_t Num) {
658e8d8bef9SDimitry Andric     uint8_t Data[8];
659e8d8bef9SDimitry Andric     support::endian::write64le(Data, Num);
660e8d8bef9SDimitry Andric     JCH.update(Data);
661e8d8bef9SDimitry Andric   };
662e8d8bef9SDimitry Andric   updateJCH((uint64_t)SIVisitor.getNumOfSelectInsts());
663e8d8bef9SDimitry Andric   updateJCH((uint64_t)ValueSites[IPVK_IndirectCallTarget].size());
664e8d8bef9SDimitry Andric   updateJCH((uint64_t)ValueSites[IPVK_MemOPSize].size());
66506c3fb27SDimitry Andric   if (BCI) {
66606c3fb27SDimitry Andric     updateJCH(BCI->getInstrumentedBlocksHash());
66706c3fb27SDimitry Andric   } else {
6685f757f3fSDimitry Andric     updateJCH((uint64_t)MST.numEdges());
66906c3fb27SDimitry Andric   }
670e8d8bef9SDimitry Andric 
671e8d8bef9SDimitry Andric   // Hash format for context sensitive profile. Reserve 4 bits for other
672e8d8bef9SDimitry Andric   // information.
673e8d8bef9SDimitry Andric   FunctionHash = (((uint64_t)JCH.getCRC()) << 28) + JC.getCRC();
674e8d8bef9SDimitry Andric 
6750b57cec5SDimitry Andric   // Reserve bit 60-63 for other information purpose.
6760b57cec5SDimitry Andric   FunctionHash &= 0x0FFFFFFFFFFFFFFF;
6770b57cec5SDimitry Andric   if (IsCS)
6780b57cec5SDimitry Andric     NamedInstrProfRecord::setCSFlagInHash(FunctionHash);
6790b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Function Hash Computation for " << F.getName() << ":\n"
6800b57cec5SDimitry Andric                     << " CRC = " << JC.getCRC()
6810b57cec5SDimitry Andric                     << ", Selects = " << SIVisitor.getNumOfSelectInsts()
6825f757f3fSDimitry Andric                     << ", Edges = " << MST.numEdges() << ", ICSites = "
683297eecfbSDimitry Andric                     << ValueSites[IPVK_IndirectCallTarget].size()
684297eecfbSDimitry Andric                     << ", Memops = " << ValueSites[IPVK_MemOPSize].size()
685297eecfbSDimitry Andric                     << ", High32 CRC = " << JCH.getCRC()
686297eecfbSDimitry Andric                     << ", Hash = " << FunctionHash << "\n";);
687fcaf7f86SDimitry Andric 
688fcaf7f86SDimitry Andric   if (PGOTraceFuncHash != "-" && F.getName().contains(PGOTraceFuncHash))
689fcaf7f86SDimitry Andric     dbgs() << "Funcname=" << F.getName() << ", Hash=" << FunctionHash
690fcaf7f86SDimitry Andric            << " in building " << F.getParent()->getSourceFileName() << "\n";
6910b57cec5SDimitry Andric }
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric // Check if we can safely rename this Comdat function.
6940b57cec5SDimitry Andric static bool canRenameComdat(
6950b57cec5SDimitry Andric     Function &F,
6960b57cec5SDimitry Andric     std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
6970b57cec5SDimitry Andric   if (!DoComdatRenaming || !canRenameComdatFunc(F, true))
6980b57cec5SDimitry Andric     return false;
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   // FIXME: Current only handle those Comdat groups that only containing one
701e8d8bef9SDimitry Andric   // function.
7020b57cec5SDimitry Andric   // (1) For a Comdat group containing multiple functions, we need to have a
7030b57cec5SDimitry Andric   // unique postfix based on the hashes for each function. There is a
7040b57cec5SDimitry Andric   // non-trivial code refactoring to do this efficiently.
7050b57cec5SDimitry Andric   // (2) Variables can not be renamed, so we can not rename Comdat function in a
7060b57cec5SDimitry Andric   // group including global vars.
7070b57cec5SDimitry Andric   Comdat *C = F.getComdat();
7080b57cec5SDimitry Andric   for (auto &&CM : make_range(ComdatMembers.equal_range(C))) {
709e8d8bef9SDimitry Andric     assert(!isa<GlobalAlias>(CM.second));
7100b57cec5SDimitry Andric     Function *FM = dyn_cast<Function>(CM.second);
7110b57cec5SDimitry Andric     if (FM != &F)
7120b57cec5SDimitry Andric       return false;
7130b57cec5SDimitry Andric   }
7140b57cec5SDimitry Andric   return true;
7150b57cec5SDimitry Andric }
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric // Append the CFGHash to the Comdat function name.
7180b57cec5SDimitry Andric template <class Edge, class BBInfo>
7190b57cec5SDimitry Andric void FuncPGOInstrumentation<Edge, BBInfo>::renameComdatFunction() {
7200b57cec5SDimitry Andric   if (!canRenameComdat(F, ComdatMembers))
7210b57cec5SDimitry Andric     return;
7220b57cec5SDimitry Andric   std::string OrigName = F.getName().str();
7230b57cec5SDimitry Andric   std::string NewFuncName =
7240b57cec5SDimitry Andric       Twine(F.getName() + "." + Twine(FunctionHash)).str();
7250b57cec5SDimitry Andric   F.setName(Twine(NewFuncName));
7260b57cec5SDimitry Andric   GlobalAlias::create(GlobalValue::WeakAnyLinkage, OrigName, &F);
7270b57cec5SDimitry Andric   FuncName = Twine(FuncName + "." + Twine(FunctionHash)).str();
7280b57cec5SDimitry Andric   Comdat *NewComdat;
7290b57cec5SDimitry Andric   Module *M = F.getParent();
7300b57cec5SDimitry Andric   // For AvailableExternallyLinkage functions, change the linkage to
7310b57cec5SDimitry Andric   // LinkOnceODR and put them into comdat. This is because after renaming, there
7320b57cec5SDimitry Andric   // is no backup external copy available for the function.
7330b57cec5SDimitry Andric   if (!F.hasComdat()) {
7340b57cec5SDimitry Andric     assert(F.getLinkage() == GlobalValue::AvailableExternallyLinkage);
7350b57cec5SDimitry Andric     NewComdat = M->getOrInsertComdat(StringRef(NewFuncName));
7360b57cec5SDimitry Andric     F.setLinkage(GlobalValue::LinkOnceODRLinkage);
7370b57cec5SDimitry Andric     F.setComdat(NewComdat);
7380b57cec5SDimitry Andric     return;
7390b57cec5SDimitry Andric   }
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric   // This function belongs to a single function Comdat group.
7420b57cec5SDimitry Andric   Comdat *OrigComdat = F.getComdat();
7430b57cec5SDimitry Andric   std::string NewComdatName =
7440b57cec5SDimitry Andric       Twine(OrigComdat->getName() + "." + Twine(FunctionHash)).str();
7450b57cec5SDimitry Andric   NewComdat = M->getOrInsertComdat(StringRef(NewComdatName));
7460b57cec5SDimitry Andric   NewComdat->setSelectionKind(OrigComdat->getSelectionKind());
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   for (auto &&CM : make_range(ComdatMembers.equal_range(OrigComdat))) {
7490b57cec5SDimitry Andric     // Must be a function.
750e8d8bef9SDimitry Andric     cast<Function>(CM.second)->setComdat(NewComdat);
7510b57cec5SDimitry Andric   }
7520b57cec5SDimitry Andric }
7530b57cec5SDimitry Andric 
75406c3fb27SDimitry Andric /// Collect all the BBs that will be instruments and add them to
75506c3fb27SDimitry Andric /// `InstrumentBBs`.
7560b57cec5SDimitry Andric template <class Edge, class BBInfo>
7570b57cec5SDimitry Andric void FuncPGOInstrumentation<Edge, BBInfo>::getInstrumentBBs(
7580b57cec5SDimitry Andric     std::vector<BasicBlock *> &InstrumentBBs) {
75906c3fb27SDimitry Andric   if (BCI) {
76006c3fb27SDimitry Andric     for (auto &BB : F)
76106c3fb27SDimitry Andric       if (BCI->shouldInstrumentBlock(BB))
76206c3fb27SDimitry Andric         InstrumentBBs.push_back(&BB);
76306c3fb27SDimitry Andric     return;
76406c3fb27SDimitry Andric   }
76506c3fb27SDimitry Andric 
7660b57cec5SDimitry Andric   // Use a worklist as we will update the vector during the iteration.
7670b57cec5SDimitry Andric   std::vector<Edge *> EdgeList;
7685f757f3fSDimitry Andric   EdgeList.reserve(MST.numEdges());
7695f757f3fSDimitry Andric   for (const auto &E : MST.allEdges())
7700b57cec5SDimitry Andric     EdgeList.push_back(E.get());
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric   for (auto &E : EdgeList) {
7730b57cec5SDimitry Andric     BasicBlock *InstrBB = getInstrBB(E);
7740b57cec5SDimitry Andric     if (InstrBB)
7750b57cec5SDimitry Andric       InstrumentBBs.push_back(InstrBB);
7760b57cec5SDimitry Andric   }
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric // Given a CFG E to be instrumented, find which BB to place the instrumented
7800b57cec5SDimitry Andric // code. The function will split the critical edge if necessary.
7810b57cec5SDimitry Andric template <class Edge, class BBInfo>
7820b57cec5SDimitry Andric BasicBlock *FuncPGOInstrumentation<Edge, BBInfo>::getInstrBB(Edge *E) {
7830b57cec5SDimitry Andric   if (E->InMST || E->Removed)
7840b57cec5SDimitry Andric     return nullptr;
7850b57cec5SDimitry Andric 
78606c3fb27SDimitry Andric   BasicBlock *SrcBB = E->SrcBB;
78706c3fb27SDimitry Andric   BasicBlock *DestBB = E->DestBB;
7880b57cec5SDimitry Andric   // For a fake edge, instrument the real BB.
7890b57cec5SDimitry Andric   if (SrcBB == nullptr)
7900b57cec5SDimitry Andric     return DestBB;
7910b57cec5SDimitry Andric   if (DestBB == nullptr)
7920b57cec5SDimitry Andric     return SrcBB;
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   auto canInstrument = [](BasicBlock *BB) -> BasicBlock * {
7950b57cec5SDimitry Andric     // There are basic blocks (such as catchswitch) cannot be instrumented.
7960b57cec5SDimitry Andric     // If the returned first insertion point is the end of BB, skip this BB.
7970b57cec5SDimitry Andric     if (BB->getFirstInsertionPt() == BB->end())
7980b57cec5SDimitry Andric       return nullptr;
7990b57cec5SDimitry Andric     return BB;
8000b57cec5SDimitry Andric   };
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric   // Instrument the SrcBB if it has a single successor,
8030b57cec5SDimitry Andric   // otherwise, the DestBB if this is not a critical edge.
8040b57cec5SDimitry Andric   Instruction *TI = SrcBB->getTerminator();
8050b57cec5SDimitry Andric   if (TI->getNumSuccessors() <= 1)
8060b57cec5SDimitry Andric     return canInstrument(SrcBB);
8070b57cec5SDimitry Andric   if (!E->IsCritical)
8080b57cec5SDimitry Andric     return canInstrument(DestBB);
8090b57cec5SDimitry Andric 
810e8d8bef9SDimitry Andric   // Some IndirectBr critical edges cannot be split by the previous
811e8d8bef9SDimitry Andric   // SplitIndirectBrCriticalEdges call. Bail out.
8120b57cec5SDimitry Andric   unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
813e8d8bef9SDimitry Andric   BasicBlock *InstrBB =
814e8d8bef9SDimitry Andric       isa<IndirectBrInst>(TI) ? nullptr : SplitCriticalEdge(TI, SuccNum);
8150b57cec5SDimitry Andric   if (!InstrBB) {
8160b57cec5SDimitry Andric     LLVM_DEBUG(
8170b57cec5SDimitry Andric         dbgs() << "Fail to split critical edge: not instrument this edge.\n");
8180b57cec5SDimitry Andric     return nullptr;
8190b57cec5SDimitry Andric   }
8200b57cec5SDimitry Andric   // For a critical edge, we have to split. Instrument the newly
8210b57cec5SDimitry Andric   // created BB.
8220b57cec5SDimitry Andric   IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++;
8230b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Split critical edge: " << getBBInfo(SrcBB).Index
8240b57cec5SDimitry Andric                     << " --> " << getBBInfo(DestBB).Index << "\n");
8250b57cec5SDimitry Andric   // Need to add two new edges. First one: Add new edge of SrcBB->InstrBB.
8260b57cec5SDimitry Andric   MST.addEdge(SrcBB, InstrBB, 0);
8270b57cec5SDimitry Andric   // Second one: Add new edge of InstrBB->DestBB.
8280b57cec5SDimitry Andric   Edge &NewEdge1 = MST.addEdge(InstrBB, DestBB, 0);
8290b57cec5SDimitry Andric   NewEdge1.InMST = true;
8300b57cec5SDimitry Andric   E->Removed = true;
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric   return canInstrument(InstrBB);
8330b57cec5SDimitry Andric }
8340b57cec5SDimitry Andric 
8355ffd83dbSDimitry Andric // When generating value profiling calls on Windows routines that make use of
8365ffd83dbSDimitry Andric // handler funclets for exception processing an operand bundle needs to attached
8375ffd83dbSDimitry Andric // to the called function. This routine will set \p OpBundles to contain the
8385ffd83dbSDimitry Andric // funclet information, if any is needed, that should be placed on the generated
8395ffd83dbSDimitry Andric // value profiling call for the value profile candidate call.
8405ffd83dbSDimitry Andric static void
8415ffd83dbSDimitry Andric populateEHOperandBundle(VPCandidateInfo &Cand,
8425ffd83dbSDimitry Andric                         DenseMap<BasicBlock *, ColorVector> &BlockColors,
8435ffd83dbSDimitry Andric                         SmallVectorImpl<OperandBundleDef> &OpBundles) {
8445ffd83dbSDimitry Andric   auto *OrigCall = dyn_cast<CallBase>(Cand.AnnotatedInst);
84504eeddc0SDimitry Andric   if (!OrigCall)
84604eeddc0SDimitry Andric     return;
84704eeddc0SDimitry Andric 
84804eeddc0SDimitry Andric   if (!isa<IntrinsicInst>(OrigCall)) {
8495ffd83dbSDimitry Andric     // The instrumentation call should belong to the same funclet as a
8505ffd83dbSDimitry Andric     // non-intrinsic call, so just copy the operand bundle, if any exists.
851bdd1243dSDimitry Andric     std::optional<OperandBundleUse> ParentFunclet =
8525ffd83dbSDimitry Andric         OrigCall->getOperandBundle(LLVMContext::OB_funclet);
8535ffd83dbSDimitry Andric     if (ParentFunclet)
8545ffd83dbSDimitry Andric       OpBundles.emplace_back(OperandBundleDef(*ParentFunclet));
8555ffd83dbSDimitry Andric   } else {
8565ffd83dbSDimitry Andric     // Intrinsics or other instructions do not get funclet information from the
8575ffd83dbSDimitry Andric     // front-end. Need to use the BlockColors that was computed by the routine
8585ffd83dbSDimitry Andric     // colorEHFunclets to determine whether a funclet is needed.
8595ffd83dbSDimitry Andric     if (!BlockColors.empty()) {
8605ffd83dbSDimitry Andric       const ColorVector &CV = BlockColors.find(OrigCall->getParent())->second;
8615ffd83dbSDimitry Andric       assert(CV.size() == 1 && "non-unique color for block!");
8625ffd83dbSDimitry Andric       Instruction *EHPad = CV.front()->getFirstNonPHI();
8635ffd83dbSDimitry Andric       if (EHPad->isEHPad())
8645ffd83dbSDimitry Andric         OpBundles.emplace_back("funclet", EHPad);
8655ffd83dbSDimitry Andric     }
8665ffd83dbSDimitry Andric   }
8675ffd83dbSDimitry Andric }
8685ffd83dbSDimitry Andric 
8690b57cec5SDimitry Andric // Visit all edge and instrument the edges not in MST, and do value profiling.
8700b57cec5SDimitry Andric // Critical edges will be split.
8710b57cec5SDimitry Andric static void instrumentOneFunc(
8725ffd83dbSDimitry Andric     Function &F, Module *M, TargetLibraryInfo &TLI, BranchProbabilityInfo *BPI,
8735ffd83dbSDimitry Andric     BlockFrequencyInfo *BFI,
8740b57cec5SDimitry Andric     std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
8750b57cec5SDimitry Andric     bool IsCS) {
87606c3fb27SDimitry Andric   if (!PGOBlockCoverage) {
8770b57cec5SDimitry Andric     // Split indirectbr critical edges here before computing the MST rather than
8780b57cec5SDimitry Andric     // later in getInstrBB() to avoid invalidating it.
87981ad6265SDimitry Andric     SplitIndirectBrCriticalEdges(F, /*IgnoreBlocksWithoutPHI=*/false, BPI, BFI);
88006c3fb27SDimitry Andric   }
8810b57cec5SDimitry Andric 
88206c3fb27SDimitry Andric   FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo(
8830fca6ea1SDimitry Andric       F, TLI, ComdatMembers, true, BPI, BFI, IsCS, shouldInstrumentEntryBB(),
88406c3fb27SDimitry Andric       PGOBlockCoverage);
8851fd87a68SDimitry Andric 
8865f757f3fSDimitry Andric   auto Name = FuncInfo.FuncNameVar;
8871fd87a68SDimitry Andric   auto CFGHash = ConstantInt::get(Type::getInt64Ty(M->getContext()),
8881fd87a68SDimitry Andric                                   FuncInfo.FunctionHash);
8891fd87a68SDimitry Andric   if (PGOFunctionEntryCoverage) {
8901fd87a68SDimitry Andric     auto &EntryBB = F.getEntryBlock();
8911fd87a68SDimitry Andric     IRBuilder<> Builder(&EntryBB, EntryBB.getFirstInsertionPt());
8921fd87a68SDimitry Andric     // llvm.instrprof.cover(i8* <name>, i64 <hash>, i32 <num-counters>,
8931fd87a68SDimitry Andric     //                      i32 <index>)
8941fd87a68SDimitry Andric     Builder.CreateCall(
8951fd87a68SDimitry Andric         Intrinsic::getDeclaration(M, Intrinsic::instrprof_cover),
8961fd87a68SDimitry Andric         {Name, CFGHash, Builder.getInt32(1), Builder.getInt32(0)});
8971fd87a68SDimitry Andric     return;
8981fd87a68SDimitry Andric   }
8991fd87a68SDimitry Andric 
9000b57cec5SDimitry Andric   std::vector<BasicBlock *> InstrumentBBs;
9010b57cec5SDimitry Andric   FuncInfo.getInstrumentBBs(InstrumentBBs);
9020b57cec5SDimitry Andric   unsigned NumCounters =
9030b57cec5SDimitry Andric       InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
9040b57cec5SDimitry Andric 
9050fca6ea1SDimitry Andric   if (PGOCtxProfLoweringPass::isContextualIRPGOEnabled()) {
9060fca6ea1SDimitry Andric     auto *CSIntrinsic =
9070fca6ea1SDimitry Andric         Intrinsic::getDeclaration(M, Intrinsic::instrprof_callsite);
9080fca6ea1SDimitry Andric     // We want to count the instrumentable callsites, then instrument them. This
9090fca6ea1SDimitry Andric     // is because the llvm.instrprof.callsite intrinsic has an argument (like
9100fca6ea1SDimitry Andric     // the other instrprof intrinsics) capturing the total number of
9110fca6ea1SDimitry Andric     // instrumented objects (counters, or callsites, in this case). In this
9120fca6ea1SDimitry Andric     // case, we want that value so we can readily pass it to the compiler-rt
9130fca6ea1SDimitry Andric     // APIs that may have to allocate memory based on the nr of callsites.
9140fca6ea1SDimitry Andric     // The traversal logic is the same for both counting and instrumentation,
9150fca6ea1SDimitry Andric     // just needs to be done in succession.
9160fca6ea1SDimitry Andric     auto Visit = [&](llvm::function_ref<void(CallBase * CB)> Visitor) {
9170fca6ea1SDimitry Andric       for (auto &BB : F)
9180fca6ea1SDimitry Andric         for (auto &Instr : BB)
9190fca6ea1SDimitry Andric           if (auto *CS = dyn_cast<CallBase>(&Instr)) {
9200fca6ea1SDimitry Andric             if ((CS->getCalledFunction() &&
9210fca6ea1SDimitry Andric                  CS->getCalledFunction()->isIntrinsic()) ||
9220fca6ea1SDimitry Andric                 dyn_cast<InlineAsm>(CS->getCalledOperand()))
9230fca6ea1SDimitry Andric               continue;
9240fca6ea1SDimitry Andric             Visitor(CS);
9250fca6ea1SDimitry Andric           }
9260fca6ea1SDimitry Andric     };
9270fca6ea1SDimitry Andric     // First, count callsites.
9280fca6ea1SDimitry Andric     uint32_t TotalNrCallsites = 0;
9290fca6ea1SDimitry Andric     Visit([&TotalNrCallsites](auto *) { ++TotalNrCallsites; });
9300fca6ea1SDimitry Andric 
9310fca6ea1SDimitry Andric     // Now instrument.
9320fca6ea1SDimitry Andric     uint32_t CallsiteIndex = 0;
9330fca6ea1SDimitry Andric     Visit([&](auto *CB) {
9340fca6ea1SDimitry Andric       IRBuilder<> Builder(CB);
9350fca6ea1SDimitry Andric       Builder.CreateCall(CSIntrinsic,
9360fca6ea1SDimitry Andric                          {Name, CFGHash, Builder.getInt32(TotalNrCallsites),
9370fca6ea1SDimitry Andric                           Builder.getInt32(CallsiteIndex++),
9380fca6ea1SDimitry Andric                           CB->getCalledOperand()});
9390fca6ea1SDimitry Andric     });
9400fca6ea1SDimitry Andric   }
9410fca6ea1SDimitry Andric 
9420b57cec5SDimitry Andric   uint32_t I = 0;
94306c3fb27SDimitry Andric   if (PGOTemporalInstrumentation) {
94406c3fb27SDimitry Andric     NumCounters += PGOBlockCoverage ? 8 : 1;
94506c3fb27SDimitry Andric     auto &EntryBB = F.getEntryBlock();
94606c3fb27SDimitry Andric     IRBuilder<> Builder(&EntryBB, EntryBB.getFirstInsertionPt());
94706c3fb27SDimitry Andric     // llvm.instrprof.timestamp(i8* <name>, i64 <hash>, i32 <num-counters>,
94806c3fb27SDimitry Andric     //                          i32 <index>)
94906c3fb27SDimitry Andric     Builder.CreateCall(
95006c3fb27SDimitry Andric         Intrinsic::getDeclaration(M, Intrinsic::instrprof_timestamp),
95106c3fb27SDimitry Andric         {Name, CFGHash, Builder.getInt32(NumCounters), Builder.getInt32(I)});
95206c3fb27SDimitry Andric     I += PGOBlockCoverage ? 8 : 1;
95306c3fb27SDimitry Andric   }
95406c3fb27SDimitry Andric 
9550b57cec5SDimitry Andric   for (auto *InstrBB : InstrumentBBs) {
9560b57cec5SDimitry Andric     IRBuilder<> Builder(InstrBB, InstrBB->getFirstInsertionPt());
9570b57cec5SDimitry Andric     assert(Builder.GetInsertPoint() != InstrBB->end() &&
9580b57cec5SDimitry Andric            "Cannot get the Instrumentation point");
9591fd87a68SDimitry Andric     // llvm.instrprof.increment(i8* <name>, i64 <hash>, i32 <num-counters>,
9601fd87a68SDimitry Andric     //                          i32 <index>)
9610b57cec5SDimitry Andric     Builder.CreateCall(
96206c3fb27SDimitry Andric         Intrinsic::getDeclaration(M, PGOBlockCoverage
96306c3fb27SDimitry Andric                                          ? Intrinsic::instrprof_cover
96406c3fb27SDimitry Andric                                          : Intrinsic::instrprof_increment),
9651fd87a68SDimitry Andric         {Name, CFGHash, Builder.getInt32(NumCounters), Builder.getInt32(I++)});
9660b57cec5SDimitry Andric   }
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   // Now instrument select instructions:
96906c3fb27SDimitry Andric   FuncInfo.SIVisitor.instrumentSelects(&I, NumCounters, FuncInfo.FuncNameVar,
9700b57cec5SDimitry Andric                                        FuncInfo.FunctionHash);
9710b57cec5SDimitry Andric   assert(I == NumCounters);
9720b57cec5SDimitry Andric 
9730fca6ea1SDimitry Andric   if (isValueProfilingDisabled())
9740b57cec5SDimitry Andric     return;
9750b57cec5SDimitry Andric 
9768bcb0991SDimitry Andric   NumOfPGOICall += FuncInfo.ValueSites[IPVK_IndirectCallTarget].size();
9778bcb0991SDimitry Andric 
9785ffd83dbSDimitry Andric   // Intrinsic function calls do not have funclet operand bundles needed for
9795ffd83dbSDimitry Andric   // Windows exception handling attached to them. However, if value profiling is
9805ffd83dbSDimitry Andric   // inserted for one of these calls, then a funclet value will need to be set
9815ffd83dbSDimitry Andric   // on the instrumentation call based on the funclet coloring.
9825ffd83dbSDimitry Andric   DenseMap<BasicBlock *, ColorVector> BlockColors;
9835ffd83dbSDimitry Andric   if (F.hasPersonalityFn() &&
9840fca6ea1SDimitry Andric       isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
9855ffd83dbSDimitry Andric     BlockColors = colorEHFunclets(F);
9865ffd83dbSDimitry Andric 
9878bcb0991SDimitry Andric   // For each VP Kind, walk the VP candidates and instrument each one.
9888bcb0991SDimitry Andric   for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
9898bcb0991SDimitry Andric     unsigned SiteIndex = 0;
9908bcb0991SDimitry Andric     if (Kind == IPVK_MemOPSize && !PGOInstrMemOP)
9918bcb0991SDimitry Andric       continue;
9928bcb0991SDimitry Andric 
9938bcb0991SDimitry Andric     for (VPCandidateInfo Cand : FuncInfo.ValueSites[Kind]) {
9948bcb0991SDimitry Andric       LLVM_DEBUG(dbgs() << "Instrument one VP " << ValueProfKindDescr[Kind]
9958bcb0991SDimitry Andric                         << " site: CallSite Index = " << SiteIndex << "\n");
9968bcb0991SDimitry Andric 
9978bcb0991SDimitry Andric       IRBuilder<> Builder(Cand.InsertPt);
9988bcb0991SDimitry Andric       assert(Builder.GetInsertPoint() != Cand.InsertPt->getParent()->end() &&
9990b57cec5SDimitry Andric              "Cannot get the Instrumentation point");
10008bcb0991SDimitry Andric 
10018bcb0991SDimitry Andric       Value *ToProfile = nullptr;
10028bcb0991SDimitry Andric       if (Cand.V->getType()->isIntegerTy())
10038bcb0991SDimitry Andric         ToProfile = Builder.CreateZExtOrTrunc(Cand.V, Builder.getInt64Ty());
10048bcb0991SDimitry Andric       else if (Cand.V->getType()->isPointerTy())
10058bcb0991SDimitry Andric         ToProfile = Builder.CreatePtrToInt(Cand.V, Builder.getInt64Ty());
10068bcb0991SDimitry Andric       assert(ToProfile && "value profiling Value is of unexpected type");
10078bcb0991SDimitry Andric 
10085ffd83dbSDimitry Andric       SmallVector<OperandBundleDef, 1> OpBundles;
10095ffd83dbSDimitry Andric       populateEHOperandBundle(Cand, BlockColors, OpBundles);
10100b57cec5SDimitry Andric       Builder.CreateCall(
10110b57cec5SDimitry Andric           Intrinsic::getDeclaration(M, Intrinsic::instrprof_value_profile),
10125f757f3fSDimitry Andric           {FuncInfo.FuncNameVar, Builder.getInt64(FuncInfo.FunctionHash),
10135f757f3fSDimitry Andric            ToProfile, Builder.getInt32(Kind), Builder.getInt32(SiteIndex++)},
10145ffd83dbSDimitry Andric           OpBundles);
10150b57cec5SDimitry Andric     }
10168bcb0991SDimitry Andric   } // IPVK_First <= Kind <= IPVK_Last
10170b57cec5SDimitry Andric }
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric namespace {
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric // This class represents a CFG edge in profile use compilation.
10220b57cec5SDimitry Andric struct PGOUseEdge : public PGOEdge {
102306c3fb27SDimitry Andric   using PGOEdge::PGOEdge;
102406c3fb27SDimitry Andric 
10250fca6ea1SDimitry Andric   std::optional<uint64_t> Count;
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric   // Set edge count value
10280fca6ea1SDimitry Andric   void setEdgeCount(uint64_t Value) { Count = Value; }
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric   // Return the information string for this object.
1031fe6060f1SDimitry Andric   std::string infoString() const {
10320fca6ea1SDimitry Andric     if (!Count)
10330b57cec5SDimitry Andric       return PGOEdge::infoString();
10340fca6ea1SDimitry Andric     return (Twine(PGOEdge::infoString()) + "  Count=" + Twine(*Count)).str();
10350b57cec5SDimitry Andric   }
10360b57cec5SDimitry Andric };
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric using DirectEdges = SmallVector<PGOUseEdge *, 2>;
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric // This class stores the auxiliary information for each BB.
104106c3fb27SDimitry Andric struct PGOUseBBInfo : public PGOBBInfo {
10420fca6ea1SDimitry Andric   std::optional<uint64_t> Count;
10430b57cec5SDimitry Andric   int32_t UnknownCountInEdge = 0;
10440b57cec5SDimitry Andric   int32_t UnknownCountOutEdge = 0;
10450b57cec5SDimitry Andric   DirectEdges InEdges;
10460b57cec5SDimitry Andric   DirectEdges OutEdges;
10470b57cec5SDimitry Andric 
10480fca6ea1SDimitry Andric   PGOUseBBInfo(unsigned IX) : PGOBBInfo(IX) {}
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   // Set the profile count value for this BB.
10510fca6ea1SDimitry Andric   void setBBInfoCount(uint64_t Value) { Count = Value; }
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric   // Return the information string of this object.
1054fe6060f1SDimitry Andric   std::string infoString() const {
10550fca6ea1SDimitry Andric     if (!Count)
105606c3fb27SDimitry Andric       return PGOBBInfo::infoString();
10570fca6ea1SDimitry Andric     return (Twine(PGOBBInfo::infoString()) + "  Count=" + Twine(*Count)).str();
10580b57cec5SDimitry Andric   }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   // Add an OutEdge and update the edge count.
10610b57cec5SDimitry Andric   void addOutEdge(PGOUseEdge *E) {
10620b57cec5SDimitry Andric     OutEdges.push_back(E);
10630b57cec5SDimitry Andric     UnknownCountOutEdge++;
10640b57cec5SDimitry Andric   }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric   // Add an InEdge and update the edge count.
10670b57cec5SDimitry Andric   void addInEdge(PGOUseEdge *E) {
10680b57cec5SDimitry Andric     InEdges.push_back(E);
10690b57cec5SDimitry Andric     UnknownCountInEdge++;
10700b57cec5SDimitry Andric   }
10710b57cec5SDimitry Andric };
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric } // end anonymous namespace
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric // Sum up the count values for all the edges.
10760b57cec5SDimitry Andric static uint64_t sumEdgeCount(const ArrayRef<PGOUseEdge *> Edges) {
10770b57cec5SDimitry Andric   uint64_t Total = 0;
1078bdd1243dSDimitry Andric   for (const auto &E : Edges) {
10790b57cec5SDimitry Andric     if (E->Removed)
10800b57cec5SDimitry Andric       continue;
10810fca6ea1SDimitry Andric     if (E->Count)
10820fca6ea1SDimitry Andric       Total += *E->Count;
10830b57cec5SDimitry Andric   }
10840b57cec5SDimitry Andric   return Total;
10850b57cec5SDimitry Andric }
10860b57cec5SDimitry Andric 
10870b57cec5SDimitry Andric namespace {
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric class PGOUseFunc {
10900b57cec5SDimitry Andric public:
10915ffd83dbSDimitry Andric   PGOUseFunc(Function &Func, Module *Modu, TargetLibraryInfo &TLI,
10920b57cec5SDimitry Andric              std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
10938bcb0991SDimitry Andric              BranchProbabilityInfo *BPI, BlockFrequencyInfo *BFIin,
109406c3fb27SDimitry Andric              ProfileSummaryInfo *PSI, bool IsCS, bool InstrumentFuncEntry,
109506c3fb27SDimitry Andric              bool HasSingleByteCoverage)
10968bcb0991SDimitry Andric       : F(Func), M(Modu), BFI(BFIin), PSI(PSI),
1097e8d8bef9SDimitry Andric         FuncInfo(Func, TLI, ComdatMembers, false, BPI, BFIin, IsCS,
109806c3fb27SDimitry Andric                  InstrumentFuncEntry, HasSingleByteCoverage),
10990fca6ea1SDimitry Andric         FreqAttr(FFA_Normal), IsCS(IsCS), VPC(Func, TLI) {}
11000b57cec5SDimitry Andric 
110106c3fb27SDimitry Andric   void handleInstrProfError(Error Err, uint64_t MismatchedFuncSum);
110206c3fb27SDimitry Andric 
11030b57cec5SDimitry Andric   // Read counts for the instrumented BB from profile.
1104e8d8bef9SDimitry Andric   bool readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
1105bdd1243dSDimitry Andric                     InstrProfRecord::CountPseudoKind &PseudoKind);
1106bdd1243dSDimitry Andric 
11070b57cec5SDimitry Andric   // Populate the counts for all BBs.
11080b57cec5SDimitry Andric   void populateCounters();
11090b57cec5SDimitry Andric 
111006c3fb27SDimitry Andric   // Set block coverage based on profile coverage values.
111106c3fb27SDimitry Andric   void populateCoverage(IndexedInstrProfReader *PGOReader);
111206c3fb27SDimitry Andric 
11130b57cec5SDimitry Andric   // Set the branch weights based on the count values.
11140b57cec5SDimitry Andric   void setBranchWeights();
11150b57cec5SDimitry Andric 
11160b57cec5SDimitry Andric   // Annotate the value profile call sites for all value kind.
11170b57cec5SDimitry Andric   void annotateValueSites();
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric   // Annotate the value profile call sites for one value kind.
11200b57cec5SDimitry Andric   void annotateValueSites(uint32_t Kind);
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   // Annotate the irreducible loop header weights.
11230b57cec5SDimitry Andric   void annotateIrrLoopHeaderWeights();
11240b57cec5SDimitry Andric 
11250b57cec5SDimitry Andric   // The hotness of the function from the profile count.
11260b57cec5SDimitry Andric   enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric   // Return the function hotness from the profile.
11290b57cec5SDimitry Andric   FuncFreqAttr getFuncFreqAttr() const { return FreqAttr; }
11300b57cec5SDimitry Andric 
11310b57cec5SDimitry Andric   // Return the function hash.
11320b57cec5SDimitry Andric   uint64_t getFuncHash() const { return FuncInfo.FunctionHash; }
11330b57cec5SDimitry Andric 
11340b57cec5SDimitry Andric   // Return the profile record for this function;
11350b57cec5SDimitry Andric   InstrProfRecord &getProfileRecord() { return ProfileRecord; }
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric   // Return the auxiliary BB information.
113806c3fb27SDimitry Andric   PGOUseBBInfo &getBBInfo(const BasicBlock *BB) const {
11390b57cec5SDimitry Andric     return FuncInfo.getBBInfo(BB);
11400b57cec5SDimitry Andric   }
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric   // Return the auxiliary BB information if available.
114306c3fb27SDimitry Andric   PGOUseBBInfo *findBBInfo(const BasicBlock *BB) const {
11440b57cec5SDimitry Andric     return FuncInfo.findBBInfo(BB);
11450b57cec5SDimitry Andric   }
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric   Function &getFunc() const { return F; }
11480b57cec5SDimitry Andric 
114906c3fb27SDimitry Andric   void dumpInfo(StringRef Str = "") const { FuncInfo.dumpInfo(Str); }
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric   uint64_t getProgramMaxCount() const { return ProgramMaxCount; }
115206c3fb27SDimitry Andric 
11530b57cec5SDimitry Andric private:
11540b57cec5SDimitry Andric   Function &F;
11550b57cec5SDimitry Andric   Module *M;
11560b57cec5SDimitry Andric   BlockFrequencyInfo *BFI;
11578bcb0991SDimitry Andric   ProfileSummaryInfo *PSI;
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   // This member stores the shared information with class PGOGenFunc.
116006c3fb27SDimitry Andric   FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> FuncInfo;
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric   // The maximum count value in the profile. This is only used in PGO use
11630b57cec5SDimitry Andric   // compilation.
11640b57cec5SDimitry Andric   uint64_t ProgramMaxCount;
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   // Position of counter that remains to be read.
11670b57cec5SDimitry Andric   uint32_t CountPosition = 0;
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric   // Total size of the profile count for this function.
11700b57cec5SDimitry Andric   uint32_t ProfileCountSize = 0;
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric   // ProfileRecord for this function.
11730b57cec5SDimitry Andric   InstrProfRecord ProfileRecord;
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric   // Function hotness info derived from profile.
11760b57cec5SDimitry Andric   FuncFreqAttr FreqAttr;
11770b57cec5SDimitry Andric 
11780b57cec5SDimitry Andric   // Is to use the context sensitive profile.
11790b57cec5SDimitry Andric   bool IsCS;
11800b57cec5SDimitry Andric 
11810fca6ea1SDimitry Andric   ValueProfileCollector VPC;
11820fca6ea1SDimitry Andric 
11830b57cec5SDimitry Andric   // Find the Instrumented BB and set the value. Return false on error.
11840b57cec5SDimitry Andric   bool setInstrumentedCounts(const std::vector<uint64_t> &CountFromProfile);
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric   // Set the edge counter value for the unknown edge -- there should be only
11870b57cec5SDimitry Andric   // one unknown edge.
11880b57cec5SDimitry Andric   void setEdgeCount(DirectEdges &Edges, uint64_t Value);
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric   // Set the hot/cold inline hints based on the count values.
11910b57cec5SDimitry Andric   // FIXME: This function should be removed once the functionality in
11920b57cec5SDimitry Andric   // the inliner is implemented.
11930b57cec5SDimitry Andric   void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
11948bcb0991SDimitry Andric     if (PSI->isHotCount(EntryCount))
11950b57cec5SDimitry Andric       FreqAttr = FFA_Hot;
11968bcb0991SDimitry Andric     else if (PSI->isColdCount(MaxCount))
11970b57cec5SDimitry Andric       FreqAttr = FFA_Cold;
11980b57cec5SDimitry Andric   }
11990b57cec5SDimitry Andric };
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric } // end anonymous namespace
12020b57cec5SDimitry Andric 
120306c3fb27SDimitry Andric /// Set up InEdges/OutEdges for all BBs in the MST.
12045f757f3fSDimitry Andric static void setupBBInfoEdges(
12055f757f3fSDimitry Andric     const FuncPGOInstrumentation<PGOUseEdge, PGOUseBBInfo> &FuncInfo) {
120606c3fb27SDimitry Andric   // This is not required when there is block coverage inference.
120706c3fb27SDimitry Andric   if (FuncInfo.BCI)
120806c3fb27SDimitry Andric     return;
12095f757f3fSDimitry Andric   for (const auto &E : FuncInfo.MST.allEdges()) {
121006c3fb27SDimitry Andric     if (E->Removed)
121106c3fb27SDimitry Andric       continue;
121206c3fb27SDimitry Andric     const BasicBlock *SrcBB = E->SrcBB;
121306c3fb27SDimitry Andric     const BasicBlock *DestBB = E->DestBB;
121406c3fb27SDimitry Andric     PGOUseBBInfo &SrcInfo = FuncInfo.getBBInfo(SrcBB);
121506c3fb27SDimitry Andric     PGOUseBBInfo &DestInfo = FuncInfo.getBBInfo(DestBB);
121606c3fb27SDimitry Andric     SrcInfo.addOutEdge(E.get());
121706c3fb27SDimitry Andric     DestInfo.addInEdge(E.get());
121806c3fb27SDimitry Andric   }
121906c3fb27SDimitry Andric }
122006c3fb27SDimitry Andric 
12210b57cec5SDimitry Andric // Visit all the edges and assign the count value for the instrumented
12220b57cec5SDimitry Andric // edges and the BB. Return false on error.
12230b57cec5SDimitry Andric bool PGOUseFunc::setInstrumentedCounts(
12240b57cec5SDimitry Andric     const std::vector<uint64_t> &CountFromProfile) {
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric   std::vector<BasicBlock *> InstrumentBBs;
12270b57cec5SDimitry Andric   FuncInfo.getInstrumentBBs(InstrumentBBs);
122806c3fb27SDimitry Andric 
122906c3fb27SDimitry Andric   setupBBInfoEdges(FuncInfo);
123006c3fb27SDimitry Andric 
12310b57cec5SDimitry Andric   unsigned NumCounters =
12320b57cec5SDimitry Andric       InstrumentBBs.size() + FuncInfo.SIVisitor.getNumOfSelectInsts();
12330b57cec5SDimitry Andric   // The number of counters here should match the number of counters
12340b57cec5SDimitry Andric   // in profile. Return if they mismatch.
12350b57cec5SDimitry Andric   if (NumCounters != CountFromProfile.size()) {
12360b57cec5SDimitry Andric     return false;
12370b57cec5SDimitry Andric   }
1238e8d8bef9SDimitry Andric   auto *FuncEntry = &*F.begin();
1239e8d8bef9SDimitry Andric 
12400b57cec5SDimitry Andric   // Set the profile count to the Instrumented BBs.
12410b57cec5SDimitry Andric   uint32_t I = 0;
12420b57cec5SDimitry Andric   for (BasicBlock *InstrBB : InstrumentBBs) {
12430b57cec5SDimitry Andric     uint64_t CountValue = CountFromProfile[I++];
124406c3fb27SDimitry Andric     PGOUseBBInfo &Info = getBBInfo(InstrBB);
1245e8d8bef9SDimitry Andric     // If we reach here, we know that we have some nonzero count
1246e8d8bef9SDimitry Andric     // values in this function. The entry count should not be 0.
1247e8d8bef9SDimitry Andric     // Fix it if necessary.
1248e8d8bef9SDimitry Andric     if (InstrBB == FuncEntry && CountValue == 0)
1249e8d8bef9SDimitry Andric       CountValue = 1;
12500b57cec5SDimitry Andric     Info.setBBInfoCount(CountValue);
12510b57cec5SDimitry Andric   }
12520b57cec5SDimitry Andric   ProfileCountSize = CountFromProfile.size();
12530b57cec5SDimitry Andric   CountPosition = I;
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric   // Set the edge count and update the count of unknown edges for BBs.
12560b57cec5SDimitry Andric   auto setEdgeCount = [this](PGOUseEdge *E, uint64_t Value) -> void {
12570b57cec5SDimitry Andric     E->setEdgeCount(Value);
12580b57cec5SDimitry Andric     this->getBBInfo(E->SrcBB).UnknownCountOutEdge--;
12590b57cec5SDimitry Andric     this->getBBInfo(E->DestBB).UnknownCountInEdge--;
12600b57cec5SDimitry Andric   };
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   // Set the profile count the Instrumented edges. There are BBs that not in
12630b57cec5SDimitry Andric   // MST but not instrumented. Need to set the edge count value so that we can
12640b57cec5SDimitry Andric   // populate the profile counts later.
12655f757f3fSDimitry Andric   for (const auto &E : FuncInfo.MST.allEdges()) {
12660b57cec5SDimitry Andric     if (E->Removed || E->InMST)
12670b57cec5SDimitry Andric       continue;
12680b57cec5SDimitry Andric     const BasicBlock *SrcBB = E->SrcBB;
126906c3fb27SDimitry Andric     PGOUseBBInfo &SrcInfo = getBBInfo(SrcBB);
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric     // If only one out-edge, the edge profile count should be the same as BB
12720b57cec5SDimitry Andric     // profile count.
12730fca6ea1SDimitry Andric     if (SrcInfo.Count && SrcInfo.OutEdges.size() == 1)
12740fca6ea1SDimitry Andric       setEdgeCount(E.get(), *SrcInfo.Count);
12750b57cec5SDimitry Andric     else {
12760b57cec5SDimitry Andric       const BasicBlock *DestBB = E->DestBB;
127706c3fb27SDimitry Andric       PGOUseBBInfo &DestInfo = getBBInfo(DestBB);
12780b57cec5SDimitry Andric       // If only one in-edge, the edge profile count should be the same as BB
12790b57cec5SDimitry Andric       // profile count.
12800fca6ea1SDimitry Andric       if (DestInfo.Count && DestInfo.InEdges.size() == 1)
12810fca6ea1SDimitry Andric         setEdgeCount(E.get(), *DestInfo.Count);
12820b57cec5SDimitry Andric     }
12830fca6ea1SDimitry Andric     if (E->Count)
12840b57cec5SDimitry Andric       continue;
12850b57cec5SDimitry Andric     // E's count should have been set from profile. If not, this meenas E skips
12860b57cec5SDimitry Andric     // the instrumentation. We set the count to 0.
12870b57cec5SDimitry Andric     setEdgeCount(E.get(), 0);
12880b57cec5SDimitry Andric   }
12890b57cec5SDimitry Andric   return true;
12900b57cec5SDimitry Andric }
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric // Set the count value for the unknown edge. There should be one and only one
12930b57cec5SDimitry Andric // unknown edge in Edges vector.
12940b57cec5SDimitry Andric void PGOUseFunc::setEdgeCount(DirectEdges &Edges, uint64_t Value) {
12950b57cec5SDimitry Andric   for (auto &E : Edges) {
12960fca6ea1SDimitry Andric     if (E->Count)
12970b57cec5SDimitry Andric       continue;
12980b57cec5SDimitry Andric     E->setEdgeCount(Value);
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric     getBBInfo(E->SrcBB).UnknownCountOutEdge--;
13010b57cec5SDimitry Andric     getBBInfo(E->DestBB).UnknownCountInEdge--;
13020b57cec5SDimitry Andric     return;
13030b57cec5SDimitry Andric   }
13040b57cec5SDimitry Andric   llvm_unreachable("Cannot find the unknown count edge");
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric 
1307fe6060f1SDimitry Andric // Emit function metadata indicating PGO profile mismatch.
130806c3fb27SDimitry Andric static void annotateFunctionWithHashMismatch(Function &F, LLVMContext &ctx) {
1309fe6060f1SDimitry Andric   const char MetadataName[] = "instr_prof_hash_mismatch";
1310fe6060f1SDimitry Andric   SmallVector<Metadata *, 2> Names;
1311fe6060f1SDimitry Andric   // If this metadata already exists, ignore.
1312fe6060f1SDimitry Andric   auto *Existing = F.getMetadata(LLVMContext::MD_annotation);
1313fe6060f1SDimitry Andric   if (Existing) {
1314fe6060f1SDimitry Andric     MDTuple *Tuple = cast<MDTuple>(Existing);
1315bdd1243dSDimitry Andric     for (const auto &N : Tuple->operands()) {
131606c3fb27SDimitry Andric       if (N.equalsStr(MetadataName))
1317fe6060f1SDimitry Andric         return;
1318fe6060f1SDimitry Andric       Names.push_back(N.get());
1319fe6060f1SDimitry Andric     }
1320fe6060f1SDimitry Andric   }
1321fe6060f1SDimitry Andric 
1322fe6060f1SDimitry Andric   MDBuilder MDB(ctx);
1323fe6060f1SDimitry Andric   Names.push_back(MDB.createString(MetadataName));
1324fe6060f1SDimitry Andric   MDNode *MD = MDTuple::get(ctx, Names);
1325fe6060f1SDimitry Andric   F.setMetadata(LLVMContext::MD_annotation, MD);
1326fe6060f1SDimitry Andric }
1327fe6060f1SDimitry Andric 
132806c3fb27SDimitry Andric void PGOUseFunc::handleInstrProfError(Error Err, uint64_t MismatchedFuncSum) {
132906c3fb27SDimitry Andric   handleAllErrors(std::move(Err), [&](const InstrProfError &IPE) {
1330bdd1243dSDimitry Andric     auto &Ctx = M->getContext();
13310b57cec5SDimitry Andric     auto Err = IPE.get();
13320b57cec5SDimitry Andric     bool SkipWarning = false;
13330b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Error in reading profile for Func "
13340b57cec5SDimitry Andric                       << FuncInfo.FuncName << ": ");
13350b57cec5SDimitry Andric     if (Err == instrprof_error::unknown_function) {
13360b57cec5SDimitry Andric       IsCS ? NumOfCSPGOMissing++ : NumOfPGOMissing++;
13370b57cec5SDimitry Andric       SkipWarning = !PGOWarnMissing;
13380b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "unknown function");
13390b57cec5SDimitry Andric     } else if (Err == instrprof_error::hash_mismatch ||
13400b57cec5SDimitry Andric                Err == instrprof_error::malformed) {
13410b57cec5SDimitry Andric       IsCS ? NumOfCSPGOMismatch++ : NumOfPGOMismatch++;
13420b57cec5SDimitry Andric       SkipWarning =
13430b57cec5SDimitry Andric           NoPGOWarnMismatch ||
1344fcaf7f86SDimitry Andric           (NoPGOWarnMismatchComdatWeak &&
1345fcaf7f86SDimitry Andric            (F.hasComdat() || F.getLinkage() == GlobalValue::WeakAnyLinkage ||
13460b57cec5SDimitry Andric             F.getLinkage() == GlobalValue::AvailableExternallyLinkage));
1347fcaf7f86SDimitry Andric       LLVM_DEBUG(dbgs() << "hash mismatch (hash= " << FuncInfo.FunctionHash
1348fcaf7f86SDimitry Andric                         << " skip=" << SkipWarning << ")");
1349fe6060f1SDimitry Andric       // Emit function metadata indicating PGO profile mismatch.
1350fe6060f1SDimitry Andric       annotateFunctionWithHashMismatch(F, M->getContext());
13510b57cec5SDimitry Andric     }
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " IsCS=" << IsCS << "\n");
13540b57cec5SDimitry Andric     if (SkipWarning)
13550b57cec5SDimitry Andric       return;
13560b57cec5SDimitry Andric 
1357fcaf7f86SDimitry Andric     std::string Msg =
1358fcaf7f86SDimitry Andric         IPE.message() + std::string(" ") + F.getName().str() +
1359fcaf7f86SDimitry Andric         std::string(" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
1360fcaf7f86SDimitry Andric         std::string(" up to ") + std::to_string(MismatchedFuncSum) +
1361fcaf7f86SDimitry Andric         std::string(" count discarded");
13620b57cec5SDimitry Andric 
13630b57cec5SDimitry Andric     Ctx.diagnose(
13640b57cec5SDimitry Andric         DiagnosticInfoPGOProfile(M->getName().data(), Msg, DS_Warning));
13650b57cec5SDimitry Andric   });
136606c3fb27SDimitry Andric }
136706c3fb27SDimitry Andric 
136806c3fb27SDimitry Andric // Read the profile from ProfileFileName and assign the value to the
136906c3fb27SDimitry Andric // instrumented BB and the edges. This function also updates ProgramMaxCount.
137006c3fb27SDimitry Andric // Return true if the profile are successfully read, and false on errors.
137106c3fb27SDimitry Andric bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
137206c3fb27SDimitry Andric                               InstrProfRecord::CountPseudoKind &PseudoKind) {
137306c3fb27SDimitry Andric   auto &Ctx = M->getContext();
137406c3fb27SDimitry Andric   uint64_t MismatchedFuncSum = 0;
137506c3fb27SDimitry Andric   Expected<InstrProfRecord> Result = PGOReader->getInstrProfRecord(
13765f757f3fSDimitry Andric       FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
13775f757f3fSDimitry Andric       &MismatchedFuncSum);
137806c3fb27SDimitry Andric   if (Error E = Result.takeError()) {
137906c3fb27SDimitry Andric     handleInstrProfError(std::move(E), MismatchedFuncSum);
13800b57cec5SDimitry Andric     return false;
13810b57cec5SDimitry Andric   }
13820b57cec5SDimitry Andric   ProfileRecord = std::move(Result.get());
1383bdd1243dSDimitry Andric   PseudoKind = ProfileRecord.getCountPseudoKind();
1384bdd1243dSDimitry Andric   if (PseudoKind != InstrProfRecord::NotPseudo) {
1385bdd1243dSDimitry Andric     return true;
1386bdd1243dSDimitry Andric   }
13870b57cec5SDimitry Andric   std::vector<uint64_t> &CountFromProfile = ProfileRecord.Counts;
13880b57cec5SDimitry Andric 
13890b57cec5SDimitry Andric   IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
13900b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << CountFromProfile.size() << " counts\n");
1391bdd1243dSDimitry Andric 
13920b57cec5SDimitry Andric   uint64_t ValueSum = 0;
13930b57cec5SDimitry Andric   for (unsigned I = 0, S = CountFromProfile.size(); I < S; I++) {
13940b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "  " << I << ": " << CountFromProfile[I] << "\n");
13950b57cec5SDimitry Andric     ValueSum += CountFromProfile[I];
13960b57cec5SDimitry Andric   }
13970b57cec5SDimitry Andric   AllZeros = (ValueSum == 0);
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "SUM =  " << ValueSum << "\n");
14000b57cec5SDimitry Andric 
14010b57cec5SDimitry Andric   getBBInfo(nullptr).UnknownCountOutEdge = 2;
14020b57cec5SDimitry Andric   getBBInfo(nullptr).UnknownCountInEdge = 2;
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric   if (!setInstrumentedCounts(CountFromProfile)) {
14050b57cec5SDimitry Andric     LLVM_DEBUG(
14060b57cec5SDimitry Andric         dbgs() << "Inconsistent number of counts, skipping this function");
14070b57cec5SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(
14080b57cec5SDimitry Andric         M->getName().data(),
140906c3fb27SDimitry Andric         Twine("Inconsistent number of counts in ") + F.getName().str() +
141006c3fb27SDimitry Andric             Twine(": the profile may be stale or there is a function name "
141106c3fb27SDimitry Andric                   "collision."),
14120b57cec5SDimitry Andric         DS_Warning));
14130b57cec5SDimitry Andric     return false;
14140b57cec5SDimitry Andric   }
14150b57cec5SDimitry Andric   ProgramMaxCount = PGOReader->getMaximumFunctionCount(IsCS);
14160b57cec5SDimitry Andric   return true;
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric 
141906c3fb27SDimitry Andric void PGOUseFunc::populateCoverage(IndexedInstrProfReader *PGOReader) {
142006c3fb27SDimitry Andric   uint64_t MismatchedFuncSum = 0;
142106c3fb27SDimitry Andric   Expected<InstrProfRecord> Result = PGOReader->getInstrProfRecord(
14225f757f3fSDimitry Andric       FuncInfo.FuncName, FuncInfo.FunctionHash, FuncInfo.DeprecatedFuncName,
14235f757f3fSDimitry Andric       &MismatchedFuncSum);
142406c3fb27SDimitry Andric   if (auto Err = Result.takeError()) {
142506c3fb27SDimitry Andric     handleInstrProfError(std::move(Err), MismatchedFuncSum);
142606c3fb27SDimitry Andric     return;
142706c3fb27SDimitry Andric   }
14280fca6ea1SDimitry Andric   IsCS ? NumOfCSPGOFunc++ : NumOfPGOFunc++;
142906c3fb27SDimitry Andric 
143006c3fb27SDimitry Andric   std::vector<uint64_t> &CountsFromProfile = Result.get().Counts;
143106c3fb27SDimitry Andric   DenseMap<const BasicBlock *, bool> Coverage;
143206c3fb27SDimitry Andric   unsigned Index = 0;
143306c3fb27SDimitry Andric   for (auto &BB : F)
143406c3fb27SDimitry Andric     if (FuncInfo.BCI->shouldInstrumentBlock(BB))
143506c3fb27SDimitry Andric       Coverage[&BB] = (CountsFromProfile[Index++] != 0);
143606c3fb27SDimitry Andric   assert(Index == CountsFromProfile.size());
143706c3fb27SDimitry Andric 
143806c3fb27SDimitry Andric   // For each B in InverseDependencies[A], if A is covered then B is covered.
143906c3fb27SDimitry Andric   DenseMap<const BasicBlock *, DenseSet<const BasicBlock *>>
144006c3fb27SDimitry Andric       InverseDependencies;
144106c3fb27SDimitry Andric   for (auto &BB : F) {
144206c3fb27SDimitry Andric     for (auto *Dep : FuncInfo.BCI->getDependencies(BB)) {
144306c3fb27SDimitry Andric       // If Dep is covered then BB is covered.
144406c3fb27SDimitry Andric       InverseDependencies[Dep].insert(&BB);
144506c3fb27SDimitry Andric     }
144606c3fb27SDimitry Andric   }
144706c3fb27SDimitry Andric 
144806c3fb27SDimitry Andric   // Infer coverage of the non-instrumented blocks using a flood-fill algorithm.
144906c3fb27SDimitry Andric   std::stack<const BasicBlock *> CoveredBlocksToProcess;
145006c3fb27SDimitry Andric   for (auto &[BB, IsCovered] : Coverage)
145106c3fb27SDimitry Andric     if (IsCovered)
145206c3fb27SDimitry Andric       CoveredBlocksToProcess.push(BB);
145306c3fb27SDimitry Andric 
145406c3fb27SDimitry Andric   while (!CoveredBlocksToProcess.empty()) {
145506c3fb27SDimitry Andric     auto *CoveredBlock = CoveredBlocksToProcess.top();
145606c3fb27SDimitry Andric     assert(Coverage[CoveredBlock]);
145706c3fb27SDimitry Andric     CoveredBlocksToProcess.pop();
145806c3fb27SDimitry Andric     for (auto *BB : InverseDependencies[CoveredBlock]) {
145906c3fb27SDimitry Andric       // If CoveredBlock is covered then BB is covered.
146006c3fb27SDimitry Andric       if (Coverage[BB])
146106c3fb27SDimitry Andric         continue;
146206c3fb27SDimitry Andric       Coverage[BB] = true;
146306c3fb27SDimitry Andric       CoveredBlocksToProcess.push(BB);
146406c3fb27SDimitry Andric     }
146506c3fb27SDimitry Andric   }
146606c3fb27SDimitry Andric 
146706c3fb27SDimitry Andric   // Annotate block coverage.
146806c3fb27SDimitry Andric   MDBuilder MDB(F.getContext());
146906c3fb27SDimitry Andric   // We set the entry count to 10000 if the entry block is covered so that BFI
147006c3fb27SDimitry Andric   // can propagate a fraction of this count to the other covered blocks.
147106c3fb27SDimitry Andric   F.setEntryCount(Coverage[&F.getEntryBlock()] ? 10000 : 0);
147206c3fb27SDimitry Andric   for (auto &BB : F) {
147306c3fb27SDimitry Andric     // For a block A and its successor B, we set the edge weight as follows:
147406c3fb27SDimitry Andric     // If A is covered and B is covered, set weight=1.
147506c3fb27SDimitry Andric     // If A is covered and B is uncovered, set weight=0.
147606c3fb27SDimitry Andric     // If A is uncovered, set weight=1.
147706c3fb27SDimitry Andric     // This setup will allow BFI to give nonzero profile counts to only covered
147806c3fb27SDimitry Andric     // blocks.
14795f757f3fSDimitry Andric     SmallVector<uint32_t, 4> Weights;
148006c3fb27SDimitry Andric     for (auto *Succ : successors(&BB))
148106c3fb27SDimitry Andric       Weights.push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
148206c3fb27SDimitry Andric     if (Weights.size() >= 2)
14830fca6ea1SDimitry Andric       llvm::setBranchWeights(*BB.getTerminator(), Weights,
14840fca6ea1SDimitry Andric                              /*IsExpected=*/false);
148506c3fb27SDimitry Andric   }
148606c3fb27SDimitry Andric 
148706c3fb27SDimitry Andric   unsigned NumCorruptCoverage = 0;
148806c3fb27SDimitry Andric   DominatorTree DT(F);
148906c3fb27SDimitry Andric   LoopInfo LI(DT);
149006c3fb27SDimitry Andric   BranchProbabilityInfo BPI(F, LI);
149106c3fb27SDimitry Andric   BlockFrequencyInfo BFI(F, BPI, LI);
149206c3fb27SDimitry Andric   auto IsBlockDead = [&](const BasicBlock &BB) -> std::optional<bool> {
149306c3fb27SDimitry Andric     if (auto C = BFI.getBlockProfileCount(&BB))
149406c3fb27SDimitry Andric       return C == 0;
149506c3fb27SDimitry Andric     return {};
149606c3fb27SDimitry Andric   };
149706c3fb27SDimitry Andric   LLVM_DEBUG(dbgs() << "Block Coverage: (Instrumented=*, Covered=X)\n");
149806c3fb27SDimitry Andric   for (auto &BB : F) {
149906c3fb27SDimitry Andric     LLVM_DEBUG(dbgs() << (FuncInfo.BCI->shouldInstrumentBlock(BB) ? "* " : "  ")
150006c3fb27SDimitry Andric                       << (Coverage[&BB] ? "X " : "  ") << " " << BB.getName()
150106c3fb27SDimitry Andric                       << "\n");
150206c3fb27SDimitry Andric     // In some cases it is possible to find a covered block that has no covered
150306c3fb27SDimitry Andric     // successors, e.g., when a block calls a function that may call exit(). In
150406c3fb27SDimitry Andric     // those cases, BFI could find its successor to be covered while BCI could
150506c3fb27SDimitry Andric     // find its successor to be dead.
150606c3fb27SDimitry Andric     if (Coverage[&BB] == IsBlockDead(BB).value_or(false)) {
150706c3fb27SDimitry Andric       LLVM_DEBUG(
150806c3fb27SDimitry Andric           dbgs() << "Found inconsistent block covearge for " << BB.getName()
150906c3fb27SDimitry Andric                  << ": BCI=" << (Coverage[&BB] ? "Covered" : "Dead") << " BFI="
151006c3fb27SDimitry Andric                  << (IsBlockDead(BB).value() ? "Dead" : "Covered") << "\n");
151106c3fb27SDimitry Andric       ++NumCorruptCoverage;
151206c3fb27SDimitry Andric     }
151306c3fb27SDimitry Andric     if (Coverage[&BB])
151406c3fb27SDimitry Andric       ++NumCoveredBlocks;
151506c3fb27SDimitry Andric   }
151606c3fb27SDimitry Andric   if (PGOVerifyBFI && NumCorruptCoverage) {
151706c3fb27SDimitry Andric     auto &Ctx = M->getContext();
151806c3fb27SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(
151906c3fb27SDimitry Andric         M->getName().data(),
152006c3fb27SDimitry Andric         Twine("Found inconsistent block coverage for function ") + F.getName() +
152106c3fb27SDimitry Andric             " in " + Twine(NumCorruptCoverage) + " blocks.",
152206c3fb27SDimitry Andric         DS_Warning));
152306c3fb27SDimitry Andric   }
152406c3fb27SDimitry Andric   if (PGOViewBlockCoverageGraph)
152506c3fb27SDimitry Andric     FuncInfo.BCI->viewBlockCoverageGraph(&Coverage);
152606c3fb27SDimitry Andric }
152706c3fb27SDimitry Andric 
15280b57cec5SDimitry Andric // Populate the counters from instrumented BBs to all BBs.
15290b57cec5SDimitry Andric // In the end of this operation, all BBs should have a valid count value.
15300b57cec5SDimitry Andric void PGOUseFunc::populateCounters() {
15310b57cec5SDimitry Andric   bool Changes = true;
15320b57cec5SDimitry Andric   unsigned NumPasses = 0;
15330b57cec5SDimitry Andric   while (Changes) {
15340b57cec5SDimitry Andric     NumPasses++;
15350b57cec5SDimitry Andric     Changes = false;
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric     // For efficient traversal, it's better to start from the end as most
15380b57cec5SDimitry Andric     // of the instrumented edges are at the end.
15390b57cec5SDimitry Andric     for (auto &BB : reverse(F)) {
15400fca6ea1SDimitry Andric       PGOUseBBInfo *UseBBInfo = findBBInfo(&BB);
15410fca6ea1SDimitry Andric       if (UseBBInfo == nullptr)
15420b57cec5SDimitry Andric         continue;
15430fca6ea1SDimitry Andric       if (!UseBBInfo->Count) {
15440fca6ea1SDimitry Andric         if (UseBBInfo->UnknownCountOutEdge == 0) {
15450fca6ea1SDimitry Andric           UseBBInfo->Count = sumEdgeCount(UseBBInfo->OutEdges);
15460b57cec5SDimitry Andric           Changes = true;
15470fca6ea1SDimitry Andric         } else if (UseBBInfo->UnknownCountInEdge == 0) {
15480fca6ea1SDimitry Andric           UseBBInfo->Count = sumEdgeCount(UseBBInfo->InEdges);
15490b57cec5SDimitry Andric           Changes = true;
15500b57cec5SDimitry Andric         }
15510b57cec5SDimitry Andric       }
15520fca6ea1SDimitry Andric       if (UseBBInfo->Count) {
15530fca6ea1SDimitry Andric         if (UseBBInfo->UnknownCountOutEdge == 1) {
15540b57cec5SDimitry Andric           uint64_t Total = 0;
15550fca6ea1SDimitry Andric           uint64_t OutSum = sumEdgeCount(UseBBInfo->OutEdges);
15560b57cec5SDimitry Andric           // If the one of the successor block can early terminate (no-return),
15570b57cec5SDimitry Andric           // we can end up with situation where out edge sum count is larger as
15580b57cec5SDimitry Andric           // the source BB's count is collected by a post-dominated block.
15590fca6ea1SDimitry Andric           if (*UseBBInfo->Count > OutSum)
15600fca6ea1SDimitry Andric             Total = *UseBBInfo->Count - OutSum;
15610fca6ea1SDimitry Andric           setEdgeCount(UseBBInfo->OutEdges, Total);
15620b57cec5SDimitry Andric           Changes = true;
15630b57cec5SDimitry Andric         }
15640fca6ea1SDimitry Andric         if (UseBBInfo->UnknownCountInEdge == 1) {
15650b57cec5SDimitry Andric           uint64_t Total = 0;
15660fca6ea1SDimitry Andric           uint64_t InSum = sumEdgeCount(UseBBInfo->InEdges);
15670fca6ea1SDimitry Andric           if (*UseBBInfo->Count > InSum)
15680fca6ea1SDimitry Andric             Total = *UseBBInfo->Count - InSum;
15690fca6ea1SDimitry Andric           setEdgeCount(UseBBInfo->InEdges, Total);
15700b57cec5SDimitry Andric           Changes = true;
15710b57cec5SDimitry Andric         }
15720b57cec5SDimitry Andric       }
15730b57cec5SDimitry Andric     }
15740b57cec5SDimitry Andric   }
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Populate counts in " << NumPasses << " passes.\n");
157781ad6265SDimitry Andric   (void)NumPasses;
15780b57cec5SDimitry Andric #ifndef NDEBUG
15790b57cec5SDimitry Andric   // Assert every BB has a valid counter.
15800b57cec5SDimitry Andric   for (auto &BB : F) {
15810b57cec5SDimitry Andric     auto BI = findBBInfo(&BB);
15820b57cec5SDimitry Andric     if (BI == nullptr)
15830b57cec5SDimitry Andric       continue;
15840fca6ea1SDimitry Andric     assert(BI->Count && "BB count is not valid");
15850b57cec5SDimitry Andric   }
15860b57cec5SDimitry Andric #endif
15870fca6ea1SDimitry Andric   uint64_t FuncEntryCount = *getBBInfo(&*F.begin()).Count;
15880b57cec5SDimitry Andric   uint64_t FuncMaxCount = FuncEntryCount;
15890b57cec5SDimitry Andric   for (auto &BB : F) {
15900b57cec5SDimitry Andric     auto BI = findBBInfo(&BB);
15910b57cec5SDimitry Andric     if (BI == nullptr)
15920b57cec5SDimitry Andric       continue;
15930fca6ea1SDimitry Andric     FuncMaxCount = std::max(FuncMaxCount, *BI->Count);
15940b57cec5SDimitry Andric   }
1595e8d8bef9SDimitry Andric 
1596e8d8bef9SDimitry Andric   // Fix the obviously inconsistent entry count.
1597e8d8bef9SDimitry Andric   if (FuncMaxCount > 0 && FuncEntryCount == 0)
1598e8d8bef9SDimitry Andric     FuncEntryCount = 1;
1599e8d8bef9SDimitry Andric   F.setEntryCount(ProfileCount(FuncEntryCount, Function::PCT_Real));
16000b57cec5SDimitry Andric   markFunctionAttributes(FuncEntryCount, FuncMaxCount);
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric   // Now annotate select instructions
160306c3fb27SDimitry Andric   FuncInfo.SIVisitor.annotateSelects(this, &CountPosition);
16040b57cec5SDimitry Andric   assert(CountPosition == ProfileCountSize);
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric   LLVM_DEBUG(FuncInfo.dumpInfo("after reading profile."));
16070b57cec5SDimitry Andric }
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric // Assign the scaled count values to the BB with multiple out edges.
16100b57cec5SDimitry Andric void PGOUseFunc::setBranchWeights() {
16110b57cec5SDimitry Andric   // Generate MD_prof metadata for every branch instruction.
16120b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\nSetting branch weights for func " << F.getName()
16130b57cec5SDimitry Andric                     << " IsCS=" << IsCS << "\n");
16140b57cec5SDimitry Andric   for (auto &BB : F) {
16150b57cec5SDimitry Andric     Instruction *TI = BB.getTerminator();
16160b57cec5SDimitry Andric     if (TI->getNumSuccessors() < 2)
16170b57cec5SDimitry Andric       continue;
16180b57cec5SDimitry Andric     if (!(isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
1619bdd1243dSDimitry Andric           isa<IndirectBrInst>(TI) || isa<InvokeInst>(TI) ||
1620bdd1243dSDimitry Andric           isa<CallBrInst>(TI)))
16210b57cec5SDimitry Andric       continue;
16220b57cec5SDimitry Andric 
16230fca6ea1SDimitry Andric     const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
16240fca6ea1SDimitry Andric     if (!*BBCountInfo.Count)
16250b57cec5SDimitry Andric       continue;
16260b57cec5SDimitry Andric 
16270b57cec5SDimitry Andric     // We have a non-zero Branch BB.
1628*6c4b055cSDimitry Andric 
1629*6c4b055cSDimitry Andric     // SuccessorCount can be greater than OutEdgesCount, because
1630*6c4b055cSDimitry Andric     // removed edges don't appear in OutEdges.
1631*6c4b055cSDimitry Andric     unsigned OutEdgesCount = BBCountInfo.OutEdges.size();
1632*6c4b055cSDimitry Andric     unsigned SuccessorCount = BB.getTerminator()->getNumSuccessors();
1633*6c4b055cSDimitry Andric     assert(OutEdgesCount <= SuccessorCount);
1634*6c4b055cSDimitry Andric 
1635*6c4b055cSDimitry Andric     SmallVector<uint64_t, 2> EdgeCounts(SuccessorCount, 0);
16360b57cec5SDimitry Andric     uint64_t MaxCount = 0;
1637*6c4b055cSDimitry Andric     for (unsigned It = 0; It < OutEdgesCount; It++) {
1638*6c4b055cSDimitry Andric       const PGOUseEdge *E = BBCountInfo.OutEdges[It];
16390b57cec5SDimitry Andric       const BasicBlock *SrcBB = E->SrcBB;
16400b57cec5SDimitry Andric       const BasicBlock *DestBB = E->DestBB;
16410b57cec5SDimitry Andric       if (DestBB == nullptr)
16420b57cec5SDimitry Andric         continue;
16430b57cec5SDimitry Andric       unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
16440fca6ea1SDimitry Andric       uint64_t EdgeCount = *E->Count;
16450b57cec5SDimitry Andric       if (EdgeCount > MaxCount)
16460b57cec5SDimitry Andric         MaxCount = EdgeCount;
16470b57cec5SDimitry Andric       EdgeCounts[SuccNum] = EdgeCount;
16480b57cec5SDimitry Andric     }
1649bdd1243dSDimitry Andric 
1650bdd1243dSDimitry Andric     if (MaxCount)
16510b57cec5SDimitry Andric       setProfMetadata(M, TI, EdgeCounts, MaxCount);
1652bdd1243dSDimitry Andric     else {
1653bdd1243dSDimitry Andric       // A zero MaxCount can come about when we have a BB with a positive
1654bdd1243dSDimitry Andric       // count, and whose successor blocks all have 0 count. This can happen
1655bdd1243dSDimitry Andric       // when there is no exit block and the code exits via a noreturn function.
1656bdd1243dSDimitry Andric       auto &Ctx = M->getContext();
1657bdd1243dSDimitry Andric       Ctx.diagnose(DiagnosticInfoPGOProfile(
1658bdd1243dSDimitry Andric           M->getName().data(),
1659bdd1243dSDimitry Andric           Twine("Profile in ") + F.getName().str() +
1660bdd1243dSDimitry Andric               Twine(" partially ignored") +
1661bdd1243dSDimitry Andric               Twine(", possibly due to the lack of a return path."),
1662bdd1243dSDimitry Andric           DS_Warning));
1663bdd1243dSDimitry Andric     }
16640b57cec5SDimitry Andric   }
16650b57cec5SDimitry Andric }
16660b57cec5SDimitry Andric 
16670b57cec5SDimitry Andric static bool isIndirectBrTarget(BasicBlock *BB) {
1668fe6060f1SDimitry Andric   for (BasicBlock *Pred : predecessors(BB)) {
1669fe6060f1SDimitry Andric     if (isa<IndirectBrInst>(Pred->getTerminator()))
16700b57cec5SDimitry Andric       return true;
16710b57cec5SDimitry Andric   }
16720b57cec5SDimitry Andric   return false;
16730b57cec5SDimitry Andric }
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric void PGOUseFunc::annotateIrrLoopHeaderWeights() {
16760b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\nAnnotating irreducible loop header weights.\n");
16770b57cec5SDimitry Andric   // Find irr loop headers
16780b57cec5SDimitry Andric   for (auto &BB : F) {
16790b57cec5SDimitry Andric     // As a heuristic also annotate indrectbr targets as they have a high chance
16800b57cec5SDimitry Andric     // to become an irreducible loop header after the indirectbr tail
16810b57cec5SDimitry Andric     // duplication.
16820b57cec5SDimitry Andric     if (BFI->isIrrLoopHeader(&BB) || isIndirectBrTarget(&BB)) {
16830b57cec5SDimitry Andric       Instruction *TI = BB.getTerminator();
168406c3fb27SDimitry Andric       const PGOUseBBInfo &BBCountInfo = getBBInfo(&BB);
16850fca6ea1SDimitry Andric       setIrrLoopHeaderMetadata(M, TI, *BBCountInfo.Count);
16860b57cec5SDimitry Andric     }
16870b57cec5SDimitry Andric   }
16880b57cec5SDimitry Andric }
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
16910b57cec5SDimitry Andric   Module *M = F.getParent();
16920b57cec5SDimitry Andric   IRBuilder<> Builder(&SI);
16930b57cec5SDimitry Andric   Type *Int64Ty = Builder.getInt64Ty();
16940b57cec5SDimitry Andric   auto *Step = Builder.CreateZExt(SI.getCondition(), Int64Ty);
16950b57cec5SDimitry Andric   Builder.CreateCall(
16960b57cec5SDimitry Andric       Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment_step),
16975f757f3fSDimitry Andric       {FuncNameVar, Builder.getInt64(FuncHash), Builder.getInt32(TotalNumCtrs),
16980b57cec5SDimitry Andric        Builder.getInt32(*CurCtrIdx), Step});
16990b57cec5SDimitry Andric   ++(*CurCtrIdx);
17000b57cec5SDimitry Andric }
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric void SelectInstVisitor::annotateOneSelectInst(SelectInst &SI) {
17030b57cec5SDimitry Andric   std::vector<uint64_t> &CountFromProfile = UseFunc->getProfileRecord().Counts;
17040b57cec5SDimitry Andric   assert(*CurCtrIdx < CountFromProfile.size() &&
17050b57cec5SDimitry Andric          "Out of bound access of counters");
17060b57cec5SDimitry Andric   uint64_t SCounts[2];
17070b57cec5SDimitry Andric   SCounts[0] = CountFromProfile[*CurCtrIdx]; // True count
17080b57cec5SDimitry Andric   ++(*CurCtrIdx);
17090b57cec5SDimitry Andric   uint64_t TotalCount = 0;
17100b57cec5SDimitry Andric   auto BI = UseFunc->findBBInfo(SI.getParent());
17110b57cec5SDimitry Andric   if (BI != nullptr)
17120fca6ea1SDimitry Andric     TotalCount = *BI->Count;
17130b57cec5SDimitry Andric   // False Count
17140b57cec5SDimitry Andric   SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0);
17150b57cec5SDimitry Andric   uint64_t MaxCount = std::max(SCounts[0], SCounts[1]);
17160b57cec5SDimitry Andric   if (MaxCount)
17170b57cec5SDimitry Andric     setProfMetadata(F.getParent(), &SI, SCounts, MaxCount);
17180b57cec5SDimitry Andric }
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
172106c3fb27SDimitry Andric   if (!PGOInstrSelect || PGOFunctionEntryCoverage || HasSingleByteCoverage)
17220b57cec5SDimitry Andric     return;
17230b57cec5SDimitry Andric   // FIXME: do not handle this yet.
17240b57cec5SDimitry Andric   if (SI.getCondition()->getType()->isVectorTy())
17250b57cec5SDimitry Andric     return;
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric   switch (Mode) {
17280b57cec5SDimitry Andric   case VM_counting:
17290b57cec5SDimitry Andric     NSIs++;
17300b57cec5SDimitry Andric     return;
17310b57cec5SDimitry Andric   case VM_instrument:
17320b57cec5SDimitry Andric     instrumentOneSelectInst(SI);
17330b57cec5SDimitry Andric     return;
17340b57cec5SDimitry Andric   case VM_annotate:
17350b57cec5SDimitry Andric     annotateOneSelectInst(SI);
17360b57cec5SDimitry Andric     return;
17370b57cec5SDimitry Andric   }
17380b57cec5SDimitry Andric 
17390b57cec5SDimitry Andric   llvm_unreachable("Unknown visiting mode");
17400b57cec5SDimitry Andric }
17410b57cec5SDimitry Andric 
17420fca6ea1SDimitry Andric static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind) {
17430fca6ea1SDimitry Andric   if (ValueProfKind == IPVK_MemOPSize)
17440fca6ea1SDimitry Andric     return MaxNumMemOPAnnotations;
17450fca6ea1SDimitry Andric   if (ValueProfKind == llvm::IPVK_VTableTarget)
17460fca6ea1SDimitry Andric     return MaxNumVTableAnnotations;
17470fca6ea1SDimitry Andric   return MaxNumAnnotations;
17480fca6ea1SDimitry Andric }
17490fca6ea1SDimitry Andric 
17500b57cec5SDimitry Andric // Traverse all valuesites and annotate the instructions for all value kind.
17510b57cec5SDimitry Andric void PGOUseFunc::annotateValueSites() {
17520fca6ea1SDimitry Andric   if (isValueProfilingDisabled())
17530b57cec5SDimitry Andric     return;
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric   // Create the PGOFuncName meta data.
17560b57cec5SDimitry Andric   createPGOFuncNameMetadata(F, FuncInfo.FuncName);
17570b57cec5SDimitry Andric 
17580b57cec5SDimitry Andric   for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
17590b57cec5SDimitry Andric     annotateValueSites(Kind);
17600b57cec5SDimitry Andric }
17610b57cec5SDimitry Andric 
17620b57cec5SDimitry Andric // Annotate the instructions for a specific value kind.
17630b57cec5SDimitry Andric void PGOUseFunc::annotateValueSites(uint32_t Kind) {
17640b57cec5SDimitry Andric   assert(Kind <= IPVK_Last);
17650b57cec5SDimitry Andric   unsigned ValueSiteIndex = 0;
17660fca6ea1SDimitry Andric 
17670b57cec5SDimitry Andric   unsigned NumValueSites = ProfileRecord.getNumValueSites(Kind);
17680fca6ea1SDimitry Andric 
17690fca6ea1SDimitry Andric   // Since there isn't a reliable or fast way for profile reader to tell if a
17700fca6ea1SDimitry Andric   // profile is generated with `-enable-vtable-value-profiling` on, we run the
17710fca6ea1SDimitry Andric   // value profile collector over the function IR to find the instrumented sites
17720fca6ea1SDimitry Andric   // iff function profile records shows the number of instrumented vtable sites
17730fca6ea1SDimitry Andric   // is not zero. Function cfg already takes the number of instrumented
17740fca6ea1SDimitry Andric   // indirect call sites into account so it doesn't hash the number of
17750fca6ea1SDimitry Andric   // instrumented vtables; as a side effect it makes it easier to enable
17760fca6ea1SDimitry Andric   // profiling and profile use in two steps if needed.
17770fca6ea1SDimitry Andric   // TODO: Remove this if/when -enable-vtable-value-profiling is on by default.
17780fca6ea1SDimitry Andric   if (NumValueSites > 0 && Kind == IPVK_VTableTarget &&
17790fca6ea1SDimitry Andric       NumValueSites != FuncInfo.ValueSites[IPVK_VTableTarget].size() &&
17800fca6ea1SDimitry Andric       MaxNumVTableAnnotations != 0)
17810fca6ea1SDimitry Andric     FuncInfo.ValueSites[IPVK_VTableTarget] = VPC.get(IPVK_VTableTarget);
17820fca6ea1SDimitry Andric   auto &ValueSites = FuncInfo.ValueSites[Kind];
17830b57cec5SDimitry Andric   if (NumValueSites != ValueSites.size()) {
17840b57cec5SDimitry Andric     auto &Ctx = M->getContext();
17850b57cec5SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(
17860b57cec5SDimitry Andric         M->getName().data(),
17870b57cec5SDimitry Andric         Twine("Inconsistent number of value sites for ") +
178806c3fb27SDimitry Andric             Twine(ValueProfKindDescr[Kind]) + Twine(" profiling in \"") +
178906c3fb27SDimitry Andric             F.getName().str() +
17900b57cec5SDimitry Andric             Twine("\", possibly due to the use of a stale profile."),
17910b57cec5SDimitry Andric         DS_Warning));
17920b57cec5SDimitry Andric     return;
17930b57cec5SDimitry Andric   }
17940b57cec5SDimitry Andric 
17958bcb0991SDimitry Andric   for (VPCandidateInfo &I : ValueSites) {
17960b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Read one value site profile (kind = " << Kind
17970b57cec5SDimitry Andric                       << "): Index = " << ValueSiteIndex << " out of "
17980b57cec5SDimitry Andric                       << NumValueSites << "\n");
17990fca6ea1SDimitry Andric     annotateValueSite(
18000fca6ea1SDimitry Andric         *M, *I.AnnotatedInst, ProfileRecord,
18010b57cec5SDimitry Andric         static_cast<InstrProfValueKind>(Kind), ValueSiteIndex,
18020fca6ea1SDimitry Andric         getMaxNumAnnotations(static_cast<InstrProfValueKind>(Kind)));
18030b57cec5SDimitry Andric     ValueSiteIndex++;
18040b57cec5SDimitry Andric   }
18050b57cec5SDimitry Andric }
18060b57cec5SDimitry Andric 
18070b57cec5SDimitry Andric // Collect the set of members for each Comdat in module M and store
18080b57cec5SDimitry Andric // in ComdatMembers.
18090b57cec5SDimitry Andric static void collectComdatMembers(
18100b57cec5SDimitry Andric     Module &M,
18110b57cec5SDimitry Andric     std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers) {
18120b57cec5SDimitry Andric   if (!DoComdatRenaming)
18130b57cec5SDimitry Andric     return;
18140b57cec5SDimitry Andric   for (Function &F : M)
18150b57cec5SDimitry Andric     if (Comdat *C = F.getComdat())
18160b57cec5SDimitry Andric       ComdatMembers.insert(std::make_pair(C, &F));
18170b57cec5SDimitry Andric   for (GlobalVariable &GV : M.globals())
18180b57cec5SDimitry Andric     if (Comdat *C = GV.getComdat())
18190b57cec5SDimitry Andric       ComdatMembers.insert(std::make_pair(C, &GV));
18200b57cec5SDimitry Andric   for (GlobalAlias &GA : M.aliases())
18210b57cec5SDimitry Andric     if (Comdat *C = GA.getComdat())
18220b57cec5SDimitry Andric       ComdatMembers.insert(std::make_pair(C, &GA));
18230b57cec5SDimitry Andric }
18240b57cec5SDimitry Andric 
18255f757f3fSDimitry Andric // Return true if we should not find instrumentation data for this function
18265f757f3fSDimitry Andric static bool skipPGOUse(const Function &F) {
1827bdd1243dSDimitry Andric   if (F.isDeclaration())
1828bdd1243dSDimitry Andric     return true;
1829bdd1243dSDimitry Andric   // If there are too many critical edges, PGO might cause
1830bdd1243dSDimitry Andric   // compiler time problem. Skip PGO if the number of
1831bdd1243dSDimitry Andric   // critical edges execeed the threshold.
1832bdd1243dSDimitry Andric   unsigned NumCriticalEdges = 0;
1833bdd1243dSDimitry Andric   for (auto &BB : F) {
1834bdd1243dSDimitry Andric     const Instruction *TI = BB.getTerminator();
1835bdd1243dSDimitry Andric     for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
1836bdd1243dSDimitry Andric       if (isCriticalEdge(TI, I))
1837bdd1243dSDimitry Andric         NumCriticalEdges++;
1838bdd1243dSDimitry Andric     }
1839bdd1243dSDimitry Andric   }
1840bdd1243dSDimitry Andric   if (NumCriticalEdges > PGOFunctionCriticalEdgeThreshold) {
1841bdd1243dSDimitry Andric     LLVM_DEBUG(dbgs() << "In func " << F.getName()
1842bdd1243dSDimitry Andric                       << ", NumCriticalEdges=" << NumCriticalEdges
1843bdd1243dSDimitry Andric                       << " exceed the threshold. Skip PGO.\n");
1844bdd1243dSDimitry Andric     return true;
1845bdd1243dSDimitry Andric   }
18465f757f3fSDimitry Andric   return false;
18475f757f3fSDimitry Andric }
1848bdd1243dSDimitry Andric 
18495f757f3fSDimitry Andric // Return true if we should not instrument this function
18505f757f3fSDimitry Andric static bool skipPGOGen(const Function &F) {
18515f757f3fSDimitry Andric   if (skipPGOUse(F))
18525f757f3fSDimitry Andric     return true;
18535f757f3fSDimitry Andric   if (F.hasFnAttribute(llvm::Attribute::Naked))
18545f757f3fSDimitry Andric     return true;
18555f757f3fSDimitry Andric   if (F.hasFnAttribute(llvm::Attribute::NoProfile))
18565f757f3fSDimitry Andric     return true;
18575f757f3fSDimitry Andric   if (F.hasFnAttribute(llvm::Attribute::SkipProfile))
18585f757f3fSDimitry Andric     return true;
18595f757f3fSDimitry Andric   if (F.getInstructionCount() < PGOFunctionSizeThreshold)
18605f757f3fSDimitry Andric     return true;
1861bdd1243dSDimitry Andric   return false;
1862bdd1243dSDimitry Andric }
1863bdd1243dSDimitry Andric 
18640b57cec5SDimitry Andric static bool InstrumentAllFunctions(
18655ffd83dbSDimitry Andric     Module &M, function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
18665ffd83dbSDimitry Andric     function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
18670b57cec5SDimitry Andric     function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS) {
18680b57cec5SDimitry Andric   // For the context-sensitve instrumentation, we should have a separated pass
18690b57cec5SDimitry Andric   // (before LTO/ThinLTO linking) to create these variables.
18700fca6ea1SDimitry Andric   if (!IsCS && !PGOCtxProfLoweringPass::isContextualIRPGOEnabled())
18711fd87a68SDimitry Andric     createIRLevelProfileFlagVar(M, /*IsCS=*/false);
18720fca6ea1SDimitry Andric 
18730fca6ea1SDimitry Andric   Triple TT(M.getTargetTriple());
18740fca6ea1SDimitry Andric   LLVMContext &Ctx = M.getContext();
18750fca6ea1SDimitry Andric   if (!TT.isOSBinFormatELF() && EnableVTableValueProfiling)
18760fca6ea1SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(
18770fca6ea1SDimitry Andric         M.getName().data(),
18780fca6ea1SDimitry Andric         Twine("VTable value profiling is presently not "
18790fca6ea1SDimitry Andric               "supported for non-ELF object formats"),
18800fca6ea1SDimitry Andric         DS_Warning));
18810b57cec5SDimitry Andric   std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
18820b57cec5SDimitry Andric   collectComdatMembers(M, ComdatMembers);
18830b57cec5SDimitry Andric 
18840b57cec5SDimitry Andric   for (auto &F : M) {
18855f757f3fSDimitry Andric     if (skipPGOGen(F))
1886e8d8bef9SDimitry Andric       continue;
18875ffd83dbSDimitry Andric     auto &TLI = LookupTLI(F);
18880b57cec5SDimitry Andric     auto *BPI = LookupBPI(F);
18890b57cec5SDimitry Andric     auto *BFI = LookupBFI(F);
18905ffd83dbSDimitry Andric     instrumentOneFunc(F, &M, TLI, BPI, BFI, ComdatMembers, IsCS);
18910b57cec5SDimitry Andric   }
18920b57cec5SDimitry Andric   return true;
18930b57cec5SDimitry Andric }
18940b57cec5SDimitry Andric 
18950b57cec5SDimitry Andric PreservedAnalyses
189606c3fb27SDimitry Andric PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &MAM) {
18970b57cec5SDimitry Andric   createProfileFileNameVar(M, CSInstrName);
1898349cc55cSDimitry Andric   // The variable in a comdat may be discarded by LTO. Ensure the declaration
1899349cc55cSDimitry Andric   // will be retained.
19001fd87a68SDimitry Andric   appendToCompilerUsed(M, createIRLevelProfileFlagVar(M, /*IsCS=*/true));
19010fca6ea1SDimitry Andric   if (ProfileSampling)
19020fca6ea1SDimitry Andric     createProfileSamplingVar(M);
190306c3fb27SDimitry Andric   PreservedAnalyses PA;
190406c3fb27SDimitry Andric   PA.preserve<FunctionAnalysisManagerModuleProxy>();
190506c3fb27SDimitry Andric   PA.preserveSet<AllAnalysesOn<Function>>();
190606c3fb27SDimitry Andric   return PA;
19070b57cec5SDimitry Andric }
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric PreservedAnalyses PGOInstrumentationGen::run(Module &M,
191006c3fb27SDimitry Andric                                              ModuleAnalysisManager &MAM) {
191106c3fb27SDimitry Andric   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
19125ffd83dbSDimitry Andric   auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
19135ffd83dbSDimitry Andric     return FAM.getResult<TargetLibraryAnalysis>(F);
19145ffd83dbSDimitry Andric   };
19150b57cec5SDimitry Andric   auto LookupBPI = [&FAM](Function &F) {
19160b57cec5SDimitry Andric     return &FAM.getResult<BranchProbabilityAnalysis>(F);
19170b57cec5SDimitry Andric   };
19180b57cec5SDimitry Andric   auto LookupBFI = [&FAM](Function &F) {
19190b57cec5SDimitry Andric     return &FAM.getResult<BlockFrequencyAnalysis>(F);
19200b57cec5SDimitry Andric   };
19210b57cec5SDimitry Andric 
19225ffd83dbSDimitry Andric   if (!InstrumentAllFunctions(M, LookupTLI, LookupBPI, LookupBFI, IsCS))
19230b57cec5SDimitry Andric     return PreservedAnalyses::all();
19240b57cec5SDimitry Andric 
19250b57cec5SDimitry Andric   return PreservedAnalyses::none();
19260b57cec5SDimitry Andric }
19270b57cec5SDimitry Andric 
1928e8d8bef9SDimitry Andric // Using the ratio b/w sums of profile count values and BFI count values to
1929e8d8bef9SDimitry Andric // adjust the func entry count.
1930e8d8bef9SDimitry Andric static void fixFuncEntryCount(PGOUseFunc &Func, LoopInfo &LI,
1931e8d8bef9SDimitry Andric                               BranchProbabilityInfo &NBPI) {
1932e8d8bef9SDimitry Andric   Function &F = Func.getFunc();
1933e8d8bef9SDimitry Andric   BlockFrequencyInfo NBFI(F, NBPI, LI);
1934e8d8bef9SDimitry Andric #ifndef NDEBUG
1935e8d8bef9SDimitry Andric   auto BFIEntryCount = F.getEntryCount();
193681ad6265SDimitry Andric   assert(BFIEntryCount && (BFIEntryCount->getCount() > 0) &&
1937e8d8bef9SDimitry Andric          "Invalid BFI Entrycount");
1938e8d8bef9SDimitry Andric #endif
1939e8d8bef9SDimitry Andric   auto SumCount = APFloat::getZero(APFloat::IEEEdouble());
1940e8d8bef9SDimitry Andric   auto SumBFICount = APFloat::getZero(APFloat::IEEEdouble());
1941e8d8bef9SDimitry Andric   for (auto &BBI : F) {
1942e8d8bef9SDimitry Andric     uint64_t CountValue = 0;
1943e8d8bef9SDimitry Andric     uint64_t BFICountValue = 0;
1944e8d8bef9SDimitry Andric     if (!Func.findBBInfo(&BBI))
1945e8d8bef9SDimitry Andric       continue;
1946e8d8bef9SDimitry Andric     auto BFICount = NBFI.getBlockProfileCount(&BBI);
19470fca6ea1SDimitry Andric     CountValue = *Func.getBBInfo(&BBI).Count;
194881ad6265SDimitry Andric     BFICountValue = *BFICount;
1949e8d8bef9SDimitry Andric     SumCount.add(APFloat(CountValue * 1.0), APFloat::rmNearestTiesToEven);
1950e8d8bef9SDimitry Andric     SumBFICount.add(APFloat(BFICountValue * 1.0), APFloat::rmNearestTiesToEven);
1951e8d8bef9SDimitry Andric   }
1952e8d8bef9SDimitry Andric   if (SumCount.isZero())
1953e8d8bef9SDimitry Andric     return;
1954e8d8bef9SDimitry Andric 
1955e8d8bef9SDimitry Andric   assert(SumBFICount.compare(APFloat(0.0)) == APFloat::cmpGreaterThan &&
1956e8d8bef9SDimitry Andric          "Incorrect sum of BFI counts");
1957e8d8bef9SDimitry Andric   if (SumBFICount.compare(SumCount) == APFloat::cmpEqual)
1958e8d8bef9SDimitry Andric     return;
1959e8d8bef9SDimitry Andric   double Scale = (SumCount / SumBFICount).convertToDouble();
1960e8d8bef9SDimitry Andric   if (Scale < 1.001 && Scale > 0.999)
1961e8d8bef9SDimitry Andric     return;
1962e8d8bef9SDimitry Andric 
19630fca6ea1SDimitry Andric   uint64_t FuncEntryCount = *Func.getBBInfo(&*F.begin()).Count;
1964e8d8bef9SDimitry Andric   uint64_t NewEntryCount = 0.5 + FuncEntryCount * Scale;
1965e8d8bef9SDimitry Andric   if (NewEntryCount == 0)
1966e8d8bef9SDimitry Andric     NewEntryCount = 1;
1967e8d8bef9SDimitry Andric   if (NewEntryCount != FuncEntryCount) {
1968e8d8bef9SDimitry Andric     F.setEntryCount(ProfileCount(NewEntryCount, Function::PCT_Real));
1969e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "FixFuncEntryCount: in " << F.getName()
1970e8d8bef9SDimitry Andric                       << ", entry_count " << FuncEntryCount << " --> "
1971e8d8bef9SDimitry Andric                       << NewEntryCount << "\n");
1972e8d8bef9SDimitry Andric   }
1973e8d8bef9SDimitry Andric }
1974e8d8bef9SDimitry Andric 
1975e8d8bef9SDimitry Andric // Compare the profile count values with BFI count values, and print out
1976e8d8bef9SDimitry Andric // the non-matching ones.
1977e8d8bef9SDimitry Andric static void verifyFuncBFI(PGOUseFunc &Func, LoopInfo &LI,
1978e8d8bef9SDimitry Andric                           BranchProbabilityInfo &NBPI,
1979e8d8bef9SDimitry Andric                           uint64_t HotCountThreshold,
1980e8d8bef9SDimitry Andric                           uint64_t ColdCountThreshold) {
1981e8d8bef9SDimitry Andric   Function &F = Func.getFunc();
1982e8d8bef9SDimitry Andric   BlockFrequencyInfo NBFI(F, NBPI, LI);
1983e8d8bef9SDimitry Andric   //  bool PrintFunc = false;
1984e8d8bef9SDimitry Andric   bool HotBBOnly = PGOVerifyHotBFI;
198506c3fb27SDimitry Andric   StringRef Msg;
1986e8d8bef9SDimitry Andric   OptimizationRemarkEmitter ORE(&F);
1987e8d8bef9SDimitry Andric 
1988e8d8bef9SDimitry Andric   unsigned BBNum = 0, BBMisMatchNum = 0, NonZeroBBNum = 0;
1989e8d8bef9SDimitry Andric   for (auto &BBI : F) {
1990e8d8bef9SDimitry Andric     uint64_t CountValue = 0;
1991e8d8bef9SDimitry Andric     uint64_t BFICountValue = 0;
1992e8d8bef9SDimitry Andric 
19930fca6ea1SDimitry Andric     CountValue = Func.getBBInfo(&BBI).Count.value_or(CountValue);
1994e8d8bef9SDimitry Andric 
1995e8d8bef9SDimitry Andric     BBNum++;
1996e8d8bef9SDimitry Andric     if (CountValue)
1997e8d8bef9SDimitry Andric       NonZeroBBNum++;
1998e8d8bef9SDimitry Andric     auto BFICount = NBFI.getBlockProfileCount(&BBI);
1999e8d8bef9SDimitry Andric     if (BFICount)
200081ad6265SDimitry Andric       BFICountValue = *BFICount;
2001e8d8bef9SDimitry Andric 
2002e8d8bef9SDimitry Andric     if (HotBBOnly) {
2003e8d8bef9SDimitry Andric       bool rawIsHot = CountValue >= HotCountThreshold;
2004e8d8bef9SDimitry Andric       bool BFIIsHot = BFICountValue >= HotCountThreshold;
2005e8d8bef9SDimitry Andric       bool rawIsCold = CountValue <= ColdCountThreshold;
2006e8d8bef9SDimitry Andric       bool ShowCount = false;
2007e8d8bef9SDimitry Andric       if (rawIsHot && !BFIIsHot) {
2008e8d8bef9SDimitry Andric         Msg = "raw-Hot to BFI-nonHot";
2009e8d8bef9SDimitry Andric         ShowCount = true;
2010e8d8bef9SDimitry Andric       } else if (rawIsCold && BFIIsHot) {
2011e8d8bef9SDimitry Andric         Msg = "raw-Cold to BFI-Hot";
2012e8d8bef9SDimitry Andric         ShowCount = true;
2013e8d8bef9SDimitry Andric       }
2014e8d8bef9SDimitry Andric       if (!ShowCount)
2015e8d8bef9SDimitry Andric         continue;
2016e8d8bef9SDimitry Andric     } else {
2017e8d8bef9SDimitry Andric       if ((CountValue < PGOVerifyBFICutoff) &&
2018e8d8bef9SDimitry Andric           (BFICountValue < PGOVerifyBFICutoff))
2019e8d8bef9SDimitry Andric         continue;
2020e8d8bef9SDimitry Andric       uint64_t Diff = (BFICountValue >= CountValue)
2021e8d8bef9SDimitry Andric                           ? BFICountValue - CountValue
2022e8d8bef9SDimitry Andric                           : CountValue - BFICountValue;
20230eae32dcSDimitry Andric       if (Diff <= CountValue / 100 * PGOVerifyBFIRatio)
2024e8d8bef9SDimitry Andric         continue;
2025e8d8bef9SDimitry Andric     }
2026e8d8bef9SDimitry Andric     BBMisMatchNum++;
2027e8d8bef9SDimitry Andric 
2028e8d8bef9SDimitry Andric     ORE.emit([&]() {
2029e8d8bef9SDimitry Andric       OptimizationRemarkAnalysis Remark(DEBUG_TYPE, "bfi-verify",
2030e8d8bef9SDimitry Andric                                         F.getSubprogram(), &BBI);
2031e8d8bef9SDimitry Andric       Remark << "BB " << ore::NV("Block", BBI.getName())
2032e8d8bef9SDimitry Andric              << " Count=" << ore::NV("Count", CountValue)
2033e8d8bef9SDimitry Andric              << " BFI_Count=" << ore::NV("Count", BFICountValue);
2034e8d8bef9SDimitry Andric       if (!Msg.empty())
2035e8d8bef9SDimitry Andric         Remark << " (" << Msg << ")";
2036e8d8bef9SDimitry Andric       return Remark;
2037e8d8bef9SDimitry Andric     });
2038e8d8bef9SDimitry Andric   }
2039e8d8bef9SDimitry Andric   if (BBMisMatchNum)
2040e8d8bef9SDimitry Andric     ORE.emit([&]() {
2041e8d8bef9SDimitry Andric       return OptimizationRemarkAnalysis(DEBUG_TYPE, "bfi-verify",
2042e8d8bef9SDimitry Andric                                         F.getSubprogram(), &F.getEntryBlock())
2043e8d8bef9SDimitry Andric              << "In Func " << ore::NV("Function", F.getName())
2044e8d8bef9SDimitry Andric              << ": Num_of_BB=" << ore::NV("Count", BBNum)
2045e8d8bef9SDimitry Andric              << ", Num_of_non_zerovalue_BB=" << ore::NV("Count", NonZeroBBNum)
2046e8d8bef9SDimitry Andric              << ", Num_of_mis_matching_BB=" << ore::NV("Count", BBMisMatchNum);
2047e8d8bef9SDimitry Andric     });
2048e8d8bef9SDimitry Andric }
2049e8d8bef9SDimitry Andric 
20500b57cec5SDimitry Andric static bool annotateAllFunctions(
20510b57cec5SDimitry Andric     Module &M, StringRef ProfileFileName, StringRef ProfileRemappingFileName,
205206c3fb27SDimitry Andric     vfs::FileSystem &FS,
20535ffd83dbSDimitry Andric     function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
20540b57cec5SDimitry Andric     function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
20558bcb0991SDimitry Andric     function_ref<BlockFrequencyInfo *(Function &)> LookupBFI,
20568bcb0991SDimitry Andric     ProfileSummaryInfo *PSI, bool IsCS) {
20570b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Read in profile counters: ");
20580b57cec5SDimitry Andric   auto &Ctx = M.getContext();
20590b57cec5SDimitry Andric   // Read the counter array from file.
206006c3fb27SDimitry Andric   auto ReaderOrErr = IndexedInstrProfReader::create(ProfileFileName, FS,
206106c3fb27SDimitry Andric                                                     ProfileRemappingFileName);
20620b57cec5SDimitry Andric   if (Error E = ReaderOrErr.takeError()) {
20630b57cec5SDimitry Andric     handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
20640b57cec5SDimitry Andric       Ctx.diagnose(
20650b57cec5SDimitry Andric           DiagnosticInfoPGOProfile(ProfileFileName.data(), EI.message()));
20660b57cec5SDimitry Andric     });
20670b57cec5SDimitry Andric     return false;
20680b57cec5SDimitry Andric   }
20690b57cec5SDimitry Andric 
20700b57cec5SDimitry Andric   std::unique_ptr<IndexedInstrProfReader> PGOReader =
20710b57cec5SDimitry Andric       std::move(ReaderOrErr.get());
20720b57cec5SDimitry Andric   if (!PGOReader) {
20730b57cec5SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(ProfileFileName.data(),
20740b57cec5SDimitry Andric                                           StringRef("Cannot get PGOReader")));
20750b57cec5SDimitry Andric     return false;
20760b57cec5SDimitry Andric   }
20770b57cec5SDimitry Andric   if (!PGOReader->hasCSIRLevelProfile() && IsCS)
20780b57cec5SDimitry Andric     return false;
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric   // TODO: might need to change the warning once the clang option is finalized.
208106c3fb27SDimitry Andric   if (!PGOReader->isIRLevelProfile()) {
20820b57cec5SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(
20830b57cec5SDimitry Andric         ProfileFileName.data(), "Not an IR level instrumentation profile"));
20840b57cec5SDimitry Andric     return false;
20850b57cec5SDimitry Andric   }
20861fd87a68SDimitry Andric   if (PGOReader->functionEntryOnly()) {
20871fd87a68SDimitry Andric     Ctx.diagnose(DiagnosticInfoPGOProfile(
20881fd87a68SDimitry Andric         ProfileFileName.data(),
20891fd87a68SDimitry Andric         "Function entry profiles are not yet supported for optimization"));
20901fd87a68SDimitry Andric     return false;
20911fd87a68SDimitry Andric   }
20920b57cec5SDimitry Andric 
20930fca6ea1SDimitry Andric   if (EnableVTableProfileUse) {
20940fca6ea1SDimitry Andric     for (GlobalVariable &G : M.globals()) {
20950fca6ea1SDimitry Andric       if (!G.hasName() || !G.hasMetadata(LLVMContext::MD_type))
20960fca6ea1SDimitry Andric         continue;
20970fca6ea1SDimitry Andric 
20980fca6ea1SDimitry Andric       // Create the PGOFuncName meta data.
20990fca6ea1SDimitry Andric       createPGONameMetadata(G, getPGOName(G, false /* InLTO*/));
21000fca6ea1SDimitry Andric     }
21010fca6ea1SDimitry Andric   }
21020fca6ea1SDimitry Andric 
21038bcb0991SDimitry Andric   // Add the profile summary (read from the header of the indexed summary) here
21048bcb0991SDimitry Andric   // so that we can use it below when reading counters (which checks if the
21058bcb0991SDimitry Andric   // function should be marked with a cold or inlinehint attribute).
21068bcb0991SDimitry Andric   M.setProfileSummary(PGOReader->getSummary(IsCS).getMD(M.getContext()),
21078bcb0991SDimitry Andric                       IsCS ? ProfileSummary::PSK_CSInstr
21088bcb0991SDimitry Andric                            : ProfileSummary::PSK_Instr);
21095ffd83dbSDimitry Andric   PSI->refresh();
21108bcb0991SDimitry Andric 
21110b57cec5SDimitry Andric   std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
21120b57cec5SDimitry Andric   collectComdatMembers(M, ComdatMembers);
21130b57cec5SDimitry Andric   std::vector<Function *> HotFunctions;
21140b57cec5SDimitry Andric   std::vector<Function *> ColdFunctions;
2115e8d8bef9SDimitry Andric 
2116e8d8bef9SDimitry Andric   // If the profile marked as always instrument the entry BB, do the
2117e8d8bef9SDimitry Andric   // same. Note this can be overwritten by the internal option in CFGMST.h
2118e8d8bef9SDimitry Andric   bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled();
2119e8d8bef9SDimitry Andric   if (PGOInstrumentEntry.getNumOccurrences() > 0)
2120e8d8bef9SDimitry Andric     InstrumentFuncEntry = PGOInstrumentEntry;
21210fca6ea1SDimitry Andric   InstrumentFuncEntry |= PGOCtxProfLoweringPass::isContextualIRPGOEnabled();
21220fca6ea1SDimitry Andric 
212306c3fb27SDimitry Andric   bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage();
21240b57cec5SDimitry Andric   for (auto &F : M) {
21255f757f3fSDimitry Andric     if (skipPGOUse(F))
21260b57cec5SDimitry Andric       continue;
21275ffd83dbSDimitry Andric     auto &TLI = LookupTLI(F);
21280b57cec5SDimitry Andric     auto *BPI = LookupBPI(F);
21290b57cec5SDimitry Andric     auto *BFI = LookupBFI(F);
213006c3fb27SDimitry Andric     if (!HasSingleByteCoverage) {
213106c3fb27SDimitry Andric       // Split indirectbr critical edges here before computing the MST rather
213206c3fb27SDimitry Andric       // than later in getInstrBB() to avoid invalidating it.
213306c3fb27SDimitry Andric       SplitIndirectBrCriticalEdges(F, /*IgnoreBlocksWithoutPHI=*/false, BPI,
213406c3fb27SDimitry Andric                                    BFI);
213506c3fb27SDimitry Andric     }
2136e8d8bef9SDimitry Andric     PGOUseFunc Func(F, &M, TLI, ComdatMembers, BPI, BFI, PSI, IsCS,
213706c3fb27SDimitry Andric                     InstrumentFuncEntry, HasSingleByteCoverage);
213806c3fb27SDimitry Andric     if (HasSingleByteCoverage) {
213906c3fb27SDimitry Andric       Func.populateCoverage(PGOReader.get());
2140bdd1243dSDimitry Andric       continue;
214106c3fb27SDimitry Andric     }
2142bdd1243dSDimitry Andric     // When PseudoKind is set to a vaule other than InstrProfRecord::NotPseudo,
2143bdd1243dSDimitry Andric     // it means the profile for the function is unrepresentative and this
2144bdd1243dSDimitry Andric     // function is actually hot / warm. We will reset the function hot / cold
2145bdd1243dSDimitry Andric     // attribute and drop all the profile counters.
2146bdd1243dSDimitry Andric     InstrProfRecord::CountPseudoKind PseudoKind = InstrProfRecord::NotPseudo;
21470b57cec5SDimitry Andric     bool AllZeros = false;
2148bdd1243dSDimitry Andric     if (!Func.readCounters(PGOReader.get(), AllZeros, PseudoKind))
21490b57cec5SDimitry Andric       continue;
21500b57cec5SDimitry Andric     if (AllZeros) {
21510b57cec5SDimitry Andric       F.setEntryCount(ProfileCount(0, Function::PCT_Real));
21520b57cec5SDimitry Andric       if (Func.getProgramMaxCount() != 0)
21530b57cec5SDimitry Andric         ColdFunctions.push_back(&F);
21540b57cec5SDimitry Andric       continue;
21550b57cec5SDimitry Andric     }
2156bdd1243dSDimitry Andric     if (PseudoKind != InstrProfRecord::NotPseudo) {
2157bdd1243dSDimitry Andric       // Clear function attribute cold.
2158bdd1243dSDimitry Andric       if (F.hasFnAttribute(Attribute::Cold))
2159bdd1243dSDimitry Andric         F.removeFnAttr(Attribute::Cold);
2160bdd1243dSDimitry Andric       // Set function attribute as hot.
2161bdd1243dSDimitry Andric       if (PseudoKind == InstrProfRecord::PseudoHot)
2162bdd1243dSDimitry Andric         F.addFnAttr(Attribute::Hot);
2163e8d8bef9SDimitry Andric       continue;
2164e8d8bef9SDimitry Andric     }
21650b57cec5SDimitry Andric     Func.populateCounters();
21660b57cec5SDimitry Andric     Func.setBranchWeights();
21670b57cec5SDimitry Andric     Func.annotateValueSites();
21680b57cec5SDimitry Andric     Func.annotateIrrLoopHeaderWeights();
21690b57cec5SDimitry Andric     PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
21700b57cec5SDimitry Andric     if (FreqAttr == PGOUseFunc::FFA_Cold)
21710b57cec5SDimitry Andric       ColdFunctions.push_back(&F);
21720b57cec5SDimitry Andric     else if (FreqAttr == PGOUseFunc::FFA_Hot)
21730b57cec5SDimitry Andric       HotFunctions.push_back(&F);
21740b57cec5SDimitry Andric     if (PGOViewCounts != PGOVCT_None &&
21750b57cec5SDimitry Andric         (ViewBlockFreqFuncName.empty() ||
21760fca6ea1SDimitry Andric          F.getName() == ViewBlockFreqFuncName)) {
21770b57cec5SDimitry Andric       LoopInfo LI{DominatorTree(F)};
21780b57cec5SDimitry Andric       std::unique_ptr<BranchProbabilityInfo> NewBPI =
21798bcb0991SDimitry Andric           std::make_unique<BranchProbabilityInfo>(F, LI);
21800b57cec5SDimitry Andric       std::unique_ptr<BlockFrequencyInfo> NewBFI =
21818bcb0991SDimitry Andric           std::make_unique<BlockFrequencyInfo>(F, *NewBPI, LI);
21820b57cec5SDimitry Andric       if (PGOViewCounts == PGOVCT_Graph)
21830b57cec5SDimitry Andric         NewBFI->view();
21840b57cec5SDimitry Andric       else if (PGOViewCounts == PGOVCT_Text) {
21850b57cec5SDimitry Andric         dbgs() << "pgo-view-counts: " << Func.getFunc().getName() << "\n";
21860b57cec5SDimitry Andric         NewBFI->print(dbgs());
21870b57cec5SDimitry Andric       }
21880b57cec5SDimitry Andric     }
21890b57cec5SDimitry Andric     if (PGOViewRawCounts != PGOVCT_None &&
21900b57cec5SDimitry Andric         (ViewBlockFreqFuncName.empty() ||
21910fca6ea1SDimitry Andric          F.getName() == ViewBlockFreqFuncName)) {
21920b57cec5SDimitry Andric       if (PGOViewRawCounts == PGOVCT_Graph)
21930b57cec5SDimitry Andric         if (ViewBlockFreqFuncName.empty())
21940b57cec5SDimitry Andric           WriteGraph(&Func, Twine("PGORawCounts_") + Func.getFunc().getName());
21950b57cec5SDimitry Andric         else
21960b57cec5SDimitry Andric           ViewGraph(&Func, Twine("PGORawCounts_") + Func.getFunc().getName());
21970b57cec5SDimitry Andric       else if (PGOViewRawCounts == PGOVCT_Text) {
21980b57cec5SDimitry Andric         dbgs() << "pgo-view-raw-counts: " << Func.getFunc().getName() << "\n";
21990b57cec5SDimitry Andric         Func.dumpInfo();
22000b57cec5SDimitry Andric       }
22010b57cec5SDimitry Andric     }
2202e8d8bef9SDimitry Andric 
2203e8d8bef9SDimitry Andric     if (PGOVerifyBFI || PGOVerifyHotBFI || PGOFixEntryCount) {
2204e8d8bef9SDimitry Andric       LoopInfo LI{DominatorTree(F)};
2205e8d8bef9SDimitry Andric       BranchProbabilityInfo NBPI(F, LI);
2206e8d8bef9SDimitry Andric 
2207e8d8bef9SDimitry Andric       // Fix func entry count.
2208e8d8bef9SDimitry Andric       if (PGOFixEntryCount)
2209e8d8bef9SDimitry Andric         fixFuncEntryCount(Func, LI, NBPI);
2210e8d8bef9SDimitry Andric 
2211e8d8bef9SDimitry Andric       // Verify BlockFrequency information.
2212e8d8bef9SDimitry Andric       uint64_t HotCountThreshold = 0, ColdCountThreshold = 0;
2213e8d8bef9SDimitry Andric       if (PGOVerifyHotBFI) {
2214e8d8bef9SDimitry Andric         HotCountThreshold = PSI->getOrCompHotCountThreshold();
2215e8d8bef9SDimitry Andric         ColdCountThreshold = PSI->getOrCompColdCountThreshold();
2216e8d8bef9SDimitry Andric       }
2217e8d8bef9SDimitry Andric       verifyFuncBFI(Func, LI, NBPI, HotCountThreshold, ColdCountThreshold);
2218e8d8bef9SDimitry Andric     }
22190b57cec5SDimitry Andric   }
22200b57cec5SDimitry Andric 
22210b57cec5SDimitry Andric   // Set function hotness attribute from the profile.
22220b57cec5SDimitry Andric   // We have to apply these attributes at the end because their presence
22230b57cec5SDimitry Andric   // can affect the BranchProbabilityInfo of any callers, resulting in an
22240b57cec5SDimitry Andric   // inconsistent MST between prof-gen and prof-use.
22250b57cec5SDimitry Andric   for (auto &F : HotFunctions) {
22260b57cec5SDimitry Andric     F->addFnAttr(Attribute::InlineHint);
22270b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Set inline attribute to function: " << F->getName()
22280b57cec5SDimitry Andric                       << "\n");
22290b57cec5SDimitry Andric   }
22300b57cec5SDimitry Andric   for (auto &F : ColdFunctions) {
2231e8d8bef9SDimitry Andric     // Only set when there is no Attribute::Hot set by the user. For Hot
2232e8d8bef9SDimitry Andric     // attribute, user's annotation has the precedence over the profile.
2233e8d8bef9SDimitry Andric     if (F->hasFnAttribute(Attribute::Hot)) {
2234e8d8bef9SDimitry Andric       auto &Ctx = M.getContext();
2235e8d8bef9SDimitry Andric       std::string Msg = std::string("Function ") + F->getName().str() +
2236e8d8bef9SDimitry Andric                         std::string(" is annotated as a hot function but"
2237e8d8bef9SDimitry Andric                                     " the profile is cold");
2238e8d8bef9SDimitry Andric       Ctx.diagnose(
2239e8d8bef9SDimitry Andric           DiagnosticInfoPGOProfile(M.getName().data(), Msg, DS_Warning));
2240e8d8bef9SDimitry Andric       continue;
2241e8d8bef9SDimitry Andric     }
22420b57cec5SDimitry Andric     F->addFnAttr(Attribute::Cold);
22430b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Set cold attribute to function: " << F->getName()
22440b57cec5SDimitry Andric                       << "\n");
22450b57cec5SDimitry Andric   }
22460b57cec5SDimitry Andric   return true;
22470b57cec5SDimitry Andric }
22480b57cec5SDimitry Andric 
224906c3fb27SDimitry Andric PGOInstrumentationUse::PGOInstrumentationUse(
225006c3fb27SDimitry Andric     std::string Filename, std::string RemappingFilename, bool IsCS,
225106c3fb27SDimitry Andric     IntrusiveRefCntPtr<vfs::FileSystem> VFS)
22520b57cec5SDimitry Andric     : ProfileFileName(std::move(Filename)),
225306c3fb27SDimitry Andric       ProfileRemappingFileName(std::move(RemappingFilename)), IsCS(IsCS),
225406c3fb27SDimitry Andric       FS(std::move(VFS)) {
22550b57cec5SDimitry Andric   if (!PGOTestProfileFile.empty())
22560b57cec5SDimitry Andric     ProfileFileName = PGOTestProfileFile;
22570b57cec5SDimitry Andric   if (!PGOTestProfileRemappingFile.empty())
22580b57cec5SDimitry Andric     ProfileRemappingFileName = PGOTestProfileRemappingFile;
225906c3fb27SDimitry Andric   if (!FS)
226006c3fb27SDimitry Andric     FS = vfs::getRealFileSystem();
22610b57cec5SDimitry Andric }
22620b57cec5SDimitry Andric 
22630b57cec5SDimitry Andric PreservedAnalyses PGOInstrumentationUse::run(Module &M,
226406c3fb27SDimitry Andric                                              ModuleAnalysisManager &MAM) {
22650b57cec5SDimitry Andric 
226606c3fb27SDimitry Andric   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
22675ffd83dbSDimitry Andric   auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
22685ffd83dbSDimitry Andric     return FAM.getResult<TargetLibraryAnalysis>(F);
22695ffd83dbSDimitry Andric   };
22700b57cec5SDimitry Andric   auto LookupBPI = [&FAM](Function &F) {
22710b57cec5SDimitry Andric     return &FAM.getResult<BranchProbabilityAnalysis>(F);
22720b57cec5SDimitry Andric   };
22730b57cec5SDimitry Andric   auto LookupBFI = [&FAM](Function &F) {
22740b57cec5SDimitry Andric     return &FAM.getResult<BlockFrequencyAnalysis>(F);
22750b57cec5SDimitry Andric   };
22760b57cec5SDimitry Andric 
227706c3fb27SDimitry Andric   auto *PSI = &MAM.getResult<ProfileSummaryAnalysis>(M);
227806c3fb27SDimitry Andric   if (!annotateAllFunctions(M, ProfileFileName, ProfileRemappingFileName, *FS,
22795ffd83dbSDimitry Andric                             LookupTLI, LookupBPI, LookupBFI, PSI, IsCS))
22800b57cec5SDimitry Andric     return PreservedAnalyses::all();
22810b57cec5SDimitry Andric 
22820b57cec5SDimitry Andric   return PreservedAnalyses::none();
22830b57cec5SDimitry Andric }
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric static std::string getSimpleNodeName(const BasicBlock *Node) {
22860b57cec5SDimitry Andric   if (!Node->getName().empty())
228706c3fb27SDimitry Andric     return Node->getName().str();
22880b57cec5SDimitry Andric 
22890b57cec5SDimitry Andric   std::string SimpleNodeName;
22900b57cec5SDimitry Andric   raw_string_ostream OS(SimpleNodeName);
22910b57cec5SDimitry Andric   Node->printAsOperand(OS, false);
22920fca6ea1SDimitry Andric   return SimpleNodeName;
22930b57cec5SDimitry Andric }
22940b57cec5SDimitry Andric 
22950b57cec5SDimitry Andric void llvm::setProfMetadata(Module *M, Instruction *TI,
229606c3fb27SDimitry Andric                            ArrayRef<uint64_t> EdgeCounts, uint64_t MaxCount) {
22970b57cec5SDimitry Andric   assert(MaxCount > 0 && "Bad max count");
22980b57cec5SDimitry Andric   uint64_t Scale = calculateCountScale(MaxCount);
22990b57cec5SDimitry Andric   SmallVector<unsigned, 4> Weights;
23000b57cec5SDimitry Andric   for (const auto &ECI : EdgeCounts)
23010b57cec5SDimitry Andric     Weights.push_back(scaleBranchCount(ECI, Scale));
23020b57cec5SDimitry Andric 
23030b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Weight is: "; for (const auto &W
23040b57cec5SDimitry Andric                                            : Weights) {
23050b57cec5SDimitry Andric     dbgs() << W << " ";
23060b57cec5SDimitry Andric   } dbgs() << "\n";);
23078bcb0991SDimitry Andric 
230881ad6265SDimitry Andric   misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false);
230981ad6265SDimitry Andric 
23100fca6ea1SDimitry Andric   setBranchWeights(*TI, Weights, /*IsExpected=*/false);
23110b57cec5SDimitry Andric   if (EmitBranchProbability) {
23120b57cec5SDimitry Andric     std::string BrCondStr = getBranchCondString(TI);
23130b57cec5SDimitry Andric     if (BrCondStr.empty())
23140b57cec5SDimitry Andric       return;
23150b57cec5SDimitry Andric 
23160b57cec5SDimitry Andric     uint64_t WSum =
23170b57cec5SDimitry Andric         std::accumulate(Weights.begin(), Weights.end(), (uint64_t)0,
23180b57cec5SDimitry Andric                         [](uint64_t w1, uint64_t w2) { return w1 + w2; });
23190b57cec5SDimitry Andric     uint64_t TotalCount =
23200b57cec5SDimitry Andric         std::accumulate(EdgeCounts.begin(), EdgeCounts.end(), (uint64_t)0,
23210b57cec5SDimitry Andric                         [](uint64_t c1, uint64_t c2) { return c1 + c2; });
23220b57cec5SDimitry Andric     Scale = calculateCountScale(WSum);
23230b57cec5SDimitry Andric     BranchProbability BP(scaleBranchCount(Weights[0], Scale),
23240b57cec5SDimitry Andric                          scaleBranchCount(WSum, Scale));
23250b57cec5SDimitry Andric     std::string BranchProbStr;
23260b57cec5SDimitry Andric     raw_string_ostream OS(BranchProbStr);
23270b57cec5SDimitry Andric     OS << BP;
23280b57cec5SDimitry Andric     OS << " (total count : " << TotalCount << ")";
23290b57cec5SDimitry Andric     OS.flush();
23300b57cec5SDimitry Andric     Function *F = TI->getParent()->getParent();
23310b57cec5SDimitry Andric     OptimizationRemarkEmitter ORE(F);
23320b57cec5SDimitry Andric     ORE.emit([&]() {
23330b57cec5SDimitry Andric       return OptimizationRemark(DEBUG_TYPE, "pgo-instrumentation", TI)
23340b57cec5SDimitry Andric              << BrCondStr << " is true with probability : " << BranchProbStr;
23350b57cec5SDimitry Andric     });
23360b57cec5SDimitry Andric   }
23370b57cec5SDimitry Andric }
23380b57cec5SDimitry Andric 
23390b57cec5SDimitry Andric namespace llvm {
23400b57cec5SDimitry Andric 
23410b57cec5SDimitry Andric void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count) {
23420b57cec5SDimitry Andric   MDBuilder MDB(M->getContext());
23430b57cec5SDimitry Andric   TI->setMetadata(llvm::LLVMContext::MD_irr_loop,
23440b57cec5SDimitry Andric                   MDB.createIrrLoopHeaderWeight(Count));
23450b57cec5SDimitry Andric }
23460b57cec5SDimitry Andric 
23470b57cec5SDimitry Andric template <> struct GraphTraits<PGOUseFunc *> {
23480b57cec5SDimitry Andric   using NodeRef = const BasicBlock *;
23495ffd83dbSDimitry Andric   using ChildIteratorType = const_succ_iterator;
23500b57cec5SDimitry Andric   using nodes_iterator = pointer_iterator<Function::const_iterator>;
23510b57cec5SDimitry Andric 
23520b57cec5SDimitry Andric   static NodeRef getEntryNode(const PGOUseFunc *G) {
23530b57cec5SDimitry Andric     return &G->getFunc().front();
23540b57cec5SDimitry Andric   }
23550b57cec5SDimitry Andric 
23560b57cec5SDimitry Andric   static ChildIteratorType child_begin(const NodeRef N) {
23570b57cec5SDimitry Andric     return succ_begin(N);
23580b57cec5SDimitry Andric   }
23590b57cec5SDimitry Andric 
23600b57cec5SDimitry Andric   static ChildIteratorType child_end(const NodeRef N) { return succ_end(N); }
23610b57cec5SDimitry Andric 
23620b57cec5SDimitry Andric   static nodes_iterator nodes_begin(const PGOUseFunc *G) {
23630b57cec5SDimitry Andric     return nodes_iterator(G->getFunc().begin());
23640b57cec5SDimitry Andric   }
23650b57cec5SDimitry Andric 
23660b57cec5SDimitry Andric   static nodes_iterator nodes_end(const PGOUseFunc *G) {
23670b57cec5SDimitry Andric     return nodes_iterator(G->getFunc().end());
23680b57cec5SDimitry Andric   }
23690b57cec5SDimitry Andric };
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric template <> struct DOTGraphTraits<PGOUseFunc *> : DefaultDOTGraphTraits {
23720b57cec5SDimitry Andric   explicit DOTGraphTraits(bool isSimple = false)
23730b57cec5SDimitry Andric       : DefaultDOTGraphTraits(isSimple) {}
23740b57cec5SDimitry Andric 
23750b57cec5SDimitry Andric   static std::string getGraphName(const PGOUseFunc *G) {
23765ffd83dbSDimitry Andric     return std::string(G->getFunc().getName());
23770b57cec5SDimitry Andric   }
23780b57cec5SDimitry Andric 
23790b57cec5SDimitry Andric   std::string getNodeLabel(const BasicBlock *Node, const PGOUseFunc *Graph) {
23800b57cec5SDimitry Andric     std::string Result;
23810b57cec5SDimitry Andric     raw_string_ostream OS(Result);
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric     OS << getSimpleNodeName(Node) << ":\\l";
238406c3fb27SDimitry Andric     PGOUseBBInfo *BI = Graph->findBBInfo(Node);
23850b57cec5SDimitry Andric     OS << "Count : ";
23860fca6ea1SDimitry Andric     if (BI && BI->Count)
23870fca6ea1SDimitry Andric       OS << *BI->Count << "\\l";
23880b57cec5SDimitry Andric     else
23890b57cec5SDimitry Andric       OS << "Unknown\\l";
23900b57cec5SDimitry Andric 
23910b57cec5SDimitry Andric     if (!PGOInstrSelect)
23920b57cec5SDimitry Andric       return Result;
23930b57cec5SDimitry Andric 
2394fe6060f1SDimitry Andric     for (const Instruction &I : *Node) {
2395fe6060f1SDimitry Andric       if (!isa<SelectInst>(&I))
23960b57cec5SDimitry Andric         continue;
23970b57cec5SDimitry Andric       // Display scaled counts for SELECT instruction:
23980b57cec5SDimitry Andric       OS << "SELECT : { T = ";
23990b57cec5SDimitry Andric       uint64_t TC, FC;
2400bdd1243dSDimitry Andric       bool HasProf = extractBranchWeights(I, TC, FC);
24010b57cec5SDimitry Andric       if (!HasProf)
24020b57cec5SDimitry Andric         OS << "Unknown, F = Unknown }\\l";
24030b57cec5SDimitry Andric       else
24040b57cec5SDimitry Andric         OS << TC << ", F = " << FC << " }\\l";
24050b57cec5SDimitry Andric     }
24060b57cec5SDimitry Andric     return Result;
24070b57cec5SDimitry Andric   }
24080b57cec5SDimitry Andric };
24090b57cec5SDimitry Andric 
24100b57cec5SDimitry Andric } // end namespace llvm
2411