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
/// 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 {
/// 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.
};
/// Represents the relative location of a callsite.
/// head is), the discriminator value within that line, and the callee
/// function name.
struct CallsiteLocation : public 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;
};
: LineLocation(L, D), CalleeName(N) {}
StringRef CalleeName;
};
} // End namespace sampleprof
template <> struct DenseMapInfo<sampleprof::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());
static inline sampleprof::LineLocation getEmptyKey() {
return sampleprof::LineLocation(OffsetInfo::getEmptyKey(),
DiscriminatorInfo::getEmptyKey());
DiscriminatorInfo::getTombstoneKey());
}
static inline unsigned getHashValue(sampleprof::LineLocation Val) {
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) {
}
static inline bool isEqual(sampleprof::LineLocation LHS,
sampleprof::LineLocation RHS) {
};
template <> struct DenseMapInfo<sampleprof::CallsiteLocation> {
};
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(),
typedef DenseMapInfo<StringRef> CalleeNameInfo;
static inline sampleprof::CallsiteLocation getEmptyKey() {
return sampleprof::CallsiteLocation(OffsetInfo::getEmptyKey(),
"");
}
static inline unsigned getHashValue(sampleprof::CallsiteLocation Val) {
"");
}
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) {
}
static inline bool isEqual(sampleprof::CallsiteLocation LHS,
sampleprof::CallsiteLocation RHS) {
/// will be a list of one or more functions.
class SampleRecord {
public:
/// 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() {}
SampleRecord() : NumSamples(0), CallTargets() {}
///
/// Sample counts accumulate using saturating arithmetic, to avoid wrapping
/// around unsigned integers.
///
/// 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 = 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.
}
/// 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 = 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; }
}
/// 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.
const CallTargetMap &getCallTargets() const { return CallTargets; }
/// Merge the samples in \p Other into this record.
CallTargetMap CallTargets;
};
CallTargetMap CallTargets;
};
public:
FunctionSamples() : TotalSamples(0), TotalHeadSamples(0) {}
void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
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);
}
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);
assert(LineOffset >= 0);
BodySamples[LineLocation(LineOffset, Discriminator)].addCalledTarget(FName,
Num);
/// 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.
/// 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();
const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator));
if (ret == BodySamples.end())
return std::error_code();
bool empty() const { return TotalSamples == 0; }
/// Return the total number of samples collected inside the function.
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.
/// 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; }
/// Return all the samples collected in the body of the function.
const BodySampleMap &getBodySamples() const { return BodySamples; }
///
/// Samples are cumulative, they include all the samples collected
/// inside this function and all its inlined callees.
///
/// Samples are cumulative, they include all the samples collected
/// inside this function and all its inlined callees.
/// 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.
/// 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.
///
/// Map instruction locations to collected samples.
///
// 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.
// 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.
// Total number of samples collected in this function.
// 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.
// Total number of samples collected at the head of the function.
// NRECS (uint32_t)
// Total number of sampling records this function's profile.
void addName(StringRef FName);
void addNames(const FunctionSamples &S);
void addName(StringRef FName);
void addNames(const FunctionSamples &S);
- MapVector<StringRef, unsigned> NameTable;
+ MapVector<StringRef, uint32_t> NameTable;
};
} // End namespace sampleprof
};
} // End namespace sampleprof
///
/// \returns true if parsing is successful.
static bool ParseHead(const StringRef &Input, StringRef &FName,
///
/// \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(':');
if (Input[0] == ' ')
return false;
size_t n2 = Input.rfind(':');
/// \param TargetCountMap map from indirect call target to count.
///
/// returns true if parsing is successful.
/// \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)
for (Depth = 0; Input[Depth] == ' '; Depth++)
;
if (Depth == 0)
if (n3 != StringRef::npos) {
pair = Rest.substr(0, n3);
}
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;
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;
CalleeName = Rest.substr(0, n3);
if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples))
return false;
// The only requirement we place on the identifier, then, is that it
// should not begin with a number.
if ((*LineIt)[0] != ' ') {
// 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(),
StringRef FName;
if (!ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
reportError(LineIt.line_number(),
InlineStack.clear();
InlineStack.push_back(&FProfile);
} else {
InlineStack.clear();
InlineStack.push_back(&FProfile);
} else {
- DenseMap<StringRef, unsigned> TargetCountMap;
+ DenseMap<StringRef, uint64_t> TargetCountMap;
- unsigned Depth, LineOffset, Discriminator;
+ uint32_t Depth, LineOffset, Discriminator;
if (!ParseLine(*LineIt, IsCallsite, Depth, NumSamples, LineOffset,
Discriminator, FName, TargetCountMap)) {
reportError(LineIt.line_number(),
if (!ParseLine(*LineIt, IsCallsite, Depth, NumSamples, LineOffset,
Discriminator, FName, TargetCountMap)) {
reportError(LineIt.line_number(),
ErrorOr<StringRef> SampleProfileReaderBinary::readStringFromTable() {
std::error_code EC;
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())
if (std::error_code EC = Idx.getError())
return EC;
if (*Idx >= NameTable.size())
std::error_code
SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
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);
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.
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;
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;
auto LineOffset = readNumber<uint64_t>();
if (std::error_code EC = LineOffset.getError())
return EC;
if (std::error_code EC = NumSamples.getError())
return EC;
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;
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;
auto CalledFunction(readStringFromTable());
if (std::error_code EC = CalledFunction.getError())
return EC;
}
// Read all the samples for inlined function calls.
}
// 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;
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;
auto LineOffset = readNumber<uint64_t>();
if (std::error_code EC = LineOffset.getError())
return EC;
return sampleprof_error::unsupported_version;
// Read the name table.
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);
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;
auto Name(readString());
if (std::error_code EC = Name.getError())
return EC;
auto Buffer = std::move(BufferOrErr.get());
// Sanity check the file.
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);
return sampleprof_error::too_large;
return std::move(Buffer);
encodeULEB128(Sample.getCallTargets().size(), OS);
for (const auto &J : Sample.getCallTargets()) {
StringRef Callee = J.first();
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);
if (std::error_code EC = writeNameIdx(Callee))
return EC;
encodeULEB128(CalleeSamples, OS);
"sample block/edge weights through the CFG."));
namespace {
"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<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;
typedef DenseMap<const BasicBlock *, SmallVector<const BasicBlock *, 8>>
BlockEdgeMap;
bool runOnFunction(Function &F);
unsigned getFunctionLoc(Function &F);
bool emitAnnotations(Function &F);
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);
const FunctionSamples *findCalleeFunctionSamples(const CallInst &I) const;
const FunctionSamples *findFunctionSamples(const Instruction &I) const;
bool inlineHotFunctions(Function &F);
SmallVector<BasicBlock *, 8> Descendants,
DominatorTreeBase<BasicBlock> *DomTree);
void propagateWeights(Function &F);
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);
void buildEdges(Function &F);
bool propagateThroughEdges(Function &F);
void computeDominanceAndLoopInfo(Function &F);
void SampleProfileLoader::printBlockWeight(raw_ostream &OS,
const BasicBlock *BB) const {
const auto &I = BlockWeights.find(BB);
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";
}
OS << "weight[" << BB->getName() << "]: " << W << "\n";
}
/// \param Inst Instruction to query.
///
/// \returns the weight of \p Inst.
/// \param Inst Instruction to query.
///
/// \returns the weight of \p Inst.
SampleProfileLoader::getInstWeight(const Instruction &Inst) const {
DebugLoc DLoc = Inst.getDebugLoc();
if (!DLoc)
SampleProfileLoader::getInstWeight(const Instruction &Inst) const {
DebugLoc DLoc = Inst.getDebugLoc();
if (!DLoc)
if (Lineno < HeaderLineno)
return std::error_code();
if (Lineno < HeaderLineno)
return std::error_code();
FS->findSamplesAt(Lineno - HeaderLineno, DIL->getDiscriminator());
if (R)
DEBUG(dbgs() << " " << Lineno << "." << DIL->getDiscriminator() << ":"
FS->findSamplesAt(Lineno - HeaderLineno, DIL->getDiscriminator());
if (R)
DEBUG(dbgs() << " " << Lineno << "." << DIL->getDiscriminator() << ":"
/// \param BB The basic block to query.
///
/// \returns the weight for \p BB.
/// \param BB The basic block to query.
///
/// \returns the weight for \p BB.
SampleProfileLoader::getBlockWeight(const BasicBlock *BB) const {
bool Found = false;
SampleProfileLoader::getBlockWeight(const BasicBlock *BB) const {
bool Found = false;
for (auto &I : BB->getInstList()) {
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;
if (R && R.get() >= Weight) {
Weight = R.get();
Found = true;
bool Changed = false;
DEBUG(dbgs() << "Block weights\n");
for (const auto &BB : 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);
if (Weight) {
BlockWeights[&BB] = Weight.get();
VisitedBlocks.insert(&BB);
BasicBlock *BB1, SmallVector<BasicBlock *, 8> Descendants,
DominatorTreeBase<BasicBlock> *DomTree) {
const BasicBlock *EC = EquivalenceClass[BB1];
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);
for (const auto *BB2 : Descendants) {
bool IsDomParent = DomTree->dominates(BB2, BB1);
bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2);
/// \param UnknownEdge Set if E has not been visited before.
///
/// \returns E's weight, if known. Otherwise, return 0.
/// \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)++;
Edge *UnknownEdge) {
if (!VisitedEdges.count(E)) {
(*NumUnknownEdges)++;
// only case we are interested in handling is when only a single
// edge is unknown (see setEdgeOrBlockWeight).
for (unsigned i = 0; i < 2; i++) {
// 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;
unsigned NumUnknownEdges = 0;
Edge UnknownEdge, SelfReferentialEdge;
// all edges will get a weight, or iteration will stop when
// it reaches SampleProfileMaxPropagateIterations.
if (NumUnknownEdges <= 1) {
// 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
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
printEdgeWeight(dbgs(), UnknownEdge));
}
} else if (SelfReferentialEdge.first && VisitedBlocks.count(EC)) {
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;
// We have a self-referential edge and the weight of BB is known.
if (BBWeight >= TotalWeight)
EdgeWeights[SelfReferentialEdge] = BBWeight - TotalWeight;
/// known).
void SampleProfileLoader::propagateWeights(Function &F) {
bool Changed = true;
/// known).
void SampleProfileLoader::propagateWeights(Function &F) {
bool Changed = true;
// Add an entry count to the function using the samples gathered
// at the function entry.
// Add an entry count to the function using the samples gathered
// at the function entry.
buildEdges(F);
// Propagate until we converge or we go past the iteration limit.
buildEdges(F);
// Propagate until we converge or we go past the iteration limit.
- while (Changed && i++ < SampleProfileMaxPropagateIterations) {
+ while (Changed && I++ < SampleProfileMaxPropagateIterations) {
Changed = propagateThroughEdges(F);
}
Changed = propagateThroughEdges(F);
}
DEBUG(dbgs() << "\nGetting weights for branch at line "
<< TI->getDebugLoc().getLine() << ".\n");
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);
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));
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;
}
if (Weight != 0)
AllWeightsZero = false;
}