mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 16:41:06 +03:00
Update LLVM 6.0 FileCheck and llvm-profdata (#2602)
This commit is contained in:
parent
af4ff423a1
commit
d0215ccf7b
2 changed files with 63 additions and 10 deletions
|
@ -37,14 +37,19 @@ using namespace llvm;
|
||||||
|
|
||||||
enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
|
enum ProfileFormat { PF_None = 0, PF_Text, PF_Binary, PF_GCC };
|
||||||
|
|
||||||
static void exitWithError(const Twine &Message, StringRef Whence = "",
|
static void warn(StringRef Prefix, Twine Message, std::string Whence = "",
|
||||||
StringRef Hint = "") {
|
std::string Hint = "") {
|
||||||
errs() << "error: ";
|
errs() << Prefix;
|
||||||
if (!Whence.empty())
|
if (!Whence.empty())
|
||||||
errs() << Whence << ": ";
|
errs() << Whence << ": ";
|
||||||
errs() << Message << "\n";
|
errs() << Message << "\n";
|
||||||
if (!Hint.empty())
|
if (!Hint.empty())
|
||||||
errs() << Hint << "\n";
|
errs() << Hint << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exitWithError(Twine Message, std::string Whence = "",
|
||||||
|
std::string Hint = "") {
|
||||||
|
warn("error: ", Message, Whence, Hint);
|
||||||
::exit(1);
|
::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +124,7 @@ struct WriterContext {
|
||||||
std::mutex Lock;
|
std::mutex Lock;
|
||||||
InstrProfWriter Writer;
|
InstrProfWriter Writer;
|
||||||
Error Err;
|
Error Err;
|
||||||
StringRef ErrWhence;
|
std::string ErrWhence;
|
||||||
std::mutex &ErrLock;
|
std::mutex &ErrLock;
|
||||||
SmallSet<instrprof_error, 4> &WriterErrorCodes;
|
SmallSet<instrprof_error, 4> &WriterErrorCodes;
|
||||||
|
|
||||||
|
@ -129,6 +134,22 @@ struct WriterContext {
|
||||||
ErrLock(ErrLock), WriterErrorCodes(WriterErrorCodes) {}
|
ErrLock(ErrLock), WriterErrorCodes(WriterErrorCodes) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Determine whether an error is fatal for profile merging.
|
||||||
|
static bool isFatalError(instrprof_error IPE) {
|
||||||
|
switch (IPE) {
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
case instrprof_error::success:
|
||||||
|
case instrprof_error::eof:
|
||||||
|
case instrprof_error::unknown_function:
|
||||||
|
case instrprof_error::hash_mismatch:
|
||||||
|
case instrprof_error::count_mismatch:
|
||||||
|
case instrprof_error::counter_overflow:
|
||||||
|
case instrprof_error::value_site_count_mismatch:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Load an input into a writer context.
|
/// Load an input into a writer context.
|
||||||
static void loadInput(const WeightedFile &Input, WriterContext *WC) {
|
static void loadInput(const WeightedFile &Input, WriterContext *WC) {
|
||||||
std::unique_lock<std::mutex> CtxGuard{WC->Lock};
|
std::unique_lock<std::mutex> CtxGuard{WC->Lock};
|
||||||
|
@ -137,6 +158,9 @@ static void loadInput(const WeightedFile &Input, WriterContext *WC) {
|
||||||
if (WC->Err)
|
if (WC->Err)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Copy the filename, because llvm::ThreadPool copied the input "const
|
||||||
|
// WeightedFile &" by value, making a reference to the filename within it
|
||||||
|
// invalid outside of this packaged task.
|
||||||
WC->ErrWhence = Input.Filename;
|
WC->ErrWhence = Input.Filename;
|
||||||
|
|
||||||
auto ReaderOrErr = InstrProfReader::create(Input.Filename);
|
auto ReaderOrErr = InstrProfReader::create(Input.Filename);
|
||||||
|
@ -174,12 +198,22 @@ static void loadInput(const WeightedFile &Input, WriterContext *WC) {
|
||||||
FuncName, firstTime);
|
FuncName, firstTime);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (Reader->hasError())
|
if (Reader->hasError()) {
|
||||||
WC->Err = Reader->getError();
|
if (Error E = Reader->getError()) {
|
||||||
|
instrprof_error IPE = InstrProfError::take(std::move(E));
|
||||||
|
if (isFatalError(IPE))
|
||||||
|
WC->Err = make_error<InstrProfError>(IPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge the \p Src writer context into \p Dst.
|
/// Merge the \p Src writer context into \p Dst.
|
||||||
static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) {
|
static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) {
|
||||||
|
// If we've already seen a hard error, continuing with the merge would
|
||||||
|
// clobber it.
|
||||||
|
if (Dst->Err || Src->Err)
|
||||||
|
return;
|
||||||
|
|
||||||
bool Reported = false;
|
bool Reported = false;
|
||||||
Dst->Writer.mergeRecordsFromWriter(std::move(Src->Writer), [&](Error E) {
|
Dst->Writer.mergeRecordsFromWriter(std::move(Src->Writer), [&](Error E) {
|
||||||
if (Reported) {
|
if (Reported) {
|
||||||
|
@ -211,8 +245,8 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
|
||||||
|
|
||||||
// If NumThreads is not specified, auto-detect a good default.
|
// If NumThreads is not specified, auto-detect a good default.
|
||||||
if (NumThreads == 0)
|
if (NumThreads == 0)
|
||||||
NumThreads = std::max(1U, std::min(std::thread::hardware_concurrency(),
|
NumThreads =
|
||||||
unsigned(Inputs.size() / 2)));
|
std::min(hardware_concurrency(), unsigned((Inputs.size() + 1) / 2));
|
||||||
|
|
||||||
// Initialize the writer contexts.
|
// Initialize the writer contexts.
|
||||||
SmallVector<std::unique_ptr<WriterContext>, 4> Contexts;
|
SmallVector<std::unique_ptr<WriterContext>, 4> Contexts;
|
||||||
|
@ -254,10 +288,20 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle deferred hard errors encountered during merging.
|
// Handle deferred hard errors encountered during merging.
|
||||||
for (std::unique_ptr<WriterContext> &WC : Contexts)
|
for (std::unique_ptr<WriterContext> &WC : Contexts) {
|
||||||
if (WC->Err)
|
if (!WC->Err)
|
||||||
|
continue;
|
||||||
|
if (!WC->Err.isA<InstrProfError>())
|
||||||
exitWithError(std::move(WC->Err), WC->ErrWhence);
|
exitWithError(std::move(WC->Err), WC->ErrWhence);
|
||||||
|
|
||||||
|
instrprof_error IPE = InstrProfError::take(std::move(WC->Err));
|
||||||
|
if (isFatalError(IPE))
|
||||||
|
exitWithError(make_error<InstrProfError>(IPE), WC->ErrWhence);
|
||||||
|
else
|
||||||
|
warn("warning: ", toString(make_error<InstrProfError>(IPE)),
|
||||||
|
WC->ErrWhence);
|
||||||
|
}
|
||||||
|
|
||||||
InstrProfWriter &Writer = Contexts[0]->Writer;
|
InstrProfWriter &Writer = Contexts[0]->Writer;
|
||||||
if (OutputFormat == PF_Text) {
|
if (OutputFormat == PF_Text) {
|
||||||
if (Error E = Writer.writeText(Output))
|
if (Error E = Writer.writeText(Output))
|
||||||
|
@ -625,6 +669,8 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
|
||||||
if (ShowCounts && TextFormat)
|
if (ShowCounts && TextFormat)
|
||||||
return 0;
|
return 0;
|
||||||
std::unique_ptr<ProfileSummary> PS(Builder.getSummary());
|
std::unique_ptr<ProfileSummary> PS(Builder.getSummary());
|
||||||
|
OS << "Instrumentation level: "
|
||||||
|
<< (Reader->isIRLevelProfile() ? "IR" : "Front-end") << "\n";
|
||||||
if (ShowAllFunctions || !ShowFunction.empty())
|
if (ShowAllFunctions || !ShowFunction.empty())
|
||||||
OS << "Functions shown: " << ShownFunctions << "\n";
|
OS << "Functions shown: " << ShownFunctions << "\n";
|
||||||
OS << "Total functions: " << PS->getNumFunctions() << "\n";
|
OS << "Total functions: " << PS->getNumFunctions() << "\n";
|
||||||
|
|
|
@ -62,6 +62,10 @@ static cl::list<std::string> ImplicitCheckNot(
|
||||||
"this pattern occur which are not matched by a positive pattern"),
|
"this pattern occur which are not matched by a positive pattern"),
|
||||||
cl::value_desc("pattern"));
|
cl::value_desc("pattern"));
|
||||||
|
|
||||||
|
static cl::list<std::string> GlobalDefines("D", cl::Prefix,
|
||||||
|
cl::desc("Define a variable to be used in capture patterns."),
|
||||||
|
cl::value_desc("VAR=VALUE"));
|
||||||
|
|
||||||
static cl::opt<bool> AllowEmptyInput(
|
static cl::opt<bool> AllowEmptyInput(
|
||||||
"allow-empty", cl::init(false),
|
"allow-empty", cl::init(false),
|
||||||
cl::desc("Allow the input file to be empty. This is useful when making\n"
|
cl::desc("Allow the input file to be empty. This is useful when making\n"
|
||||||
|
@ -1295,6 +1299,9 @@ bool CheckInput(SourceMgr &SM, StringRef Buffer,
|
||||||
/// VariableTable - This holds all the current filecheck variables.
|
/// VariableTable - This holds all the current filecheck variables.
|
||||||
StringMap<StringRef> VariableTable;
|
StringMap<StringRef> VariableTable;
|
||||||
|
|
||||||
|
for (const auto& Def : GlobalDefines)
|
||||||
|
VariableTable.insert(StringRef(Def).split('='));
|
||||||
|
|
||||||
unsigned i = 0, j = 0, e = CheckStrings.size();
|
unsigned i = 0, j = 0, e = CheckStrings.size();
|
||||||
while (true) {
|
while (true) {
|
||||||
StringRef CheckRegion;
|
StringRef CheckRegion;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue