1ef512b99SJustin Bogner //===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===// 2ef512b99SJustin Bogner // 3ef512b99SJustin Bogner // The LLVM Compiler Infrastructure 4ef512b99SJustin Bogner // 5ef512b99SJustin Bogner // This file is distributed under the University of Illinois Open Source 6ef512b99SJustin Bogner // License. See LICENSE.TXT for details. 7ef512b99SJustin Bogner // 8ef512b99SJustin Bogner //===----------------------------------------------------------------------===// 9ef512b99SJustin Bogner // 10ef512b99SJustin Bogner // Instrumentation-based profile-guided optimization 11ef512b99SJustin Bogner // 12ef512b99SJustin Bogner //===----------------------------------------------------------------------===// 13ef512b99SJustin Bogner 14ef512b99SJustin Bogner #include "CodeGenPGO.h" 15ef512b99SJustin Bogner #include "CodeGenFunction.h" 16ef512b99SJustin Bogner #include "clang/AST/RecursiveASTVisitor.h" 17ef512b99SJustin Bogner #include "clang/AST/StmtVisitor.h" 18529f6dd8SJustin Bogner #include "llvm/Config/config.h" // for strtoull()/strtoll() define 19ef512b99SJustin Bogner #include "llvm/IR/MDBuilder.h" 20ef512b99SJustin Bogner #include "llvm/Support/FileSystem.h" 21ef512b99SJustin Bogner 22ef512b99SJustin Bogner using namespace clang; 23ef512b99SJustin Bogner using namespace CodeGen; 24ef512b99SJustin Bogner 25d66a17d0SJustin Bogner static void ReportBadPGOData(CodeGenModule &CGM, const char *Message) { 26d66a17d0SJustin Bogner DiagnosticsEngine &Diags = CGM.getDiags(); 27d66a17d0SJustin Bogner unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"); 28d66a17d0SJustin Bogner Diags.Report(diagID) << Message; 29d66a17d0SJustin Bogner } 30d66a17d0SJustin Bogner 31d66a17d0SJustin Bogner PGOProfileData::PGOProfileData(CodeGenModule &CGM, std::string Path) 32d66a17d0SJustin Bogner : CGM(CGM) { 33d66a17d0SJustin Bogner if (llvm::MemoryBuffer::getFile(Path, DataBuffer)) { 34d66a17d0SJustin Bogner ReportBadPGOData(CGM, "failed to open pgo data file"); 35d66a17d0SJustin Bogner return; 36d66a17d0SJustin Bogner } 37d66a17d0SJustin Bogner 38d66a17d0SJustin Bogner if (DataBuffer->getBufferSize() > std::numeric_limits<unsigned>::max()) { 39d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo data file too big"); 40d66a17d0SJustin Bogner return; 41d66a17d0SJustin Bogner } 42d66a17d0SJustin Bogner 43d66a17d0SJustin Bogner // Scan through the data file and map each function to the corresponding 44d66a17d0SJustin Bogner // file offset where its counts are stored. 45d66a17d0SJustin Bogner const char *BufferStart = DataBuffer->getBufferStart(); 46d66a17d0SJustin Bogner const char *BufferEnd = DataBuffer->getBufferEnd(); 47d66a17d0SJustin Bogner const char *CurPtr = BufferStart; 48d66a17d0SJustin Bogner uint64_t MaxCount = 0; 49d66a17d0SJustin Bogner while (CurPtr < BufferEnd) { 50d66a17d0SJustin Bogner // Read the function name. 51d66a17d0SJustin Bogner const char *FuncStart = CurPtr; 52d66a17d0SJustin Bogner // For Objective-C methods, the name may include whitespace, so search 53d66a17d0SJustin Bogner // backward from the end of the line to find the space that separates the 54d66a17d0SJustin Bogner // name from the number of counters. (This is a temporary hack since we are 55d66a17d0SJustin Bogner // going to completely replace this file format in the near future.) 56d66a17d0SJustin Bogner CurPtr = strchr(CurPtr, '\n'); 57d66a17d0SJustin Bogner if (!CurPtr) { 58d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo data file has malformed function entry"); 59d66a17d0SJustin Bogner return; 60d66a17d0SJustin Bogner } 61d66a17d0SJustin Bogner while (*--CurPtr != ' ') 62d66a17d0SJustin Bogner ; 63d66a17d0SJustin Bogner StringRef FuncName(FuncStart, CurPtr - FuncStart); 64d66a17d0SJustin Bogner 65d66a17d0SJustin Bogner // Read the number of counters. 66d66a17d0SJustin Bogner char *EndPtr; 67d66a17d0SJustin Bogner unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10); 68d66a17d0SJustin Bogner if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) { 69d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo data file has unexpected number of counters"); 70d66a17d0SJustin Bogner return; 71d66a17d0SJustin Bogner } 72d66a17d0SJustin Bogner CurPtr = EndPtr; 73d66a17d0SJustin Bogner 74d66a17d0SJustin Bogner // Read function count. 75d66a17d0SJustin Bogner uint64_t Count = strtoll(CurPtr, &EndPtr, 10); 76d66a17d0SJustin Bogner if (EndPtr == CurPtr || *EndPtr != '\n') { 77d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo-data file has bad count value"); 78d66a17d0SJustin Bogner return; 79d66a17d0SJustin Bogner } 80d66a17d0SJustin Bogner CurPtr = EndPtr; // Point to '\n'. 81d66a17d0SJustin Bogner FunctionCounts[FuncName] = Count; 82d66a17d0SJustin Bogner MaxCount = Count > MaxCount ? Count : MaxCount; 83d66a17d0SJustin Bogner 84d66a17d0SJustin Bogner // There is one line for each counter; skip over those lines. 85d66a17d0SJustin Bogner // Since function count is already read, we start the loop from 1. 86d66a17d0SJustin Bogner for (unsigned N = 1; N < NumCounters; ++N) { 87d66a17d0SJustin Bogner CurPtr = strchr(++CurPtr, '\n'); 88d66a17d0SJustin Bogner if (!CurPtr) { 89d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo data file is missing some counter info"); 90d66a17d0SJustin Bogner return; 91d66a17d0SJustin Bogner } 92d66a17d0SJustin Bogner } 93d66a17d0SJustin Bogner 94d66a17d0SJustin Bogner // Skip over the blank line separating functions. 95d66a17d0SJustin Bogner CurPtr += 2; 96d66a17d0SJustin Bogner 97d66a17d0SJustin Bogner DataOffsets[FuncName] = FuncStart - BufferStart; 98d66a17d0SJustin Bogner } 99d66a17d0SJustin Bogner MaxFunctionCount = MaxCount; 100d66a17d0SJustin Bogner } 101d66a17d0SJustin Bogner 102d66a17d0SJustin Bogner bool PGOProfileData::getFunctionCounts(StringRef FuncName, 103d66a17d0SJustin Bogner std::vector<uint64_t> &Counts) { 104d66a17d0SJustin Bogner // Find the relevant section of the pgo-data file. 105d66a17d0SJustin Bogner llvm::StringMap<unsigned>::const_iterator OffsetIter = 106d66a17d0SJustin Bogner DataOffsets.find(FuncName); 107d66a17d0SJustin Bogner if (OffsetIter == DataOffsets.end()) 108d66a17d0SJustin Bogner return true; 109d66a17d0SJustin Bogner const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue(); 110d66a17d0SJustin Bogner 111d66a17d0SJustin Bogner // Skip over the function name. 112d66a17d0SJustin Bogner CurPtr = strchr(CurPtr, '\n'); 113d66a17d0SJustin Bogner assert(CurPtr && "pgo-data has corrupted function entry"); 114d66a17d0SJustin Bogner while (*--CurPtr != ' ') 115d66a17d0SJustin Bogner ; 116d66a17d0SJustin Bogner 117d66a17d0SJustin Bogner // Read the number of counters. 118d66a17d0SJustin Bogner char *EndPtr; 119d66a17d0SJustin Bogner unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10); 120d66a17d0SJustin Bogner assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 && 121d66a17d0SJustin Bogner "pgo-data file has corrupted number of counters"); 122d66a17d0SJustin Bogner CurPtr = EndPtr; 123d66a17d0SJustin Bogner 124d66a17d0SJustin Bogner Counts.reserve(NumCounters); 125d66a17d0SJustin Bogner 126d66a17d0SJustin Bogner for (unsigned N = 0; N < NumCounters; ++N) { 127d66a17d0SJustin Bogner // Read the count value. 128d66a17d0SJustin Bogner uint64_t Count = strtoll(CurPtr, &EndPtr, 10); 129d66a17d0SJustin Bogner if (EndPtr == CurPtr || *EndPtr != '\n') { 130d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo-data file has bad count value"); 131d66a17d0SJustin Bogner return true; 132d66a17d0SJustin Bogner } 133d66a17d0SJustin Bogner Counts.push_back(Count); 134d66a17d0SJustin Bogner CurPtr = EndPtr + 1; 135d66a17d0SJustin Bogner } 136d66a17d0SJustin Bogner 137d66a17d0SJustin Bogner // Make sure the number of counters matches up. 138d66a17d0SJustin Bogner if (Counts.size() != NumCounters) { 139d66a17d0SJustin Bogner ReportBadPGOData(CGM, "pgo-data file has inconsistent counters"); 140d66a17d0SJustin Bogner return true; 141d66a17d0SJustin Bogner } 142d66a17d0SJustin Bogner 143d66a17d0SJustin Bogner return false; 144d66a17d0SJustin Bogner } 145d66a17d0SJustin Bogner 146da1ebedeSBob Wilson void CodeGenPGO::setFuncName(llvm::Function *Fn) { 147*2fe531cbSDuncan P. N. Exon Smith RawFuncName = Fn->getName(); 148da1ebedeSBob Wilson 149da1ebedeSBob Wilson // Function names may be prefixed with a binary '1' to indicate 150da1ebedeSBob Wilson // that the backend should not modify the symbols due to any platform 151da1ebedeSBob Wilson // naming convention. Do not include that '1' in the PGO profile name. 152*2fe531cbSDuncan P. N. Exon Smith if (RawFuncName[0] == '\1') 153*2fe531cbSDuncan P. N. Exon Smith RawFuncName = RawFuncName.substr(1); 154da1ebedeSBob Wilson 155da1ebedeSBob Wilson if (!Fn->hasLocalLinkage()) { 156*2fe531cbSDuncan P. N. Exon Smith PrefixedFuncName = new std::string(RawFuncName); 157da1ebedeSBob Wilson return; 158da1ebedeSBob Wilson } 159da1ebedeSBob Wilson 160da1ebedeSBob Wilson // For local symbols, prepend the main file name to distinguish them. 161da1ebedeSBob Wilson // Do not include the full path in the file name since there's no guarantee 162da1ebedeSBob Wilson // that it will stay the same, e.g., if the files are checked out from 163da1ebedeSBob Wilson // version control in different locations. 164*2fe531cbSDuncan P. N. Exon Smith PrefixedFuncName = new std::string(CGM.getCodeGenOpts().MainFileName); 165*2fe531cbSDuncan P. N. Exon Smith if (PrefixedFuncName->empty()) 166*2fe531cbSDuncan P. N. Exon Smith PrefixedFuncName->assign("<unknown>"); 167*2fe531cbSDuncan P. N. Exon Smith PrefixedFuncName->append(":"); 168*2fe531cbSDuncan P. N. Exon Smith PrefixedFuncName->append(RawFuncName); 169da1ebedeSBob Wilson } 170da1ebedeSBob Wilson 171*2fe531cbSDuncan P. N. Exon Smith static llvm::Function *getRegisterFunc(CodeGenModule &CGM) { 172*2fe531cbSDuncan P. N. Exon Smith return CGM.getModule().getFunction("__llvm_pgo_register_functions"); 173*2fe531cbSDuncan P. N. Exon Smith } 174*2fe531cbSDuncan P. N. Exon Smith 175*2fe531cbSDuncan P. N. Exon Smith static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) { 176*2fe531cbSDuncan P. N. Exon Smith // Only need to insert this once per module. 177*2fe531cbSDuncan P. N. Exon Smith if (llvm::Function *RegisterF = getRegisterFunc(CGM)) 178*2fe531cbSDuncan P. N. Exon Smith return &RegisterF->getEntryBlock(); 179*2fe531cbSDuncan P. N. Exon Smith 180*2fe531cbSDuncan P. N. Exon Smith // Construct the function. 181*2fe531cbSDuncan P. N. Exon Smith auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); 182*2fe531cbSDuncan P. N. Exon Smith auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false); 183*2fe531cbSDuncan P. N. Exon Smith auto *RegisterF = llvm::Function::Create(RegisterFTy, 184*2fe531cbSDuncan P. N. Exon Smith llvm::GlobalValue::InternalLinkage, 185*2fe531cbSDuncan P. N. Exon Smith "__llvm_pgo_register_functions", 186*2fe531cbSDuncan P. N. Exon Smith &CGM.getModule()); 187*2fe531cbSDuncan P. N. Exon Smith RegisterF->setUnnamedAddr(true); 188*2fe531cbSDuncan P. N. Exon Smith RegisterF->addFnAttr(llvm::Attribute::NoInline); 189*2fe531cbSDuncan P. N. Exon Smith if (CGM.getCodeGenOpts().DisableRedZone) 190*2fe531cbSDuncan P. N. Exon Smith RegisterF->addFnAttr(llvm::Attribute::NoRedZone); 191*2fe531cbSDuncan P. N. Exon Smith 192*2fe531cbSDuncan P. N. Exon Smith // Construct and return the entry block. 193*2fe531cbSDuncan P. N. Exon Smith auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF); 194*2fe531cbSDuncan P. N. Exon Smith CGBuilderTy Builder(BB); 195*2fe531cbSDuncan P. N. Exon Smith Builder.CreateRetVoid(); 196*2fe531cbSDuncan P. N. Exon Smith return BB; 197*2fe531cbSDuncan P. N. Exon Smith } 198*2fe531cbSDuncan P. N. Exon Smith 199*2fe531cbSDuncan P. N. Exon Smith static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) { 200*2fe531cbSDuncan P. N. Exon Smith auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); 201*2fe531cbSDuncan P. N. Exon Smith auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 202*2fe531cbSDuncan P. N. Exon Smith auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false); 203*2fe531cbSDuncan P. N. Exon Smith return CGM.getModule().getOrInsertFunction("__llvm_pgo_register_function", 204*2fe531cbSDuncan P. N. Exon Smith RuntimeRegisterTy); 205*2fe531cbSDuncan P. N. Exon Smith } 206*2fe531cbSDuncan P. N. Exon Smith 207*2fe531cbSDuncan P. N. Exon Smith static llvm::Constant *getOrInsertRuntimeWriteAtExit(CodeGenModule &CGM) { 208*2fe531cbSDuncan P. N. Exon Smith // TODO: make this depend on a command-line option. 209*2fe531cbSDuncan P. N. Exon Smith auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); 210*2fe531cbSDuncan P. N. Exon Smith auto *WriteAtExitTy = llvm::FunctionType::get(VoidTy, false); 211*2fe531cbSDuncan P. N. Exon Smith return CGM.getModule().getOrInsertFunction("__llvm_pgo_register_write_atexit", 212*2fe531cbSDuncan P. N. Exon Smith WriteAtExitTy); 213*2fe531cbSDuncan P. N. Exon Smith } 214*2fe531cbSDuncan P. N. Exon Smith 215*2fe531cbSDuncan P. N. Exon Smith static StringRef getCountersSection(const CodeGenModule &CGM) { 216*2fe531cbSDuncan P. N. Exon Smith if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO) 217*2fe531cbSDuncan P. N. Exon Smith return "__DATA,__llvm_pgo_cnts"; 218*2fe531cbSDuncan P. N. Exon Smith else 219*2fe531cbSDuncan P. N. Exon Smith return "__llvm_pgo_cnts"; 220*2fe531cbSDuncan P. N. Exon Smith } 221*2fe531cbSDuncan P. N. Exon Smith 222*2fe531cbSDuncan P. N. Exon Smith static StringRef getNameSection(const CodeGenModule &CGM) { 223*2fe531cbSDuncan P. N. Exon Smith if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO) 224*2fe531cbSDuncan P. N. Exon Smith return "__DATA,__llvm_pgo_names"; 225*2fe531cbSDuncan P. N. Exon Smith else 226*2fe531cbSDuncan P. N. Exon Smith return "__llvm_pgo_names"; 227*2fe531cbSDuncan P. N. Exon Smith } 228*2fe531cbSDuncan P. N. Exon Smith 229*2fe531cbSDuncan P. N. Exon Smith static StringRef getDataSection(const CodeGenModule &CGM) { 230*2fe531cbSDuncan P. N. Exon Smith if (CGM.getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO) 231*2fe531cbSDuncan P. N. Exon Smith return "__DATA,__llvm_pgo_data"; 232*2fe531cbSDuncan P. N. Exon Smith else 233*2fe531cbSDuncan P. N. Exon Smith return "__llvm_pgo_data"; 234*2fe531cbSDuncan P. N. Exon Smith } 235*2fe531cbSDuncan P. N. Exon Smith 236*2fe531cbSDuncan P. N. Exon Smith llvm::GlobalVariable *CodeGenPGO::buildDataVar() { 237*2fe531cbSDuncan P. N. Exon Smith // Create name variable. 238*2fe531cbSDuncan P. N. Exon Smith llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 239*2fe531cbSDuncan P. N. Exon Smith auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(), 240*2fe531cbSDuncan P. N. Exon Smith false); 241*2fe531cbSDuncan P. N. Exon Smith auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(), 242*2fe531cbSDuncan P. N. Exon Smith true, FuncLinkage, VarName, 243*2fe531cbSDuncan P. N. Exon Smith getFuncVarName("name")); 244*2fe531cbSDuncan P. N. Exon Smith Name->setSection(getNameSection(CGM)); 245*2fe531cbSDuncan P. N. Exon Smith Name->setAlignment(1); 246*2fe531cbSDuncan P. N. Exon Smith 247*2fe531cbSDuncan P. N. Exon Smith // Create data variable. 248*2fe531cbSDuncan P. N. Exon Smith auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 249*2fe531cbSDuncan P. N. Exon Smith auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx); 250*2fe531cbSDuncan P. N. Exon Smith auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx); 251*2fe531cbSDuncan P. N. Exon Smith llvm::Type *DataTypes[] = { 252*2fe531cbSDuncan P. N. Exon Smith Int32Ty, Int32Ty, Int8PtrTy, Int64PtrTy 253*2fe531cbSDuncan P. N. Exon Smith }; 254*2fe531cbSDuncan P. N. Exon Smith auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes)); 255*2fe531cbSDuncan P. N. Exon Smith llvm::Constant *DataVals[] = { 256*2fe531cbSDuncan P. N. Exon Smith llvm::ConstantInt::get(Int32Ty, getFuncName().size()), 257*2fe531cbSDuncan P. N. Exon Smith llvm::ConstantInt::get(Int32Ty, NumRegionCounters), 258*2fe531cbSDuncan P. N. Exon Smith llvm::ConstantExpr::getBitCast(Name, Int8PtrTy), 259*2fe531cbSDuncan P. N. Exon Smith llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy) 260*2fe531cbSDuncan P. N. Exon Smith }; 261*2fe531cbSDuncan P. N. Exon Smith auto *Data = 262*2fe531cbSDuncan P. N. Exon Smith new llvm::GlobalVariable(CGM.getModule(), DataTy, true, FuncLinkage, 263*2fe531cbSDuncan P. N. Exon Smith llvm::ConstantStruct::get(DataTy, DataVals), 264*2fe531cbSDuncan P. N. Exon Smith getFuncVarName("data")); 265*2fe531cbSDuncan P. N. Exon Smith 266*2fe531cbSDuncan P. N. Exon Smith // All the data should be packed into an array in its own section. 267*2fe531cbSDuncan P. N. Exon Smith Data->setSection(getDataSection(CGM)); 268*2fe531cbSDuncan P. N. Exon Smith Data->setAlignment(8); 269*2fe531cbSDuncan P. N. Exon Smith 270*2fe531cbSDuncan P. N. Exon Smith // Make sure the data doesn't get deleted. 271*2fe531cbSDuncan P. N. Exon Smith CGM.addUsedGlobal(Data); 272*2fe531cbSDuncan P. N. Exon Smith return Data; 273*2fe531cbSDuncan P. N. Exon Smith } 274*2fe531cbSDuncan P. N. Exon Smith 275*2fe531cbSDuncan P. N. Exon Smith void CodeGenPGO::emitInstrumentationData() { 276ef512b99SJustin Bogner if (!CGM.getCodeGenOpts().ProfileInstrGenerate) 277ef512b99SJustin Bogner return; 278ef512b99SJustin Bogner 279*2fe531cbSDuncan P. N. Exon Smith // Build the data. 280*2fe531cbSDuncan P. N. Exon Smith auto *Data = buildDataVar(); 281ef512b99SJustin Bogner 282*2fe531cbSDuncan P. N. Exon Smith // Register the data. 283*2fe531cbSDuncan P. N. Exon Smith // 284*2fe531cbSDuncan P. N. Exon Smith // TODO: only register when static initialization is required. 285*2fe531cbSDuncan P. N. Exon Smith CGBuilderTy Builder(getOrInsertRegisterBB(CGM)->getTerminator()); 286*2fe531cbSDuncan P. N. Exon Smith auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 287*2fe531cbSDuncan P. N. Exon Smith Builder.CreateCall(getOrInsertRuntimeRegister(CGM), 288*2fe531cbSDuncan P. N. Exon Smith Builder.CreateBitCast(Data, VoidPtrTy)); 289ef512b99SJustin Bogner } 290ef512b99SJustin Bogner 291ef512b99SJustin Bogner llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) { 292*2fe531cbSDuncan P. N. Exon Smith if (!CGM.getCodeGenOpts().ProfileInstrGenerate) 293*2fe531cbSDuncan P. N. Exon Smith return 0; 294ef512b99SJustin Bogner 295*2fe531cbSDuncan P. N. Exon Smith // Only need to create this once per module. 296*2fe531cbSDuncan P. N. Exon Smith if (CGM.getModule().getFunction("__llvm_pgo_init")) 297*2fe531cbSDuncan P. N. Exon Smith return 0; 298ef512b99SJustin Bogner 299*2fe531cbSDuncan P. N. Exon Smith // Get the functions to call at initialization. 300*2fe531cbSDuncan P. N. Exon Smith llvm::Constant *RegisterF = getRegisterFunc(CGM); 301*2fe531cbSDuncan P. N. Exon Smith llvm::Constant *WriteAtExitF = getOrInsertRuntimeWriteAtExit(CGM); 302*2fe531cbSDuncan P. N. Exon Smith if (!RegisterF && !WriteAtExitF) 303*2fe531cbSDuncan P. N. Exon Smith return 0; 304*2fe531cbSDuncan P. N. Exon Smith 305*2fe531cbSDuncan P. N. Exon Smith // Create the initialization function. 306*2fe531cbSDuncan P. N. Exon Smith auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext()); 307*2fe531cbSDuncan P. N. Exon Smith auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false), 308*2fe531cbSDuncan P. N. Exon Smith llvm::GlobalValue::InternalLinkage, 309ef512b99SJustin Bogner "__llvm_pgo_init", &CGM.getModule()); 310ef512b99SJustin Bogner F->setUnnamedAddr(true); 311ef512b99SJustin Bogner F->addFnAttr(llvm::Attribute::NoInline); 312ef512b99SJustin Bogner if (CGM.getCodeGenOpts().DisableRedZone) 313ef512b99SJustin Bogner F->addFnAttr(llvm::Attribute::NoRedZone); 314ef512b99SJustin Bogner 315*2fe531cbSDuncan P. N. Exon Smith // Add the basic block and the necessary calls. 316*2fe531cbSDuncan P. N. Exon Smith CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F)); 317*2fe531cbSDuncan P. N. Exon Smith if (RegisterF) 318*2fe531cbSDuncan P. N. Exon Smith Builder.CreateCall(RegisterF); 319*2fe531cbSDuncan P. N. Exon Smith if (WriteAtExitF) 320*2fe531cbSDuncan P. N. Exon Smith Builder.CreateCall(WriteAtExitF); 321*2fe531cbSDuncan P. N. Exon Smith Builder.CreateRetVoid(); 322ef512b99SJustin Bogner 323ef512b99SJustin Bogner return F; 324ef512b99SJustin Bogner } 325ef512b99SJustin Bogner 326ef512b99SJustin Bogner namespace { 327ef512b99SJustin Bogner /// A StmtVisitor that fills a map of statements to PGO counters. 328ef512b99SJustin Bogner struct MapRegionCounters : public ConstStmtVisitor<MapRegionCounters> { 329ef512b99SJustin Bogner /// The next counter value to assign. 330ef512b99SJustin Bogner unsigned NextCounter; 331ef512b99SJustin Bogner /// The map of statements to counters. 332ef512b99SJustin Bogner llvm::DenseMap<const Stmt*, unsigned> *CounterMap; 333ef512b99SJustin Bogner 334ef512b99SJustin Bogner MapRegionCounters(llvm::DenseMap<const Stmt*, unsigned> *CounterMap) : 335ef512b99SJustin Bogner NextCounter(0), CounterMap(CounterMap) { 336ef512b99SJustin Bogner } 337ef512b99SJustin Bogner 338ef512b99SJustin Bogner void VisitChildren(const Stmt *S) { 339ef512b99SJustin Bogner for (Stmt::const_child_range I = S->children(); I; ++I) 340ef512b99SJustin Bogner if (*I) 341ef512b99SJustin Bogner this->Visit(*I); 342ef512b99SJustin Bogner } 343ef512b99SJustin Bogner void VisitStmt(const Stmt *S) { VisitChildren(S); } 344ef512b99SJustin Bogner 345ea278c32SJustin Bogner /// Assign a counter to track entry to the function body. 346ef512b99SJustin Bogner void VisitFunctionDecl(const FunctionDecl *S) { 347ef512b99SJustin Bogner (*CounterMap)[S->getBody()] = NextCounter++; 348ef512b99SJustin Bogner Visit(S->getBody()); 349ef512b99SJustin Bogner } 3505ec8fe19SBob Wilson void VisitObjCMethodDecl(const ObjCMethodDecl *S) { 3515ec8fe19SBob Wilson (*CounterMap)[S->getBody()] = NextCounter++; 3525ec8fe19SBob Wilson Visit(S->getBody()); 3535ec8fe19SBob Wilson } 354c845c00aSBob Wilson void VisitBlockDecl(const BlockDecl *S) { 355c845c00aSBob Wilson (*CounterMap)[S->getBody()] = NextCounter++; 356c845c00aSBob Wilson Visit(S->getBody()); 357c845c00aSBob Wilson } 358ea278c32SJustin Bogner /// Assign a counter to track the block following a label. 359ef512b99SJustin Bogner void VisitLabelStmt(const LabelStmt *S) { 360ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 361ef512b99SJustin Bogner Visit(S->getSubStmt()); 362ef512b99SJustin Bogner } 363bf854f0fSBob Wilson /// Assign a counter for the body of a while loop. 364ef512b99SJustin Bogner void VisitWhileStmt(const WhileStmt *S) { 365bf854f0fSBob Wilson (*CounterMap)[S] = NextCounter++; 366ef512b99SJustin Bogner Visit(S->getCond()); 367ef512b99SJustin Bogner Visit(S->getBody()); 368ef512b99SJustin Bogner } 369bf854f0fSBob Wilson /// Assign a counter for the body of a do-while loop. 370ef512b99SJustin Bogner void VisitDoStmt(const DoStmt *S) { 371bf854f0fSBob Wilson (*CounterMap)[S] = NextCounter++; 372ef512b99SJustin Bogner Visit(S->getBody()); 373ef512b99SJustin Bogner Visit(S->getCond()); 374ef512b99SJustin Bogner } 375bf854f0fSBob Wilson /// Assign a counter for the body of a for loop. 376ef512b99SJustin Bogner void VisitForStmt(const ForStmt *S) { 377bf854f0fSBob Wilson (*CounterMap)[S] = NextCounter++; 378bf854f0fSBob Wilson if (S->getInit()) 379bf854f0fSBob Wilson Visit(S->getInit()); 380ef512b99SJustin Bogner const Expr *E; 381ef512b99SJustin Bogner if ((E = S->getCond())) 382ef512b99SJustin Bogner Visit(E); 383ef512b99SJustin Bogner if ((E = S->getInc())) 384ef512b99SJustin Bogner Visit(E); 385bf854f0fSBob Wilson Visit(S->getBody()); 386ef512b99SJustin Bogner } 387bf854f0fSBob Wilson /// Assign a counter for the body of a for-range loop. 388ef512b99SJustin Bogner void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 389bf854f0fSBob Wilson (*CounterMap)[S] = NextCounter++; 390bf854f0fSBob Wilson Visit(S->getRangeStmt()); 391bf854f0fSBob Wilson Visit(S->getBeginEndStmt()); 392bf854f0fSBob Wilson Visit(S->getCond()); 393bf854f0fSBob Wilson Visit(S->getLoopVarStmt()); 394ef512b99SJustin Bogner Visit(S->getBody()); 395bf854f0fSBob Wilson Visit(S->getInc()); 396ef512b99SJustin Bogner } 397bf854f0fSBob Wilson /// Assign a counter for the body of a for-collection loop. 398ef512b99SJustin Bogner void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 399bf854f0fSBob Wilson (*CounterMap)[S] = NextCounter++; 400ef512b99SJustin Bogner Visit(S->getElement()); 401ef512b99SJustin Bogner Visit(S->getBody()); 402ef512b99SJustin Bogner } 403ef512b99SJustin Bogner /// Assign a counter for the exit block of the switch statement. 404ef512b99SJustin Bogner void VisitSwitchStmt(const SwitchStmt *S) { 405ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 406ef512b99SJustin Bogner Visit(S->getCond()); 407ef512b99SJustin Bogner Visit(S->getBody()); 408ef512b99SJustin Bogner } 409ef512b99SJustin Bogner /// Assign a counter for a particular case in a switch. This counts jumps 410ef512b99SJustin Bogner /// from the switch header as well as fallthrough from the case before this 411ef512b99SJustin Bogner /// one. 412ef512b99SJustin Bogner void VisitCaseStmt(const CaseStmt *S) { 413ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 414ef512b99SJustin Bogner Visit(S->getSubStmt()); 415ef512b99SJustin Bogner } 416ef512b99SJustin Bogner /// Assign a counter for the default case of a switch statement. The count 417ef512b99SJustin Bogner /// is the number of branches from the loop header to the default, and does 418ef512b99SJustin Bogner /// not include fallthrough from previous cases. If we have multiple 419ef512b99SJustin Bogner /// conditional branch blocks from the switch instruction to the default 420ef512b99SJustin Bogner /// block, as with large GNU case ranges, this is the counter for the last 421ef512b99SJustin Bogner /// edge in that series, rather than the first. 422ef512b99SJustin Bogner void VisitDefaultStmt(const DefaultStmt *S) { 423ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 424ef512b99SJustin Bogner Visit(S->getSubStmt()); 425ef512b99SJustin Bogner } 426ef512b99SJustin Bogner /// Assign a counter for the "then" part of an if statement. The count for 427ef512b99SJustin Bogner /// the "else" part, if it exists, will be calculated from this counter. 428ef512b99SJustin Bogner void VisitIfStmt(const IfStmt *S) { 429ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 430ef512b99SJustin Bogner Visit(S->getCond()); 431ef512b99SJustin Bogner Visit(S->getThen()); 432ef512b99SJustin Bogner if (S->getElse()) 433ef512b99SJustin Bogner Visit(S->getElse()); 434ef512b99SJustin Bogner } 435ef512b99SJustin Bogner /// Assign a counter for the continuation block of a C++ try statement. 436ef512b99SJustin Bogner void VisitCXXTryStmt(const CXXTryStmt *S) { 437ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 438ef512b99SJustin Bogner Visit(S->getTryBlock()); 439ef512b99SJustin Bogner for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 440ef512b99SJustin Bogner Visit(S->getHandler(I)); 441ef512b99SJustin Bogner } 442ef512b99SJustin Bogner /// Assign a counter for a catch statement's handler block. 443ef512b99SJustin Bogner void VisitCXXCatchStmt(const CXXCatchStmt *S) { 444ef512b99SJustin Bogner (*CounterMap)[S] = NextCounter++; 445ef512b99SJustin Bogner Visit(S->getHandlerBlock()); 446ef512b99SJustin Bogner } 447ef512b99SJustin Bogner /// Assign a counter for the "true" part of a conditional operator. The 448ef512b99SJustin Bogner /// count in the "false" part will be calculated from this counter. 449ef512b99SJustin Bogner void VisitConditionalOperator(const ConditionalOperator *E) { 450ef512b99SJustin Bogner (*CounterMap)[E] = NextCounter++; 451ef512b99SJustin Bogner Visit(E->getCond()); 452ef512b99SJustin Bogner Visit(E->getTrueExpr()); 453ef512b99SJustin Bogner Visit(E->getFalseExpr()); 454ef512b99SJustin Bogner } 455ef512b99SJustin Bogner /// Assign a counter for the right hand side of a logical and operator. 456ef512b99SJustin Bogner void VisitBinLAnd(const BinaryOperator *E) { 457ef512b99SJustin Bogner (*CounterMap)[E] = NextCounter++; 458ef512b99SJustin Bogner Visit(E->getLHS()); 459ef512b99SJustin Bogner Visit(E->getRHS()); 460ef512b99SJustin Bogner } 461ef512b99SJustin Bogner /// Assign a counter for the right hand side of a logical or operator. 462ef512b99SJustin Bogner void VisitBinLOr(const BinaryOperator *E) { 463ef512b99SJustin Bogner (*CounterMap)[E] = NextCounter++; 464ef512b99SJustin Bogner Visit(E->getLHS()); 465ef512b99SJustin Bogner Visit(E->getRHS()); 466ef512b99SJustin Bogner } 467ef512b99SJustin Bogner }; 468bf854f0fSBob Wilson 469bf854f0fSBob Wilson /// A StmtVisitor that propagates the raw counts through the AST and 470bf854f0fSBob Wilson /// records the count at statements where the value may change. 471bf854f0fSBob Wilson struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> { 472bf854f0fSBob Wilson /// PGO state. 473bf854f0fSBob Wilson CodeGenPGO &PGO; 474bf854f0fSBob Wilson 475bf854f0fSBob Wilson /// A flag that is set when the current count should be recorded on the 476bf854f0fSBob Wilson /// next statement, such as at the exit of a loop. 477bf854f0fSBob Wilson bool RecordNextStmtCount; 478bf854f0fSBob Wilson 479bf854f0fSBob Wilson /// The map of statements to count values. 480bf854f0fSBob Wilson llvm::DenseMap<const Stmt*, uint64_t> *CountMap; 481bf854f0fSBob Wilson 482bf854f0fSBob Wilson /// BreakContinueStack - Keep counts of breaks and continues inside loops. 483bf854f0fSBob Wilson struct BreakContinue { 484bf854f0fSBob Wilson uint64_t BreakCount; 485bf854f0fSBob Wilson uint64_t ContinueCount; 486bf854f0fSBob Wilson BreakContinue() : BreakCount(0), ContinueCount(0) {} 487bf854f0fSBob Wilson }; 488bf854f0fSBob Wilson SmallVector<BreakContinue, 8> BreakContinueStack; 489bf854f0fSBob Wilson 490bf854f0fSBob Wilson ComputeRegionCounts(llvm::DenseMap<const Stmt*, uint64_t> *CountMap, 491bf854f0fSBob Wilson CodeGenPGO &PGO) : 492bf854f0fSBob Wilson PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) { 493bf854f0fSBob Wilson } 494bf854f0fSBob Wilson 495bf854f0fSBob Wilson void RecordStmtCount(const Stmt *S) { 496bf854f0fSBob Wilson if (RecordNextStmtCount) { 497bf854f0fSBob Wilson (*CountMap)[S] = PGO.getCurrentRegionCount(); 498bf854f0fSBob Wilson RecordNextStmtCount = false; 499bf854f0fSBob Wilson } 500bf854f0fSBob Wilson } 501bf854f0fSBob Wilson 502bf854f0fSBob Wilson void VisitStmt(const Stmt *S) { 503bf854f0fSBob Wilson RecordStmtCount(S); 504bf854f0fSBob Wilson for (Stmt::const_child_range I = S->children(); I; ++I) { 505bf854f0fSBob Wilson if (*I) 506bf854f0fSBob Wilson this->Visit(*I); 507bf854f0fSBob Wilson } 508bf854f0fSBob Wilson } 509bf854f0fSBob Wilson 510bf854f0fSBob Wilson void VisitFunctionDecl(const FunctionDecl *S) { 511bf854f0fSBob Wilson RegionCounter Cnt(PGO, S->getBody()); 512bf854f0fSBob Wilson Cnt.beginRegion(); 513bf854f0fSBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 514bf854f0fSBob Wilson Visit(S->getBody()); 515bf854f0fSBob Wilson } 516bf854f0fSBob Wilson 5175ec8fe19SBob Wilson void VisitObjCMethodDecl(const ObjCMethodDecl *S) { 5185ec8fe19SBob Wilson RegionCounter Cnt(PGO, S->getBody()); 5195ec8fe19SBob Wilson Cnt.beginRegion(); 5205ec8fe19SBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 5215ec8fe19SBob Wilson Visit(S->getBody()); 5225ec8fe19SBob Wilson } 5235ec8fe19SBob Wilson 524c845c00aSBob Wilson void VisitBlockDecl(const BlockDecl *S) { 525c845c00aSBob Wilson RegionCounter Cnt(PGO, S->getBody()); 526c845c00aSBob Wilson Cnt.beginRegion(); 527c845c00aSBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 528c845c00aSBob Wilson Visit(S->getBody()); 529c845c00aSBob Wilson } 530c845c00aSBob Wilson 531bf854f0fSBob Wilson void VisitReturnStmt(const ReturnStmt *S) { 532bf854f0fSBob Wilson RecordStmtCount(S); 533bf854f0fSBob Wilson if (S->getRetValue()) 534bf854f0fSBob Wilson Visit(S->getRetValue()); 535bf854f0fSBob Wilson PGO.setCurrentRegionUnreachable(); 536bf854f0fSBob Wilson RecordNextStmtCount = true; 537bf854f0fSBob Wilson } 538bf854f0fSBob Wilson 539bf854f0fSBob Wilson void VisitGotoStmt(const GotoStmt *S) { 540bf854f0fSBob Wilson RecordStmtCount(S); 541bf854f0fSBob Wilson PGO.setCurrentRegionUnreachable(); 542bf854f0fSBob Wilson RecordNextStmtCount = true; 543bf854f0fSBob Wilson } 544bf854f0fSBob Wilson 545bf854f0fSBob Wilson void VisitLabelStmt(const LabelStmt *S) { 546bf854f0fSBob Wilson RecordNextStmtCount = false; 547bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 548bf854f0fSBob Wilson Cnt.beginRegion(); 549bf854f0fSBob Wilson (*CountMap)[S] = PGO.getCurrentRegionCount(); 550bf854f0fSBob Wilson Visit(S->getSubStmt()); 551bf854f0fSBob Wilson } 552bf854f0fSBob Wilson 553bf854f0fSBob Wilson void VisitBreakStmt(const BreakStmt *S) { 554bf854f0fSBob Wilson RecordStmtCount(S); 555bf854f0fSBob Wilson assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 556bf854f0fSBob Wilson BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount(); 557bf854f0fSBob Wilson PGO.setCurrentRegionUnreachable(); 558bf854f0fSBob Wilson RecordNextStmtCount = true; 559bf854f0fSBob Wilson } 560bf854f0fSBob Wilson 561bf854f0fSBob Wilson void VisitContinueStmt(const ContinueStmt *S) { 562bf854f0fSBob Wilson RecordStmtCount(S); 563bf854f0fSBob Wilson assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 564bf854f0fSBob Wilson BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount(); 565bf854f0fSBob Wilson PGO.setCurrentRegionUnreachable(); 566bf854f0fSBob Wilson RecordNextStmtCount = true; 567bf854f0fSBob Wilson } 568bf854f0fSBob Wilson 569bf854f0fSBob Wilson void VisitWhileStmt(const WhileStmt *S) { 570bf854f0fSBob Wilson RecordStmtCount(S); 571bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 572bf854f0fSBob Wilson BreakContinueStack.push_back(BreakContinue()); 573bf854f0fSBob Wilson // Visit the body region first so the break/continue adjustments can be 574bf854f0fSBob Wilson // included when visiting the condition. 575bf854f0fSBob Wilson Cnt.beginRegion(); 576bf854f0fSBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 577bf854f0fSBob Wilson Visit(S->getBody()); 578bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 579bf854f0fSBob Wilson 580bf854f0fSBob Wilson // ...then go back and propagate counts through the condition. The count 581bf854f0fSBob Wilson // at the start of the condition is the sum of the incoming edges, 582bf854f0fSBob Wilson // the backedge from the end of the loop body, and the edges from 583bf854f0fSBob Wilson // continue statements. 584bf854f0fSBob Wilson BreakContinue BC = BreakContinueStack.pop_back_val(); 585bf854f0fSBob Wilson Cnt.setCurrentRegionCount(Cnt.getParentCount() + 586bf854f0fSBob Wilson Cnt.getAdjustedCount() + BC.ContinueCount); 587bf854f0fSBob Wilson (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount(); 588bf854f0fSBob Wilson Visit(S->getCond()); 589bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 590bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 591bf854f0fSBob Wilson RecordNextStmtCount = true; 592bf854f0fSBob Wilson } 593bf854f0fSBob Wilson 594bf854f0fSBob Wilson void VisitDoStmt(const DoStmt *S) { 595bf854f0fSBob Wilson RecordStmtCount(S); 596bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 597bf854f0fSBob Wilson BreakContinueStack.push_back(BreakContinue()); 598bf854f0fSBob Wilson Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 599bf854f0fSBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 600bf854f0fSBob Wilson Visit(S->getBody()); 601bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 602bf854f0fSBob Wilson 603bf854f0fSBob Wilson BreakContinue BC = BreakContinueStack.pop_back_val(); 604bf854f0fSBob Wilson // The count at the start of the condition is equal to the count at the 605bf854f0fSBob Wilson // end of the body. The adjusted count does not include either the 606bf854f0fSBob Wilson // fall-through count coming into the loop or the continue count, so add 607bf854f0fSBob Wilson // both of those separately. This is coincidentally the same equation as 608bf854f0fSBob Wilson // with while loops but for different reasons. 609bf854f0fSBob Wilson Cnt.setCurrentRegionCount(Cnt.getParentCount() + 610bf854f0fSBob Wilson Cnt.getAdjustedCount() + BC.ContinueCount); 611bf854f0fSBob Wilson (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount(); 612bf854f0fSBob Wilson Visit(S->getCond()); 613bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 614bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 615bf854f0fSBob Wilson RecordNextStmtCount = true; 616bf854f0fSBob Wilson } 617bf854f0fSBob Wilson 618bf854f0fSBob Wilson void VisitForStmt(const ForStmt *S) { 619bf854f0fSBob Wilson RecordStmtCount(S); 620bf854f0fSBob Wilson if (S->getInit()) 621bf854f0fSBob Wilson Visit(S->getInit()); 622bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 623bf854f0fSBob Wilson BreakContinueStack.push_back(BreakContinue()); 624bf854f0fSBob Wilson // Visit the body region first. (This is basically the same as a while 625bf854f0fSBob Wilson // loop; see further comments in VisitWhileStmt.) 626bf854f0fSBob Wilson Cnt.beginRegion(); 627bf854f0fSBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 628bf854f0fSBob Wilson Visit(S->getBody()); 629bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 630bf854f0fSBob Wilson 631bf854f0fSBob Wilson // The increment is essentially part of the body but it needs to include 632bf854f0fSBob Wilson // the count for all the continue statements. 633bf854f0fSBob Wilson if (S->getInc()) { 634bf854f0fSBob Wilson Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() + 635bf854f0fSBob Wilson BreakContinueStack.back().ContinueCount); 636bf854f0fSBob Wilson (*CountMap)[S->getInc()] = PGO.getCurrentRegionCount(); 637bf854f0fSBob Wilson Visit(S->getInc()); 638bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 639bf854f0fSBob Wilson } 640bf854f0fSBob Wilson 641bf854f0fSBob Wilson BreakContinue BC = BreakContinueStack.pop_back_val(); 642bf854f0fSBob Wilson 643bf854f0fSBob Wilson // ...then go back and propagate counts through the condition. 644bf854f0fSBob Wilson if (S->getCond()) { 645bf854f0fSBob Wilson Cnt.setCurrentRegionCount(Cnt.getParentCount() + 646bf854f0fSBob Wilson Cnt.getAdjustedCount() + 647bf854f0fSBob Wilson BC.ContinueCount); 648bf854f0fSBob Wilson (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount(); 649bf854f0fSBob Wilson Visit(S->getCond()); 650bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 651bf854f0fSBob Wilson } 652bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 653bf854f0fSBob Wilson RecordNextStmtCount = true; 654bf854f0fSBob Wilson } 655bf854f0fSBob Wilson 656bf854f0fSBob Wilson void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 657bf854f0fSBob Wilson RecordStmtCount(S); 658bf854f0fSBob Wilson Visit(S->getRangeStmt()); 659bf854f0fSBob Wilson Visit(S->getBeginEndStmt()); 660bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 661bf854f0fSBob Wilson BreakContinueStack.push_back(BreakContinue()); 662bf854f0fSBob Wilson // Visit the body region first. (This is basically the same as a while 663bf854f0fSBob Wilson // loop; see further comments in VisitWhileStmt.) 664bf854f0fSBob Wilson Cnt.beginRegion(); 665bf854f0fSBob Wilson (*CountMap)[S->getLoopVarStmt()] = PGO.getCurrentRegionCount(); 666bf854f0fSBob Wilson Visit(S->getLoopVarStmt()); 667bf854f0fSBob Wilson Visit(S->getBody()); 668bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 669bf854f0fSBob Wilson 670bf854f0fSBob Wilson // The increment is essentially part of the body but it needs to include 671bf854f0fSBob Wilson // the count for all the continue statements. 672bf854f0fSBob Wilson Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() + 673bf854f0fSBob Wilson BreakContinueStack.back().ContinueCount); 674bf854f0fSBob Wilson (*CountMap)[S->getInc()] = PGO.getCurrentRegionCount(); 675bf854f0fSBob Wilson Visit(S->getInc()); 676bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 677bf854f0fSBob Wilson 678bf854f0fSBob Wilson BreakContinue BC = BreakContinueStack.pop_back_val(); 679bf854f0fSBob Wilson 680bf854f0fSBob Wilson // ...then go back and propagate counts through the condition. 681bf854f0fSBob Wilson Cnt.setCurrentRegionCount(Cnt.getParentCount() + 682bf854f0fSBob Wilson Cnt.getAdjustedCount() + 683bf854f0fSBob Wilson BC.ContinueCount); 684bf854f0fSBob Wilson (*CountMap)[S->getCond()] = PGO.getCurrentRegionCount(); 685bf854f0fSBob Wilson Visit(S->getCond()); 686bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 687bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 688bf854f0fSBob Wilson RecordNextStmtCount = true; 689bf854f0fSBob Wilson } 690bf854f0fSBob Wilson 691bf854f0fSBob Wilson void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 692bf854f0fSBob Wilson RecordStmtCount(S); 693bf854f0fSBob Wilson Visit(S->getElement()); 694bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 695bf854f0fSBob Wilson BreakContinueStack.push_back(BreakContinue()); 696bf854f0fSBob Wilson Cnt.beginRegion(); 697bf854f0fSBob Wilson (*CountMap)[S->getBody()] = PGO.getCurrentRegionCount(); 698bf854f0fSBob Wilson Visit(S->getBody()); 699bf854f0fSBob Wilson BreakContinue BC = BreakContinueStack.pop_back_val(); 700bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 701bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); 702bf854f0fSBob Wilson RecordNextStmtCount = true; 703bf854f0fSBob Wilson } 704bf854f0fSBob Wilson 705bf854f0fSBob Wilson void VisitSwitchStmt(const SwitchStmt *S) { 706bf854f0fSBob Wilson RecordStmtCount(S); 707bf854f0fSBob Wilson Visit(S->getCond()); 708bf854f0fSBob Wilson PGO.setCurrentRegionUnreachable(); 709bf854f0fSBob Wilson BreakContinueStack.push_back(BreakContinue()); 710bf854f0fSBob Wilson Visit(S->getBody()); 711bf854f0fSBob Wilson // If the switch is inside a loop, add the continue counts. 712bf854f0fSBob Wilson BreakContinue BC = BreakContinueStack.pop_back_val(); 713bf854f0fSBob Wilson if (!BreakContinueStack.empty()) 714bf854f0fSBob Wilson BreakContinueStack.back().ContinueCount += BC.ContinueCount; 715bf854f0fSBob Wilson RegionCounter ExitCnt(PGO, S); 716bf854f0fSBob Wilson ExitCnt.beginRegion(); 717bf854f0fSBob Wilson RecordNextStmtCount = true; 718bf854f0fSBob Wilson } 719bf854f0fSBob Wilson 720bf854f0fSBob Wilson void VisitCaseStmt(const CaseStmt *S) { 721bf854f0fSBob Wilson RecordNextStmtCount = false; 722bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 723bf854f0fSBob Wilson Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 724bf854f0fSBob Wilson (*CountMap)[S] = Cnt.getCount(); 725bf854f0fSBob Wilson RecordNextStmtCount = true; 726bf854f0fSBob Wilson Visit(S->getSubStmt()); 727bf854f0fSBob Wilson } 728bf854f0fSBob Wilson 729bf854f0fSBob Wilson void VisitDefaultStmt(const DefaultStmt *S) { 730bf854f0fSBob Wilson RecordNextStmtCount = false; 731bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 732bf854f0fSBob Wilson Cnt.beginRegion(/*AddIncomingFallThrough=*/true); 733bf854f0fSBob Wilson (*CountMap)[S] = Cnt.getCount(); 734bf854f0fSBob Wilson RecordNextStmtCount = true; 735bf854f0fSBob Wilson Visit(S->getSubStmt()); 736bf854f0fSBob Wilson } 737bf854f0fSBob Wilson 738bf854f0fSBob Wilson void VisitIfStmt(const IfStmt *S) { 739bf854f0fSBob Wilson RecordStmtCount(S); 740bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 741bf854f0fSBob Wilson Visit(S->getCond()); 742bf854f0fSBob Wilson 743bf854f0fSBob Wilson Cnt.beginRegion(); 744bf854f0fSBob Wilson (*CountMap)[S->getThen()] = PGO.getCurrentRegionCount(); 745bf854f0fSBob Wilson Visit(S->getThen()); 746bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 747bf854f0fSBob Wilson 748bf854f0fSBob Wilson if (S->getElse()) { 749bf854f0fSBob Wilson Cnt.beginElseRegion(); 750bf854f0fSBob Wilson (*CountMap)[S->getElse()] = PGO.getCurrentRegionCount(); 751bf854f0fSBob Wilson Visit(S->getElse()); 752bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 753bf854f0fSBob Wilson } 754bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(0); 755bf854f0fSBob Wilson RecordNextStmtCount = true; 756bf854f0fSBob Wilson } 757bf854f0fSBob Wilson 758bf854f0fSBob Wilson void VisitCXXTryStmt(const CXXTryStmt *S) { 759bf854f0fSBob Wilson RecordStmtCount(S); 760bf854f0fSBob Wilson Visit(S->getTryBlock()); 761bf854f0fSBob Wilson for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 762bf854f0fSBob Wilson Visit(S->getHandler(I)); 763bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 764bf854f0fSBob Wilson Cnt.beginRegion(); 765bf854f0fSBob Wilson RecordNextStmtCount = true; 766bf854f0fSBob Wilson } 767bf854f0fSBob Wilson 768bf854f0fSBob Wilson void VisitCXXCatchStmt(const CXXCatchStmt *S) { 769bf854f0fSBob Wilson RecordNextStmtCount = false; 770bf854f0fSBob Wilson RegionCounter Cnt(PGO, S); 771bf854f0fSBob Wilson Cnt.beginRegion(); 772bf854f0fSBob Wilson (*CountMap)[S] = PGO.getCurrentRegionCount(); 773bf854f0fSBob Wilson Visit(S->getHandlerBlock()); 774bf854f0fSBob Wilson } 775bf854f0fSBob Wilson 776bf854f0fSBob Wilson void VisitConditionalOperator(const ConditionalOperator *E) { 777bf854f0fSBob Wilson RecordStmtCount(E); 778bf854f0fSBob Wilson RegionCounter Cnt(PGO, E); 779bf854f0fSBob Wilson Visit(E->getCond()); 780bf854f0fSBob Wilson 781bf854f0fSBob Wilson Cnt.beginRegion(); 782bf854f0fSBob Wilson (*CountMap)[E->getTrueExpr()] = PGO.getCurrentRegionCount(); 783bf854f0fSBob Wilson Visit(E->getTrueExpr()); 784bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 785bf854f0fSBob Wilson 786bf854f0fSBob Wilson Cnt.beginElseRegion(); 787bf854f0fSBob Wilson (*CountMap)[E->getFalseExpr()] = PGO.getCurrentRegionCount(); 788bf854f0fSBob Wilson Visit(E->getFalseExpr()); 789bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 790bf854f0fSBob Wilson 791bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(0); 792bf854f0fSBob Wilson RecordNextStmtCount = true; 793bf854f0fSBob Wilson } 794bf854f0fSBob Wilson 795bf854f0fSBob Wilson void VisitBinLAnd(const BinaryOperator *E) { 796bf854f0fSBob Wilson RecordStmtCount(E); 797bf854f0fSBob Wilson RegionCounter Cnt(PGO, E); 798bf854f0fSBob Wilson Visit(E->getLHS()); 799bf854f0fSBob Wilson Cnt.beginRegion(); 800bf854f0fSBob Wilson (*CountMap)[E->getRHS()] = PGO.getCurrentRegionCount(); 801bf854f0fSBob Wilson Visit(E->getRHS()); 802bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 803bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(0); 804bf854f0fSBob Wilson RecordNextStmtCount = true; 805bf854f0fSBob Wilson } 806bf854f0fSBob Wilson 807bf854f0fSBob Wilson void VisitBinLOr(const BinaryOperator *E) { 808bf854f0fSBob Wilson RecordStmtCount(E); 809bf854f0fSBob Wilson RegionCounter Cnt(PGO, E); 810bf854f0fSBob Wilson Visit(E->getLHS()); 811bf854f0fSBob Wilson Cnt.beginRegion(); 812bf854f0fSBob Wilson (*CountMap)[E->getRHS()] = PGO.getCurrentRegionCount(); 813bf854f0fSBob Wilson Visit(E->getRHS()); 814bf854f0fSBob Wilson Cnt.adjustForControlFlow(); 815bf854f0fSBob Wilson Cnt.applyAdjustmentsToRegion(0); 816bf854f0fSBob Wilson RecordNextStmtCount = true; 817bf854f0fSBob Wilson } 818bf854f0fSBob Wilson }; 819ef512b99SJustin Bogner } 820ef512b99SJustin Bogner 821da1ebedeSBob Wilson void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { 822ef512b99SJustin Bogner bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate; 823d66a17d0SJustin Bogner PGOProfileData *PGOData = CGM.getPGOData(); 824d66a17d0SJustin Bogner if (!InstrumentRegions && !PGOData) 825ef512b99SJustin Bogner return; 826ef512b99SJustin Bogner if (!D) 827ef512b99SJustin Bogner return; 828da1ebedeSBob Wilson setFuncName(Fn); 829*2fe531cbSDuncan P. N. Exon Smith FuncLinkage = Fn->getLinkage(); 830ef512b99SJustin Bogner mapRegionCounters(D); 831ef512b99SJustin Bogner if (InstrumentRegions) 832ef512b99SJustin Bogner emitCounterVariables(); 833d66a17d0SJustin Bogner if (PGOData) { 834d66a17d0SJustin Bogner loadRegionCounts(PGOData); 835bf854f0fSBob Wilson computeRegionCounts(D); 836d66a17d0SJustin Bogner applyFunctionAttributes(PGOData, Fn); 837bf854f0fSBob Wilson } 838ef512b99SJustin Bogner } 839ef512b99SJustin Bogner 840ef512b99SJustin Bogner void CodeGenPGO::mapRegionCounters(const Decl *D) { 841ef512b99SJustin Bogner RegionCounterMap = new llvm::DenseMap<const Stmt*, unsigned>(); 842ef512b99SJustin Bogner MapRegionCounters Walker(RegionCounterMap); 843ef512b99SJustin Bogner if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 844ef512b99SJustin Bogner Walker.VisitFunctionDecl(FD); 8455ec8fe19SBob Wilson else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 8465ec8fe19SBob Wilson Walker.VisitObjCMethodDecl(MD); 847c845c00aSBob Wilson else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 848c845c00aSBob Wilson Walker.VisitBlockDecl(BD); 849ef512b99SJustin Bogner NumRegionCounters = Walker.NextCounter; 850ef512b99SJustin Bogner } 851ef512b99SJustin Bogner 852bf854f0fSBob Wilson void CodeGenPGO::computeRegionCounts(const Decl *D) { 853bf854f0fSBob Wilson StmtCountMap = new llvm::DenseMap<const Stmt*, uint64_t>(); 854bf854f0fSBob Wilson ComputeRegionCounts Walker(StmtCountMap, *this); 855bf854f0fSBob Wilson if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 856bf854f0fSBob Wilson Walker.VisitFunctionDecl(FD); 8575ec8fe19SBob Wilson else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) 8585ec8fe19SBob Wilson Walker.VisitObjCMethodDecl(MD); 859c845c00aSBob Wilson else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D)) 860c845c00aSBob Wilson Walker.VisitBlockDecl(BD); 861bf854f0fSBob Wilson } 862bf854f0fSBob Wilson 863d66a17d0SJustin Bogner void CodeGenPGO::applyFunctionAttributes(PGOProfileData *PGOData, 8644c9c45c0SJustin Bogner llvm::Function *Fn) { 8654c9c45c0SJustin Bogner if (!haveRegionCounts()) 8664c9c45c0SJustin Bogner return; 8674c9c45c0SJustin Bogner 868d66a17d0SJustin Bogner uint64_t MaxFunctionCount = PGOData->getMaximumFunctionCount(); 8694c9c45c0SJustin Bogner uint64_t FunctionCount = getRegionCount(0); 8704c9c45c0SJustin Bogner if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount)) 8714c9c45c0SJustin Bogner // Turn on InlineHint attribute for hot functions. 8724c9c45c0SJustin Bogner // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal. 8734c9c45c0SJustin Bogner Fn->addFnAttr(llvm::Attribute::InlineHint); 8744c9c45c0SJustin Bogner else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount)) 8754c9c45c0SJustin Bogner // Turn on Cold attribute for cold functions. 8764c9c45c0SJustin Bogner // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal. 8774c9c45c0SJustin Bogner Fn->addFnAttr(llvm::Attribute::Cold); 8784c9c45c0SJustin Bogner } 8794c9c45c0SJustin Bogner 880ef512b99SJustin Bogner void CodeGenPGO::emitCounterVariables() { 881ef512b99SJustin Bogner llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 882ef512b99SJustin Bogner llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx), 883ef512b99SJustin Bogner NumRegionCounters); 884ef512b99SJustin Bogner RegionCounters = 885*2fe531cbSDuncan P. N. Exon Smith new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, FuncLinkage, 886ef512b99SJustin Bogner llvm::Constant::getNullValue(CounterTy), 887*2fe531cbSDuncan P. N. Exon Smith getFuncVarName("counters")); 888*2fe531cbSDuncan P. N. Exon Smith RegionCounters->setAlignment(8); 889*2fe531cbSDuncan P. N. Exon Smith RegionCounters->setSection(getCountersSection(CGM)); 890ef512b99SJustin Bogner } 891ef512b99SJustin Bogner 892ef512b99SJustin Bogner void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) { 893749ebc7fSBob Wilson if (!RegionCounters) 894ef512b99SJustin Bogner return; 895ef512b99SJustin Bogner llvm::Value *Addr = 896ef512b99SJustin Bogner Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter); 897ef512b99SJustin Bogner llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount"); 898ef512b99SJustin Bogner Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 899ef512b99SJustin Bogner Builder.CreateStore(Count, Addr); 900ef512b99SJustin Bogner } 901ef512b99SJustin Bogner 902d66a17d0SJustin Bogner void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) { 903ef512b99SJustin Bogner // For now, ignore the counts from the PGO data file only if the number of 904ef512b99SJustin Bogner // counters does not match. This could be tightened down in the future to 905ef512b99SJustin Bogner // ignore counts when the input changes in various ways, e.g., by comparing a 906ef512b99SJustin Bogner // hash value based on some characteristics of the input. 907ef512b99SJustin Bogner RegionCounts = new std::vector<uint64_t>(); 908d66a17d0SJustin Bogner if (PGOData->getFunctionCounts(getFuncName(), *RegionCounts) || 909ef512b99SJustin Bogner RegionCounts->size() != NumRegionCounters) { 910ef512b99SJustin Bogner delete RegionCounts; 911ef512b99SJustin Bogner RegionCounts = 0; 912ef512b99SJustin Bogner } 913ef512b99SJustin Bogner } 914ef512b99SJustin Bogner 915ef512b99SJustin Bogner void CodeGenPGO::destroyRegionCounters() { 916ef512b99SJustin Bogner if (RegionCounterMap != 0) 917ef512b99SJustin Bogner delete RegionCounterMap; 918bf854f0fSBob Wilson if (StmtCountMap != 0) 919bf854f0fSBob Wilson delete StmtCountMap; 920ef512b99SJustin Bogner if (RegionCounts != 0) 921ef512b99SJustin Bogner delete RegionCounts; 922ef512b99SJustin Bogner } 923ef512b99SJustin Bogner 92438402dc9SDuncan P. N. Exon Smith /// \brief Calculate what to divide by to scale weights. 92538402dc9SDuncan P. N. Exon Smith /// 92638402dc9SDuncan P. N. Exon Smith /// Given the maximum weight, calculate a divisor that will scale all the 92738402dc9SDuncan P. N. Exon Smith /// weights to strictly less than UINT32_MAX. 92838402dc9SDuncan P. N. Exon Smith static uint64_t calculateWeightScale(uint64_t MaxWeight) { 92938402dc9SDuncan P. N. Exon Smith return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1; 93038402dc9SDuncan P. N. Exon Smith } 93138402dc9SDuncan P. N. Exon Smith 93238402dc9SDuncan P. N. Exon Smith /// \brief Scale an individual branch weight (and add 1). 93338402dc9SDuncan P. N. Exon Smith /// 93438402dc9SDuncan P. N. Exon Smith /// Scale a 64-bit weight down to 32-bits using \c Scale. 93538402dc9SDuncan P. N. Exon Smith /// 93638402dc9SDuncan P. N. Exon Smith /// According to Laplace's Rule of Succession, it is better to compute the 93738402dc9SDuncan P. N. Exon Smith /// weight based on the count plus 1, so universally add 1 to the value. 93838402dc9SDuncan P. N. Exon Smith /// 93938402dc9SDuncan P. N. Exon Smith /// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no 94038402dc9SDuncan P. N. Exon Smith /// greater than \c Weight. 94138402dc9SDuncan P. N. Exon Smith static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) { 94238402dc9SDuncan P. N. Exon Smith assert(Scale && "scale by 0?"); 94338402dc9SDuncan P. N. Exon Smith uint64_t Scaled = Weight / Scale + 1; 94438402dc9SDuncan P. N. Exon Smith assert(Scaled <= UINT32_MAX && "overflow 32-bits"); 94538402dc9SDuncan P. N. Exon Smith return Scaled; 94638402dc9SDuncan P. N. Exon Smith } 94738402dc9SDuncan P. N. Exon Smith 948ef512b99SJustin Bogner llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount, 949ef512b99SJustin Bogner uint64_t FalseCount) { 95038402dc9SDuncan P. N. Exon Smith // Check for empty weights. 951ef512b99SJustin Bogner if (!TrueCount && !FalseCount) 952ef512b99SJustin Bogner return 0; 953ef512b99SJustin Bogner 95438402dc9SDuncan P. N. Exon Smith // Calculate how to scale down to 32-bits. 95538402dc9SDuncan P. N. Exon Smith uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount)); 95638402dc9SDuncan P. N. Exon Smith 957ef512b99SJustin Bogner llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 95838402dc9SDuncan P. N. Exon Smith return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale), 95938402dc9SDuncan P. N. Exon Smith scaleBranchWeight(FalseCount, Scale)); 960ef512b99SJustin Bogner } 961ef512b99SJustin Bogner 96295a27b0eSBob Wilson llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) { 96338402dc9SDuncan P. N. Exon Smith // We need at least two elements to create meaningful weights. 96438402dc9SDuncan P. N. Exon Smith if (Weights.size() < 2) 96538402dc9SDuncan P. N. Exon Smith return 0; 96638402dc9SDuncan P. N. Exon Smith 96738402dc9SDuncan P. N. Exon Smith // Calculate how to scale down to 32-bits. 96838402dc9SDuncan P. N. Exon Smith uint64_t Scale = calculateWeightScale(*std::max_element(Weights.begin(), 96938402dc9SDuncan P. N. Exon Smith Weights.end())); 97038402dc9SDuncan P. N. Exon Smith 971ef512b99SJustin Bogner SmallVector<uint32_t, 16> ScaledWeights; 972ef512b99SJustin Bogner ScaledWeights.reserve(Weights.size()); 97338402dc9SDuncan P. N. Exon Smith for (uint64_t W : Weights) 97438402dc9SDuncan P. N. Exon Smith ScaledWeights.push_back(scaleBranchWeight(W, Scale)); 97538402dc9SDuncan P. N. Exon Smith 97638402dc9SDuncan P. N. Exon Smith llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 977ef512b99SJustin Bogner return MDHelper.createBranchWeights(ScaledWeights); 978ef512b99SJustin Bogner } 979bf854f0fSBob Wilson 980bf854f0fSBob Wilson llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond, 981bf854f0fSBob Wilson RegionCounter &Cnt) { 982bf854f0fSBob Wilson if (!haveRegionCounts()) 983bf854f0fSBob Wilson return 0; 984bf854f0fSBob Wilson uint64_t LoopCount = Cnt.getCount(); 985bf854f0fSBob Wilson uint64_t CondCount = 0; 986bf854f0fSBob Wilson bool Found = getStmtCount(Cond, CondCount); 987bf854f0fSBob Wilson assert(Found && "missing expected loop condition count"); 988bf854f0fSBob Wilson (void)Found; 989bf854f0fSBob Wilson if (CondCount == 0) 990bf854f0fSBob Wilson return 0; 991bf854f0fSBob Wilson return createBranchWeights(LoopCount, 992bf854f0fSBob Wilson std::max(CondCount, LoopCount) - LoopCount); 993bf854f0fSBob Wilson } 994