diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ProfileData/SampleProfReader.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/ProfileData/SampleProfWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/SampleProfile.cpp | 51 |
3 files changed, 54 insertions, 47 deletions
diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp index 6149c6c3506..1ea7d2a0c4b 100644 --- a/llvm/lib/ProfileData/SampleProfReader.cpp +++ b/llvm/lib/ProfileData/SampleProfReader.cpp @@ -87,7 +87,7 @@ void SampleProfileReader::dump(raw_ostream &OS) { /// /// \returns true if parsing is successful. static bool ParseHead(const StringRef &Input, StringRef &FName, - unsigned &NumSamples, unsigned &NumHeadSamples) { + uint64_t &NumSamples, uint64_t &NumHeadSamples) { if (Input[0] == ' ') return false; size_t n2 = Input.rfind(':'); @@ -111,10 +111,10 @@ static bool ParseHead(const StringRef &Input, StringRef &FName, /// \param TargetCountMap map from indirect call target to count. /// /// returns true if parsing is successful. -static bool ParseLine(const StringRef &Input, bool &IsCallsite, unsigned &Depth, - unsigned &NumSamples, unsigned &LineOffset, - unsigned &Discriminator, StringRef &CalleeName, - DenseMap<StringRef, unsigned> &TargetCountMap) { +static bool ParseLine(const StringRef &Input, bool &IsCallsite, uint32_t &Depth, + uint64_t &NumSamples, uint32_t &LineOffset, + uint32_t &Discriminator, StringRef &CalleeName, + DenseMap<StringRef, uint64_t> &TargetCountMap) { for (Depth = 0; Input[Depth] == ' '; Depth++) ; if (Depth == 0) @@ -153,15 +153,15 @@ static bool ParseLine(const StringRef &Input, bool &IsCallsite, unsigned &Depth, if (n3 != StringRef::npos) { pair = Rest.substr(0, n3); } - int n4 = pair.find(':'); - unsigned count; + size_t n4 = pair.find(':'); + uint64_t count; if (pair.substr(n4 + 1).getAsInteger(10, count)) return false; TargetCountMap[pair.substr(0, n4)] = count; } } else { IsCallsite = true; - int n3 = Rest.find_last_of(':'); + size_t n3 = Rest.find_last_of(':'); CalleeName = Rest.substr(0, n3); if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples)) return false; @@ -196,7 +196,7 @@ std::error_code SampleProfileReaderText::read() { // The only requirement we place on the identifier, then, is that it // should not begin with a number. if ((*LineIt)[0] != ' ') { - unsigned NumSamples, NumHeadSamples; + uint64_t NumSamples, NumHeadSamples; StringRef FName; if (!ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) { reportError(LineIt.line_number(), @@ -210,11 +210,11 @@ std::error_code SampleProfileReaderText::read() { InlineStack.clear(); InlineStack.push_back(&FProfile); } else { - unsigned NumSamples; + uint64_t NumSamples; StringRef FName; - DenseMap<StringRef, unsigned> TargetCountMap; + DenseMap<StringRef, uint64_t> TargetCountMap; bool IsCallsite; - unsigned Depth, LineOffset, Discriminator; + uint32_t Depth, LineOffset, Discriminator; if (!ParseLine(*LineIt, IsCallsite, Depth, NumSamples, LineOffset, Discriminator, FName, TargetCountMap)) { reportError(LineIt.line_number(), @@ -283,7 +283,7 @@ ErrorOr<StringRef> SampleProfileReaderBinary::readString() { ErrorOr<StringRef> SampleProfileReaderBinary::readStringFromTable() { std::error_code EC; - auto Idx = readNumber<unsigned>(); + auto Idx = readNumber<uint32_t>(); if (std::error_code EC = Idx.getError()) return EC; if (*Idx >= NameTable.size()) @@ -293,22 +293,22 @@ ErrorOr<StringRef> SampleProfileReaderBinary::readStringFromTable() { std::error_code SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { - auto Val = readNumber<unsigned>(); + auto Val = readNumber<uint64_t>(); if (std::error_code EC = Val.getError()) return EC; FProfile.addTotalSamples(*Val); - Val = readNumber<unsigned>(); + Val = readNumber<uint64_t>(); if (std::error_code EC = Val.getError()) return EC; FProfile.addHeadSamples(*Val); // Read the samples in the body. - auto NumRecords = readNumber<unsigned>(); + auto NumRecords = readNumber<uint32_t>(); if (std::error_code EC = NumRecords.getError()) return EC; - for (unsigned I = 0; I < *NumRecords; ++I) { + for (uint32_t I = 0; I < *NumRecords; ++I) { auto LineOffset = readNumber<uint64_t>(); if (std::error_code EC = LineOffset.getError()) return EC; @@ -321,11 +321,11 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { if (std::error_code EC = NumSamples.getError()) return EC; - auto NumCalls = readNumber<unsigned>(); + auto NumCalls = readNumber<uint32_t>(); if (std::error_code EC = NumCalls.getError()) return EC; - for (unsigned J = 0; J < *NumCalls; ++J) { + for (uint32_t J = 0; J < *NumCalls; ++J) { auto CalledFunction(readStringFromTable()); if (std::error_code EC = CalledFunction.getError()) return EC; @@ -342,11 +342,11 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { } // Read all the samples for inlined function calls. - auto NumCallsites = readNumber<unsigned>(); + auto NumCallsites = readNumber<uint32_t>(); if (std::error_code EC = NumCallsites.getError()) return EC; - for (unsigned J = 0; J < *NumCallsites; ++J) { + for (uint32_t J = 0; J < *NumCallsites; ++J) { auto LineOffset = readNumber<uint64_t>(); if (std::error_code EC = LineOffset.getError()) return EC; @@ -403,11 +403,11 @@ std::error_code SampleProfileReaderBinary::readHeader() { return sampleprof_error::unsupported_version; // Read the name table. - auto Size = readNumber<size_t>(); + auto Size = readNumber<uint32_t>(); if (std::error_code EC = Size.getError()) return EC; NameTable.reserve(*Size); - for (size_t I = 0; I < *Size; ++I) { + for (uint32_t I = 0; I < *Size; ++I) { auto Name(readString()); if (std::error_code EC = Name.getError()) return EC; @@ -678,7 +678,7 @@ setupMemoryBuffer(std::string Filename) { auto Buffer = std::move(BufferOrErr.get()); // Sanity check the file. - if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max()) + if (Buffer->getBufferSize() > std::numeric_limits<uint32_t>::max()) return sampleprof_error::too_large; return std::move(Buffer); diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp index d3001aac3f6..daf3783aba6 100644 --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -144,7 +144,7 @@ std::error_code SampleProfileWriterBinary::write(StringRef FName, encodeULEB128(Sample.getCallTargets().size(), OS); for (const auto &J : Sample.getCallTargets()) { StringRef Callee = J.first(); - unsigned CalleeSamples = J.second; + uint64_t CalleeSamples = J.second; if (std::error_code EC = writeNameIdx(Callee)) return EC; encodeULEB128(CalleeSamples, OS); diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index cb4dad2f7eb..e0691515c95 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -65,10 +65,10 @@ static cl::opt<unsigned> SampleProfileMaxPropagateIterations( "sample block/edge weights through the CFG.")); namespace { -typedef DenseMap<const BasicBlock *, unsigned> BlockWeightMap; +typedef DenseMap<const BasicBlock *, uint64_t> BlockWeightMap; typedef DenseMap<const BasicBlock *, const BasicBlock *> EquivalenceClassMap; typedef std::pair<const BasicBlock *, const BasicBlock *> Edge; -typedef DenseMap<Edge, unsigned> EdgeWeightMap; +typedef DenseMap<Edge, uint64_t> EdgeWeightMap; typedef DenseMap<const BasicBlock *, SmallVector<const BasicBlock *, 8>> BlockEdgeMap; @@ -104,8 +104,8 @@ protected: bool runOnFunction(Function &F); unsigned getFunctionLoc(Function &F); bool emitAnnotations(Function &F); - ErrorOr<unsigned> getInstWeight(const Instruction &I) const; - ErrorOr<unsigned> getBlockWeight(const BasicBlock *BB) const; + ErrorOr<uint64_t> getInstWeight(const Instruction &I) const; + ErrorOr<uint64_t> getBlockWeight(const BasicBlock *BB) const; const FunctionSamples *findCalleeFunctionSamples(const CallInst &I) const; const FunctionSamples *findFunctionSamples(const Instruction &I) const; bool inlineHotFunctions(Function &F); @@ -118,7 +118,7 @@ protected: SmallVector<BasicBlock *, 8> Descendants, DominatorTreeBase<BasicBlock> *DomTree); void propagateWeights(Function &F); - unsigned visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge); + uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge); void buildEdges(Function &F); bool propagateThroughEdges(Function &F); void computeDominanceAndLoopInfo(Function &F); @@ -201,7 +201,7 @@ void SampleProfileLoader::printBlockEquivalence(raw_ostream &OS, void SampleProfileLoader::printBlockWeight(raw_ostream &OS, const BasicBlock *BB) const { const auto &I = BlockWeights.find(BB); - unsigned W = (I == BlockWeights.end() ? 0 : I->second); + uint64_t W = (I == BlockWeights.end() ? 0 : I->second); OS << "weight[" << BB->getName() << "]: " << W << "\n"; } @@ -216,7 +216,7 @@ void SampleProfileLoader::printBlockWeight(raw_ostream &OS, /// \param Inst Instruction to query. /// /// \returns the weight of \p Inst. -ErrorOr<unsigned> +ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) const { DebugLoc DLoc = Inst.getDebugLoc(); if (!DLoc) @@ -232,7 +232,7 @@ SampleProfileLoader::getInstWeight(const Instruction &Inst) const { if (Lineno < HeaderLineno) return std::error_code(); - ErrorOr<unsigned> R = + ErrorOr<uint64_t> R = FS->findSamplesAt(Lineno - HeaderLineno, DIL->getDiscriminator()); if (R) DEBUG(dbgs() << " " << Lineno << "." << DIL->getDiscriminator() << ":" @@ -250,12 +250,12 @@ SampleProfileLoader::getInstWeight(const Instruction &Inst) const { /// \param BB The basic block to query. /// /// \returns the weight for \p BB. -ErrorOr<unsigned> +ErrorOr<uint64_t> SampleProfileLoader::getBlockWeight(const BasicBlock *BB) const { bool Found = false; - unsigned Weight = 0; + uint64_t Weight = 0; for (auto &I : BB->getInstList()) { - const ErrorOr<unsigned> &R = getInstWeight(I); + const ErrorOr<uint64_t> &R = getInstWeight(I); if (R && R.get() >= Weight) { Weight = R.get(); Found = true; @@ -277,7 +277,7 @@ bool SampleProfileLoader::computeBlockWeights(Function &F) { bool Changed = false; DEBUG(dbgs() << "Block weights\n"); for (const auto &BB : F) { - ErrorOr<unsigned> Weight = getBlockWeight(&BB); + ErrorOr<uint64_t> Weight = getBlockWeight(&BB); if (Weight) { BlockWeights[&BB] = Weight.get(); VisitedBlocks.insert(&BB); @@ -431,7 +431,7 @@ void SampleProfileLoader::findEquivalencesFor( BasicBlock *BB1, SmallVector<BasicBlock *, 8> Descendants, DominatorTreeBase<BasicBlock> *DomTree) { const BasicBlock *EC = EquivalenceClass[BB1]; - unsigned Weight = BlockWeights[EC]; + uint64_t Weight = BlockWeights[EC]; for (const auto *BB2 : Descendants) { bool IsDomParent = DomTree->dominates(BB2, BB1); bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2); @@ -520,7 +520,7 @@ void SampleProfileLoader::findEquivalenceClasses(Function &F) { /// \param UnknownEdge Set if E has not been visited before. /// /// \returns E's weight, if known. Otherwise, return 0. -unsigned SampleProfileLoader::visitEdge(Edge E, unsigned *NumUnknownEdges, +uint64_t SampleProfileLoader::visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge) { if (!VisitedEdges.count(E)) { (*NumUnknownEdges)++; @@ -555,7 +555,7 @@ bool SampleProfileLoader::propagateThroughEdges(Function &F) { // only case we are interested in handling is when only a single // edge is unknown (see setEdgeOrBlockWeight). for (unsigned i = 0; i < 2; i++) { - unsigned TotalWeight = 0; + uint64_t TotalWeight = 0; unsigned NumUnknownEdges = 0; Edge UnknownEdge, SelfReferentialEdge; @@ -599,7 +599,7 @@ bool SampleProfileLoader::propagateThroughEdges(Function &F) { // all edges will get a weight, or iteration will stop when // it reaches SampleProfileMaxPropagateIterations. if (NumUnknownEdges <= 1) { - unsigned &BBWeight = BlockWeights[EC]; + uint64_t &BBWeight = BlockWeights[EC]; if (NumUnknownEdges == 0) { // If we already know the weight of all edges, the weight of the // basic block can be computed. It should be no larger than the sum @@ -626,7 +626,7 @@ bool SampleProfileLoader::propagateThroughEdges(Function &F) { printEdgeWeight(dbgs(), UnknownEdge)); } } else if (SelfReferentialEdge.first && VisitedBlocks.count(EC)) { - unsigned &BBWeight = BlockWeights[BB]; + uint64_t &BBWeight = BlockWeights[BB]; // We have a self-referential edge and the weight of BB is known. if (BBWeight >= TotalWeight) EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight; @@ -692,7 +692,7 @@ void SampleProfileLoader::buildEdges(Function &F) { /// known). void SampleProfileLoader::propagateWeights(Function &F) { bool Changed = true; - unsigned i = 0; + unsigned I = 0; // Add an entry count to the function using the samples gathered // at the function entry. @@ -706,7 +706,7 @@ void SampleProfileLoader::propagateWeights(Function &F) { buildEdges(F); // Propagate until we converge or we go past the iteration limit. - while (Changed && i++ < SampleProfileMaxPropagateIterations) { + while (Changed && I++ < SampleProfileMaxPropagateIterations) { Changed = propagateThroughEdges(F); } @@ -724,14 +724,21 @@ void SampleProfileLoader::propagateWeights(Function &F) { DEBUG(dbgs() << "\nGetting weights for branch at line " << TI->getDebugLoc().getLine() << ".\n"); - SmallVector<unsigned, 4> Weights; + SmallVector<uint32_t, 4> Weights; bool AllWeightsZero = true; for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) { BasicBlock *Succ = TI->getSuccessor(I); Edge E = std::make_pair(BB, Succ); - unsigned Weight = EdgeWeights[E]; + uint64_t Weight = EdgeWeights[E]; DEBUG(dbgs() << "\t"; printEdgeWeight(dbgs(), E)); - Weights.push_back(Weight); + // Use uint32_t saturated arithmetic to adjust the incoming weights, + // if needed. Sample counts in profiles are 64-bit unsigned values, + // but internally branch weights are expressed as 32-bit values. + if (Weight > std::numeric_limits<uint32_t>::max()) { + DEBUG(dbgs() << " (saturated due to uint32_t overflow)"); + Weight = std::numeric_limits<uint32_t>::max(); + } + Weights.push_back(static_cast<uint32_t>(Weight)); if (Weight != 0) AllWeightsZero = false; } |