mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-19 00:14:20 +00:00
Sample Profiles - Adjust integer types. Mostly NFC.
This adjusts all integers in the reader/writer to reflect the types stored on profile files. They should all be unsigned 32-bit or 64-bit values. Changed all associated internal types to be uint32_t or uint64_t. The only place that needed some adjustments is in the sample profile transformation. Altough the weight read from the profile are 64-bit values, the internal API for branch weights only accepts 32-bit values. The pass now saturates weights that overflow uint32_t. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250427 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
55975672e8
commit
634f5c1b9b
@ -73,9 +73,9 @@ static inline uint64_t SPVersion() { return 101; }
|
||||
/// that are on the same line but belong to different basic blocks
|
||||
/// (e.g., the two post-increment instructions in "if (p) x++; else y++;").
|
||||
struct LineLocation {
|
||||
LineLocation(int L, unsigned D) : LineOffset(L), Discriminator(D) {}
|
||||
int LineOffset;
|
||||
unsigned Discriminator;
|
||||
LineLocation(uint32_t L, uint32_t D) : LineOffset(L), Discriminator(D) {}
|
||||
uint32_t LineOffset;
|
||||
uint32_t Discriminator;
|
||||
};
|
||||
|
||||
/// Represents the relative location of a callsite.
|
||||
@ -85,7 +85,7 @@ struct LineLocation {
|
||||
/// head is), the discriminator value within that line, and the callee
|
||||
/// function name.
|
||||
struct CallsiteLocation : public LineLocation {
|
||||
CallsiteLocation(int L, unsigned D, StringRef N)
|
||||
CallsiteLocation(uint32_t L, uint32_t D, StringRef N)
|
||||
: LineLocation(L, D), CalleeName(N) {}
|
||||
StringRef CalleeName;
|
||||
};
|
||||
@ -93,8 +93,8 @@ struct CallsiteLocation : public LineLocation {
|
||||
} // End namespace sampleprof
|
||||
|
||||
template <> struct DenseMapInfo<sampleprof::LineLocation> {
|
||||
typedef DenseMapInfo<int> OffsetInfo;
|
||||
typedef DenseMapInfo<unsigned> DiscriminatorInfo;
|
||||
typedef DenseMapInfo<uint32_t> OffsetInfo;
|
||||
typedef DenseMapInfo<uint32_t> DiscriminatorInfo;
|
||||
static inline sampleprof::LineLocation getEmptyKey() {
|
||||
return sampleprof::LineLocation(OffsetInfo::getEmptyKey(),
|
||||
DiscriminatorInfo::getEmptyKey());
|
||||
@ -104,8 +104,8 @@ template <> struct DenseMapInfo<sampleprof::LineLocation> {
|
||||
DiscriminatorInfo::getTombstoneKey());
|
||||
}
|
||||
static inline unsigned getHashValue(sampleprof::LineLocation Val) {
|
||||
return DenseMapInfo<std::pair<int, unsigned>>::getHashValue(
|
||||
std::pair<int, unsigned>(Val.LineOffset, Val.Discriminator));
|
||||
return DenseMapInfo<std::pair<uint32_t, uint32_t>>::getHashValue(
|
||||
std::pair<uint32_t, uint32_t>(Val.LineOffset, Val.Discriminator));
|
||||
}
|
||||
static inline bool isEqual(sampleprof::LineLocation LHS,
|
||||
sampleprof::LineLocation RHS) {
|
||||
@ -115,8 +115,8 @@ template <> struct DenseMapInfo<sampleprof::LineLocation> {
|
||||
};
|
||||
|
||||
template <> struct DenseMapInfo<sampleprof::CallsiteLocation> {
|
||||
typedef DenseMapInfo<int> OffsetInfo;
|
||||
typedef DenseMapInfo<unsigned> DiscriminatorInfo;
|
||||
typedef DenseMapInfo<uint32_t> OffsetInfo;
|
||||
typedef DenseMapInfo<uint32_t> DiscriminatorInfo;
|
||||
typedef DenseMapInfo<StringRef> CalleeNameInfo;
|
||||
static inline sampleprof::CallsiteLocation getEmptyKey() {
|
||||
return sampleprof::CallsiteLocation(OffsetInfo::getEmptyKey(),
|
||||
@ -128,8 +128,8 @@ template <> struct DenseMapInfo<sampleprof::CallsiteLocation> {
|
||||
"");
|
||||
}
|
||||
static inline unsigned getHashValue(sampleprof::CallsiteLocation Val) {
|
||||
return DenseMapInfo<std::pair<int, unsigned>>::getHashValue(
|
||||
std::pair<int, unsigned>(Val.LineOffset, Val.Discriminator));
|
||||
return DenseMapInfo<std::pair<uint32_t, uint32_t>>::getHashValue(
|
||||
std::pair<uint32_t, uint32_t>(Val.LineOffset, Val.Discriminator));
|
||||
}
|
||||
static inline bool isEqual(sampleprof::CallsiteLocation LHS,
|
||||
sampleprof::CallsiteLocation RHS) {
|
||||
@ -153,7 +153,7 @@ namespace sampleprof {
|
||||
/// will be a list of one or more functions.
|
||||
class SampleRecord {
|
||||
public:
|
||||
typedef StringMap<unsigned> CallTargetMap;
|
||||
typedef StringMap<uint64_t> CallTargetMap;
|
||||
|
||||
SampleRecord() : NumSamples(0), CallTargets() {}
|
||||
|
||||
@ -161,29 +161,29 @@ public:
|
||||
///
|
||||
/// Sample counts accumulate using saturating arithmetic, to avoid wrapping
|
||||
/// around unsigned integers.
|
||||
void addSamples(unsigned S) {
|
||||
if (NumSamples <= std::numeric_limits<unsigned>::max() - S)
|
||||
void addSamples(uint64_t S) {
|
||||
if (NumSamples <= std::numeric_limits<uint64_t>::max() - S)
|
||||
NumSamples += S;
|
||||
else
|
||||
NumSamples = std::numeric_limits<unsigned>::max();
|
||||
NumSamples = std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
|
||||
/// Add called function \p F with samples \p S.
|
||||
///
|
||||
/// Sample counts accumulate using saturating arithmetic, to avoid wrapping
|
||||
/// around unsigned integers.
|
||||
void addCalledTarget(StringRef F, unsigned S) {
|
||||
unsigned &TargetSamples = CallTargets[F];
|
||||
if (TargetSamples <= std::numeric_limits<unsigned>::max() - S)
|
||||
void addCalledTarget(StringRef F, uint64_t S) {
|
||||
uint64_t &TargetSamples = CallTargets[F];
|
||||
if (TargetSamples <= std::numeric_limits<uint64_t>::max() - S)
|
||||
TargetSamples += S;
|
||||
else
|
||||
TargetSamples = std::numeric_limits<unsigned>::max();
|
||||
TargetSamples = std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
|
||||
/// Return true if this sample record contains function calls.
|
||||
bool hasCalls() const { return CallTargets.size() > 0; }
|
||||
|
||||
unsigned getSamples() const { return NumSamples; }
|
||||
uint64_t getSamples() const { return NumSamples; }
|
||||
const CallTargetMap &getCallTargets() const { return CallTargets; }
|
||||
|
||||
/// Merge the samples in \p Other into this record.
|
||||
@ -194,7 +194,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned NumSamples;
|
||||
uint64_t NumSamples;
|
||||
CallTargetMap CallTargets;
|
||||
};
|
||||
|
||||
@ -211,14 +211,15 @@ class FunctionSamples {
|
||||
public:
|
||||
FunctionSamples() : TotalSamples(0), TotalHeadSamples(0) {}
|
||||
void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
|
||||
void addTotalSamples(unsigned Num) { TotalSamples += Num; }
|
||||
void addHeadSamples(unsigned Num) { TotalHeadSamples += Num; }
|
||||
void addBodySamples(int LineOffset, unsigned Discriminator, unsigned Num) {
|
||||
void addTotalSamples(uint64_t Num) { TotalSamples += Num; }
|
||||
void addHeadSamples(uint64_t Num) { TotalHeadSamples += Num; }
|
||||
void addBodySamples(uint32_t LineOffset, uint32_t Discriminator,
|
||||
uint64_t Num) {
|
||||
assert(LineOffset >= 0);
|
||||
BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(Num);
|
||||
}
|
||||
void addCalledTargetSamples(int LineOffset, unsigned Discriminator,
|
||||
std::string FName, unsigned Num) {
|
||||
void addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator,
|
||||
std::string FName, uint64_t Num) {
|
||||
assert(LineOffset >= 0);
|
||||
BodySamples[LineLocation(LineOffset, Discriminator)].addCalledTarget(FName,
|
||||
Num);
|
||||
@ -227,8 +228,8 @@ public:
|
||||
/// Return the number of samples collected at the given location.
|
||||
/// Each location is specified by \p LineOffset and \p Discriminator.
|
||||
/// If the location is not found in profile, return error.
|
||||
ErrorOr<unsigned> findSamplesAt(int LineOffset,
|
||||
unsigned Discriminator) const {
|
||||
ErrorOr<uint64_t> findSamplesAt(uint32_t LineOffset,
|
||||
uint32_t Discriminator) const {
|
||||
const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator));
|
||||
if (ret == BodySamples.end())
|
||||
return std::error_code();
|
||||
@ -255,11 +256,11 @@ public:
|
||||
bool empty() const { return TotalSamples == 0; }
|
||||
|
||||
/// Return the total number of samples collected inside the function.
|
||||
unsigned getTotalSamples() const { return TotalSamples; }
|
||||
uint64_t getTotalSamples() const { return TotalSamples; }
|
||||
|
||||
/// Return the total number of samples collected at the head of the
|
||||
/// function.
|
||||
unsigned getHeadSamples() const { return TotalHeadSamples; }
|
||||
uint64_t getHeadSamples() const { return TotalHeadSamples; }
|
||||
|
||||
/// Return all the samples collected in the body of the function.
|
||||
const BodySampleMap &getBodySamples() const { return BodySamples; }
|
||||
@ -290,12 +291,12 @@ private:
|
||||
///
|
||||
/// Samples are cumulative, they include all the samples collected
|
||||
/// inside this function and all its inlined callees.
|
||||
unsigned TotalSamples;
|
||||
uint64_t TotalSamples;
|
||||
|
||||
/// Total number of samples collected at the head of the function.
|
||||
/// This is an approximation of the number of calls made to this function
|
||||
/// at runtime.
|
||||
unsigned TotalHeadSamples;
|
||||
uint64_t TotalHeadSamples;
|
||||
|
||||
/// Map instruction locations to collected samples.
|
||||
///
|
||||
|
@ -138,10 +138,9 @@
|
||||
// FUNCTION BODY (one for each uninlined function body present in the profile)
|
||||
// NAME_IDX (uint32_t)
|
||||
// Index into the name table indicating the function name.
|
||||
// SAMPLES (uint32_t)
|
||||
// SAMPLES (uint64_t)
|
||||
// Total number of samples collected in this function.
|
||||
// FIXME(dnovillo) this should be a uint64_t value.
|
||||
// HEAD_SAMPLES (uint32_t)
|
||||
// HEAD_SAMPLES (uint64_t)
|
||||
// Total number of samples collected at the head of the function.
|
||||
// NRECS (uint32_t)
|
||||
// Total number of sampling records this function's profile.
|
||||
|
@ -110,7 +110,7 @@ private:
|
||||
void addName(StringRef FName);
|
||||
void addNames(const FunctionSamples &S);
|
||||
|
||||
MapVector<StringRef, unsigned> NameTable;
|
||||
MapVector<StringRef, uint32_t> NameTable;
|
||||
};
|
||||
|
||||
} // End namespace sampleprof
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user