summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-12-30 13:13:10 +0000
committerdim <dim@FreeBSD.org>2015-12-30 13:13:10 +0000
commit9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a (patch)
treeb466a4817f79516eb1df8eae92bccf62ecc84003 /contrib/llvm/lib/Support
parentf09a28d1de99fda4f5517fb12670fc36552f4927 (diff)
parente194cd6d03d91631334d9d5e55b506036f423cc8 (diff)
downloadFreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.zip
FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.tar.gz
Update llvm to trunk r256633.
Diffstat (limited to 'contrib/llvm/lib/Support')
-rw-r--r--contrib/llvm/lib/Support/APFloat.cpp46
-rw-r--r--contrib/llvm/lib/Support/BlockFrequency.cpp36
-rw-r--r--contrib/llvm/lib/Support/BranchProbability.cpp49
-rw-r--r--contrib/llvm/lib/Support/CommandLine.cpp60
-rw-r--r--contrib/llvm/lib/Support/CrashRecoveryContext.cpp26
-rw-r--r--contrib/llvm/lib/Support/Dwarf.cpp37
-rw-r--r--contrib/llvm/lib/Support/ErrorHandling.cpp2
-rw-r--r--contrib/llvm/lib/Support/FileOutputBuffer.cpp18
-rw-r--r--contrib/llvm/lib/Support/FoldingSet.cpp20
-rw-r--r--contrib/llvm/lib/Support/GraphWriter.cpp74
-rw-r--r--contrib/llvm/lib/Support/Host.cpp43
-rw-r--r--contrib/llvm/lib/Support/JamCRC.cpp96
-rw-r--r--contrib/llvm/lib/Support/Locale.cpp1
-rw-r--r--contrib/llvm/lib/Support/ManagedStatic.cpp1
-rw-r--r--contrib/llvm/lib/Support/MemoryBuffer.cpp5
-rw-r--r--contrib/llvm/lib/Support/Path.cpp110
-rw-r--r--contrib/llvm/lib/Support/PrettyStackTrace.cpp16
-rw-r--r--contrib/llvm/lib/Support/Signals.cpp140
-rw-r--r--contrib/llvm/lib/Support/Statistic.cpp18
-rw-r--r--contrib/llvm/lib/Support/StringRef.cpp103
-rw-r--r--contrib/llvm/lib/Support/StringSaver.cpp2
-rw-r--r--contrib/llvm/lib/Support/TargetParser.cpp504
-rw-r--r--contrib/llvm/lib/Support/ThreadPool.cpp155
-rw-r--r--contrib/llvm/lib/Support/TimeValue.cpp6
-rw-r--r--contrib/llvm/lib/Support/Timer.cpp74
-rw-r--r--contrib/llvm/lib/Support/Triple.cpp209
-rw-r--r--contrib/llvm/lib/Support/Unix/Memory.inc15
-rw-r--r--contrib/llvm/lib/Support/Unix/Path.inc120
-rw-r--r--contrib/llvm/lib/Support/Unix/Process.inc13
-rw-r--r--contrib/llvm/lib/Support/Unix/Program.inc7
-rw-r--r--contrib/llvm/lib/Support/Unix/Signals.inc151
-rw-r--r--contrib/llvm/lib/Support/Unix/Unix.h13
-rw-r--r--contrib/llvm/lib/Support/Valgrind.cpp21
-rw-r--r--contrib/llvm/lib/Support/Windows/COM.inc2
-rw-r--r--contrib/llvm/lib/Support/Windows/DynamicLibrary.inc4
-rw-r--r--contrib/llvm/lib/Support/Windows/Memory.inc4
-rw-r--r--contrib/llvm/lib/Support/Windows/Path.inc107
-rw-r--r--contrib/llvm/lib/Support/Windows/Process.inc11
-rw-r--r--contrib/llvm/lib/Support/Windows/Program.inc25
-rw-r--r--contrib/llvm/lib/Support/Windows/Signals.inc129
-rw-r--r--contrib/llvm/lib/Support/Windows/WindowsSupport.h18
-rw-r--r--contrib/llvm/lib/Support/YAMLParser.cpp18
-rw-r--r--contrib/llvm/lib/Support/YAMLTraits.cpp16
-rw-r--r--contrib/llvm/lib/Support/raw_ostream.cpp83
44 files changed, 1671 insertions, 937 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp
index 5d31225..19b8221 100644
--- a/contrib/llvm/lib/Support/APFloat.cpp
+++ b/contrib/llvm/lib/Support/APFloat.cpp
@@ -768,6 +768,15 @@ APFloat::isLargest() const {
}
bool
+APFloat::isInteger() const {
+ // This could be made more efficient; I'm going for obviously correct.
+ if (!isFinite()) return false;
+ APFloat truncated = *this;
+ truncated.roundToIntegral(rmTowardZero);
+ return compare(truncated) == cmpEqual;
+}
+
+bool
APFloat::bitwiseIsEqual(const APFloat &rhs) const {
if (this == &rhs)
return true;
@@ -777,18 +786,12 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
return false;
if (category==fcZero || category==fcInfinity)
return true;
- else if (isFiniteNonZero() && exponent!=rhs.exponent)
+
+ if (isFiniteNonZero() && exponent != rhs.exponent)
return false;
- else {
- int i= partCount();
- const integerPart* p=significandParts();
- const integerPart* q=rhs.significandParts();
- for (; i>0; i--, p++, q++) {
- if (*p != *q)
- return false;
- }
- return true;
- }
+
+ return std::equal(significandParts(), significandParts() + partCount(),
+ rhs.significandParts());
}
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
@@ -847,6 +850,21 @@ APFloat::semanticsPrecision(const fltSemantics &semantics)
{
return semantics.precision;
}
+APFloat::ExponentType
+APFloat::semanticsMaxExponent(const fltSemantics &semantics)
+{
+ return semantics.maxExponent;
+}
+APFloat::ExponentType
+APFloat::semanticsMinExponent(const fltSemantics &semantics)
+{
+ return semantics.minExponent;
+}
+unsigned int
+APFloat::semanticsSizeInBits(const fltSemantics &semantics)
+{
+ return semantics.sizeInBits;
+}
const integerPart *
APFloat::significandParts() const
@@ -1762,7 +1780,7 @@ APFloat::remainder(const APFloat &rhs)
/* Normalized llvm frem (C fmod).
This is not currently correct in all cases. */
APFloat::opStatus
-APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
+APFloat::mod(const APFloat &rhs)
{
opStatus fs;
fs = modSpecials(rhs);
@@ -1787,10 +1805,10 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
rmNearestTiesToEven);
assert(fs==opOK); // should always work
- fs = V.multiply(rhs, rounding_mode);
+ fs = V.multiply(rhs, rmNearestTiesToEven);
assert(fs==opOK || fs==opInexact); // should not overflow or underflow
- fs = subtract(V, rounding_mode);
+ fs = subtract(V, rmNearestTiesToEven);
assert(fs==opOK || fs==opInexact); // likewise
if (isZero())
diff --git a/contrib/llvm/lib/Support/BlockFrequency.cpp b/contrib/llvm/lib/Support/BlockFrequency.cpp
index 6f7e341..e7f3e17 100644
--- a/contrib/llvm/lib/Support/BlockFrequency.cpp
+++ b/contrib/llvm/lib/Support/BlockFrequency.cpp
@@ -11,37 +11,35 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
using namespace llvm;
-BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {
+BlockFrequency &BlockFrequency::operator*=(BranchProbability Prob) {
Frequency = Prob.scale(Frequency);
return *this;
}
-const BlockFrequency
-BlockFrequency::operator*(const BranchProbability &Prob) const {
+BlockFrequency BlockFrequency::operator*(BranchProbability Prob) const {
BlockFrequency Freq(Frequency);
Freq *= Prob;
return Freq;
}
-BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) {
+BlockFrequency &BlockFrequency::operator/=(BranchProbability Prob) {
Frequency = Prob.scaleByInverse(Frequency);
return *this;
}
-BlockFrequency BlockFrequency::operator/(const BranchProbability &Prob) const {
+BlockFrequency BlockFrequency::operator/(BranchProbability Prob) const {
BlockFrequency Freq(Frequency);
Freq /= Prob;
return Freq;
}
-BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
+BlockFrequency &BlockFrequency::operator+=(BlockFrequency Freq) {
uint64_t Before = Freq.Frequency;
Frequency += Freq.Frequency;
@@ -52,11 +50,25 @@ BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
return *this;
}
-const BlockFrequency
-BlockFrequency::operator+(const BlockFrequency &Prob) const {
- BlockFrequency Freq(Frequency);
- Freq += Prob;
- return Freq;
+BlockFrequency BlockFrequency::operator+(BlockFrequency Freq) const {
+ BlockFrequency NewFreq(Frequency);
+ NewFreq += Freq;
+ return NewFreq;
+}
+
+BlockFrequency &BlockFrequency::operator-=(BlockFrequency Freq) {
+ // If underflow, set frequency to 0.
+ if (Frequency <= Freq.Frequency)
+ Frequency = 0;
+ else
+ Frequency -= Freq.Frequency;
+ return *this;
+}
+
+BlockFrequency BlockFrequency::operator-(BlockFrequency Freq) const {
+ BlockFrequency NewFreq(Frequency);
+ NewFreq -= Freq;
+ return NewFreq;
}
BlockFrequency &BlockFrequency::operator>>=(const unsigned count) {
diff --git a/contrib/llvm/lib/Support/BranchProbability.cpp b/contrib/llvm/lib/Support/BranchProbability.cpp
index 65878d6..771d02c 100644
--- a/contrib/llvm/lib/Support/BranchProbability.cpp
+++ b/contrib/llvm/lib/Support/BranchProbability.cpp
@@ -15,17 +15,58 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
using namespace llvm;
+const uint32_t BranchProbability::D;
+
raw_ostream &BranchProbability::print(raw_ostream &OS) const {
- return OS << N << " / " << D << " = "
- << format("%g%%", ((double)N / D) * 100.0);
+ if (isUnknown())
+ return OS << "?%";
+
+ // Get a percentage rounded to two decimal digits. This avoids
+ // implementation-defined rounding inside printf.
+ double Percent = rint(((double)N / D) * 100.0 * 100.0) / 100.0;
+ return OS << format("0x%08" PRIx32 " / 0x%08" PRIx32 " = %.2f%%", N, D,
+ Percent);
}
void BranchProbability::dump() const { print(dbgs()) << '\n'; }
+BranchProbability::BranchProbability(uint32_t Numerator, uint32_t Denominator) {
+ assert(Denominator > 0 && "Denominator cannot be 0!");
+ assert(Numerator <= Denominator && "Probability cannot be bigger than 1!");
+ if (Denominator == D)
+ N = Numerator;
+ else {
+ uint64_t Prob64 =
+ (Numerator * static_cast<uint64_t>(D) + Denominator / 2) / Denominator;
+ N = static_cast<uint32_t>(Prob64);
+ }
+}
+
+BranchProbability
+BranchProbability::getBranchProbability(uint64_t Numerator,
+ uint64_t Denominator) {
+ assert(Numerator <= Denominator && "Probability cannot be bigger than 1!");
+ // Scale down Denominator to fit in a 32-bit integer.
+ int Scale = 0;
+ while (Denominator > UINT32_MAX) {
+ Denominator >>= 1;
+ Scale++;
+ }
+ return BranchProbability(Numerator >> Scale, Denominator);
+}
+
+// If ConstD is not zero, then replace D by ConstD so that division and modulo
+// operations by D can be optimized, in case this function is not inlined by the
+// compiler.
+template <uint32_t ConstD>
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
+ if (ConstD > 0)
+ D = ConstD;
+
assert(D && "divide by 0");
// Fast path for multiplying by 1.0.
@@ -65,9 +106,9 @@ static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) {
}
uint64_t BranchProbability::scale(uint64_t Num) const {
- return ::scale(Num, N, D);
+ return ::scale<D>(Num, N, D);
}
uint64_t BranchProbability::scaleByInverse(uint64_t Num) const {
- return ::scale(Num, D, N);
+ return ::scale<0>(Num, D, N);
}
diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp
index 17fba95..fdcdb03 100644
--- a/contrib/llvm/lib/Support/CommandLine.cpp
+++ b/contrib/llvm/lib/Support/CommandLine.cpp
@@ -120,7 +120,7 @@ public:
void addOption(Option *O) {
bool HadErrors = false;
- if (O->ArgStr[0]) {
+ if (O->hasArgStr()) {
// Add argument to the argument map!
if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
@@ -151,12 +151,12 @@ public:
}
void removeOption(Option *O) {
- SmallVector<const char *, 16> OptionNames;
+ SmallVector<StringRef, 16> OptionNames;
O->getExtraOptionNames(OptionNames);
- if (O->ArgStr[0])
+ if (O->hasArgStr())
OptionNames.push_back(O->ArgStr);
for (auto Name : OptionNames)
- OptionsMap.erase(StringRef(Name));
+ OptionsMap.erase(Name);
if (O->getFormattingFlag() == cl::Positional)
for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end();
@@ -182,13 +182,13 @@ public:
nullptr != ConsumeAfterOpt);
}
- void updateArgStr(Option *O, const char *NewName) {
+ void updateArgStr(Option *O, StringRef NewName) {
if (!OptionsMap.insert(std::make_pair(NewName, O)).second) {
errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
<< "' registered more than once!\n";
report_fatal_error("inconsistency in registered CommandLine options");
}
- OptionsMap.erase(StringRef(O->ArgStr));
+ OptionsMap.erase(O->ArgStr);
}
void printOptionValues();
@@ -227,7 +227,7 @@ void Option::addArgument() {
void Option::removeArgument() { GlobalParser->removeOption(this); }
-void Option::setArgStr(const char *S) {
+void Option::setArgStr(StringRef S) {
if (FullyInitialized)
GlobalParser->updateArgStr(this, S);
ArgStr = S;
@@ -296,24 +296,23 @@ static Option *LookupNearestOption(StringRef Arg,
ie = OptionsMap.end();
it != ie; ++it) {
Option *O = it->second;
- SmallVector<const char *, 16> OptionNames;
+ SmallVector<StringRef, 16> OptionNames;
O->getExtraOptionNames(OptionNames);
- if (O->ArgStr[0])
+ if (O->hasArgStr())
OptionNames.push_back(O->ArgStr);
bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed;
StringRef Flag = PermitValue ? LHS : Arg;
- for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
- StringRef Name = OptionNames[i];
+ for (auto Name : OptionNames) {
unsigned Distance = StringRef(Name).edit_distance(
Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
if (!Best || Distance < BestDistance) {
Best = O;
BestDistance = Distance;
if (RHS.empty() || !PermitValue)
- NearestString = OptionNames[i];
+ NearestString = Name;
else
- NearestString = (Twine(OptionNames[i]) + "=" + RHS).str();
+ NearestString = (Twine(Name) + "=" + RHS).str();
}
}
}
@@ -346,10 +345,7 @@ static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,
Value = Val;
}
- if (Handler->addOccurrence(pos, ArgName, Value, MultiArg))
- return true;
-
- return false;
+ return Handler->addOccurrence(pos, ArgName, Value, MultiArg);
}
/// ProvideOption - For Value, this differentiates between an empty value ("")
@@ -799,7 +795,7 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
// telling us.
SmallVector<const char *, 20> newArgv;
BumpPtrAllocator A;
- BumpPtrStringSaver Saver(A);
+ StringSaver Saver(A);
newArgv.push_back(Saver.save(progName));
// Parse the value of the environment variable into a "command line"
@@ -822,7 +818,7 @@ void CommandLineParser::ParseCommandLineOptions(int argc,
// Expand response files.
SmallVector<const char *, 20> newArgv(argv, argv + argc);
BumpPtrAllocator A;
- BumpPtrStringSaver Saver(A);
+ StringSaver Saver(A);
ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv);
argv = &newArgv[0];
argc = static_cast<int>(newArgv.size());
@@ -859,7 +855,7 @@ void CommandLineParser::ParseCommandLineOptions(int argc,
"error - this positional option will never be matched, "
"because it does not Require a value, and a "
"cl::ConsumeAfter option is active!");
- } else if (UnboundedFound && !Opt->ArgStr[0]) {
+ } else if (UnboundedFound && !Opt->hasArgStr()) {
// This option does not "require" a value... Make sure this option is
// not specified after an option that eats all extra arguments, or this
// one will never get any!
@@ -1144,8 +1140,8 @@ bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,
// getValueStr - Get the value description string, using "DefaultMsg" if nothing
// has been specified yet.
//
-static const char *getValueStr(const Option &O, const char *DefaultMsg) {
- if (O.ValueStr[0] == 0)
+static StringRef getValueStr(const Option &O, StringRef DefaultMsg) {
+ if (O.ValueStr.empty())
return DefaultMsg;
return O.ValueStr;
}
@@ -1155,7 +1151,7 @@ static const char *getValueStr(const Option &O, const char *DefaultMsg) {
//
// Return the width of the option tag for printing...
-size_t alias::getOptionWidth() const { return std::strlen(ArgStr) + 6; }
+size_t alias::getOptionWidth() const { return ArgStr.size() + 6; }
static void printHelpStr(StringRef HelpStr, size_t Indent,
size_t FirstLineIndentedBy) {
@@ -1170,7 +1166,7 @@ static void printHelpStr(StringRef HelpStr, size_t Indent,
// Print out the option for the alias.
void alias::printOptionInfo(size_t GlobalWidth) const {
outs() << " -" << ArgStr;
- printHelpStr(HelpStr, GlobalWidth, std::strlen(ArgStr) + 6);
+ printHelpStr(HelpStr, GlobalWidth, ArgStr.size() + 6);
}
//===----------------------------------------------------------------------===//
@@ -1182,9 +1178,9 @@ void alias::printOptionInfo(size_t GlobalWidth) const {
// Return the width of the option tag for printing...
size_t basic_parser_impl::getOptionWidth(const Option &O) const {
- size_t Len = std::strlen(O.ArgStr);
+ size_t Len = O.ArgStr.size();
if (const char *ValName = getValueName())
- Len += std::strlen(getValueStr(O, ValName)) + 3;
+ Len += getValueStr(O, ValName).size() + 3;
return Len + 6;
}
@@ -1205,7 +1201,7 @@ void basic_parser_impl::printOptionInfo(const Option &O,
void basic_parser_impl::printOptionName(const Option &O,
size_t GlobalWidth) const {
outs() << " -" << O.ArgStr;
- outs().indent(GlobalWidth - std::strlen(O.ArgStr));
+ outs().indent(GlobalWidth - O.ArgStr.size());
}
// parser<bool> implementation
@@ -1319,7 +1315,7 @@ unsigned generic_parser_base::findOption(const char *Name) {
// Return the width of the option tag for printing...
size_t generic_parser_base::getOptionWidth(const Option &O) const {
if (O.hasArgStr()) {
- size_t Size = std::strlen(O.ArgStr) + 6;
+ size_t Size = O.ArgStr.size() + 6;
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
Size = std::max(Size, std::strlen(getOption(i)) + 8);
return Size;
@@ -1338,7 +1334,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
size_t GlobalWidth) const {
if (O.hasArgStr()) {
outs() << " -" << O.ArgStr;
- printHelpStr(O.HelpStr, GlobalWidth, std::strlen(O.ArgStr) + 6);
+ printHelpStr(O.HelpStr, GlobalWidth, O.ArgStr.size() + 6);
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
size_t NumSpaces = GlobalWidth - strlen(getOption(i)) - 8;
@@ -1346,7 +1342,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
outs().indent(NumSpaces) << " - " << getDescription(i) << '\n';
}
} else {
- if (O.HelpStr[0])
+ if (!O.HelpStr.empty())
outs() << " " << O.HelpStr << '\n';
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
const char *Option = getOption(i);
@@ -1365,7 +1361,7 @@ void generic_parser_base::printGenericOptionDiff(
const Option &O, const GenericOptionValue &Value,
const GenericOptionValue &Default, size_t GlobalWidth) const {
outs() << " -" << O.ArgStr;
- outs().indent(GlobalWidth - std::strlen(O.ArgStr));
+ outs().indent(GlobalWidth - O.ArgStr.size());
unsigned NumOpts = getNumOptions();
for (unsigned i = 0; i != NumOpts; ++i) {
@@ -1508,7 +1504,7 @@ public:
outs() << "USAGE: " << GlobalParser->ProgramName << " [options]";
for (auto Opt : GlobalParser->PositionalOpts) {
- if (Opt->ArgStr[0])
+ if (Opt->hasArgStr())
outs() << " --" << Opt->ArgStr;
outs() << " " << Opt->HelpStr;
}
diff --git a/contrib/llvm/lib/Support/CrashRecoveryContext.cpp b/contrib/llvm/lib/Support/CrashRecoveryContext.cpp
index aba0f1d..3f4ef9d 100644
--- a/contrib/llvm/lib/Support/CrashRecoveryContext.cpp
+++ b/contrib/llvm/lib/Support/CrashRecoveryContext.cpp
@@ -24,6 +24,12 @@ static ManagedStatic<
sys::ThreadLocal<const CrashRecoveryContextImpl> > CurrentContext;
struct CrashRecoveryContextImpl {
+ // When threads are disabled, this links up all active
+ // CrashRecoveryContextImpls. When threads are enabled there's one thread
+ // per CrashRecoveryContext and CurrentContext is a thread-local, so only one
+ // CrashRecoveryContextImpl is active per thread and this is always null.
+ const CrashRecoveryContextImpl *Next;
+
CrashRecoveryContext *CRC;
std::string Backtrace;
::jmp_buf JumpBuffer;
@@ -34,21 +40,26 @@ public:
CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC),
Failed(false),
SwitchedThread(false) {
+ Next = CurrentContext->get();
CurrentContext->set(this);
}
~CrashRecoveryContextImpl() {
if (!SwitchedThread)
- CurrentContext->erase();
+ CurrentContext->set(Next);
}
/// \brief Called when the separate crash-recovery thread was finished, to
/// indicate that we don't need to clear the thread-local CurrentContext.
- void setSwitchedThread() { SwitchedThread = true; }
+ void setSwitchedThread() {
+#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
+ SwitchedThread = true;
+#endif
+ }
void HandleCrash() {
// Eliminate the current context entry, to avoid re-entering in case the
// cleanup code crashes.
- CurrentContext->erase();
+ CurrentContext->set(Next);
assert(!Failed && "Crash recovery context already failed!");
Failed = true;
@@ -65,7 +76,7 @@ public:
static ManagedStatic<sys::Mutex> gCrashRecoveryContextMutex;
static bool gCrashRecoveryEnabled = false;
-static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContextCleanup> >
+static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContext>>
tlIsRecoveringFromCrash;
CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
@@ -73,7 +84,8 @@ CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
CrashRecoveryContext::~CrashRecoveryContext() {
// Reclaim registered resources.
CrashRecoveryContextCleanup *i = head;
- tlIsRecoveringFromCrash->set(head);
+ const CrashRecoveryContext *PC = tlIsRecoveringFromCrash->get();
+ tlIsRecoveringFromCrash->set(this);
while (i) {
CrashRecoveryContextCleanup *tmp = i;
i = tmp->next;
@@ -81,7 +93,7 @@ CrashRecoveryContext::~CrashRecoveryContext() {
tmp->recoverResources();
delete tmp;
}
- tlIsRecoveringFromCrash->erase();
+ tlIsRecoveringFromCrash->set(PC);
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
delete CRCI;
@@ -232,7 +244,7 @@ void CrashRecoveryContext::Disable() {
static const int Signals[] =
{ SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP };
-static const unsigned NumSignals = sizeof(Signals) / sizeof(Signals[0]);
+static const unsigned NumSignals = array_lengthof(Signals);
static struct sigaction PrevActions[NumSignals];
static void CrashRecoverySignalHandler(int Signal) {
diff --git a/contrib/llvm/lib/Support/Dwarf.cpp b/contrib/llvm/lib/Support/Dwarf.cpp
index 13a4155..7d72256 100644
--- a/contrib/llvm/lib/Support/Dwarf.cpp
+++ b/contrib/llvm/lib/Support/Dwarf.cpp
@@ -177,6 +177,23 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
case DW_AT_MIPS_assumed_size: return "DW_AT_MIPS_assumed_size";
case DW_AT_lo_user: return "DW_AT_lo_user";
case DW_AT_hi_user: return "DW_AT_hi_user";
+ case DW_AT_BORLAND_property_read: return "DW_AT_BORLAND_property_read";
+ case DW_AT_BORLAND_property_write: return "DW_AT_BORLAND_property_write";
+ case DW_AT_BORLAND_property_implements: return "DW_AT_BORLAND_property_implements";
+ case DW_AT_BORLAND_property_index: return "DW_AT_BORLAND_property_index";
+ case DW_AT_BORLAND_property_default: return "DW_AT_BORLAND_property_default";
+ case DW_AT_BORLAND_Delphi_unit: return "DW_AT_BORLAND_Delphi_unit";
+ case DW_AT_BORLAND_Delphi_class: return "DW_AT_BORLAND_Delphi_class";
+ case DW_AT_BORLAND_Delphi_record: return "DW_AT_BORLAND_Delphi_record";
+ case DW_AT_BORLAND_Delphi_metaclass: return "DW_AT_BORLAND_Delphi_metaclass";
+ case DW_AT_BORLAND_Delphi_constructor: return "DW_AT_BORLAND_Delphi_constructor";
+ case DW_AT_BORLAND_Delphi_destructor: return "DW_AT_BORLAND_Delphi_destructor";
+ case DW_AT_BORLAND_Delphi_anonymous_method: return "DW_AT_BORLAND_Delphi_anonymous_method";
+ case DW_AT_BORLAND_Delphi_interface: return "DW_AT_BORLAND_Delphi_interface";
+ case DW_AT_BORLAND_Delphi_ABI: return "DW_AT_BORLAND_Delphi_ABI";
+ case DW_AT_BORLAND_Delphi_return: return "DW_AT_BORLAND_Delphi_return";
+ case DW_AT_BORLAND_Delphi_frameptr: return "DW_AT_BORLAND_Delphi_frameptr";
+ case DW_AT_BORLAND_closure: return "DW_AT_BORLAND_closure";
case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized";
case DW_AT_APPLE_flags: return "DW_AT_APPLE_flags";
case DW_AT_APPLE_isa: return "DW_AT_APPLE_isa";
@@ -201,6 +218,7 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
case DW_AT_GNU_addr_base: return "DW_AT_GNU_addr_base";
case DW_AT_GNU_pubnames: return "DW_AT_GNU_pubnames";
case DW_AT_GNU_pubtypes: return "DW_AT_GNU_pubtypes";
+ case DW_AT_GNU_discriminator: return "DW_AT_GNU_discriminator";
}
return nullptr;
}
@@ -373,6 +391,14 @@ const char *llvm::dwarf::ConventionString(unsigned Convention) {
case DW_CC_nocall: return "DW_CC_nocall";
case DW_CC_lo_user: return "DW_CC_lo_user";
case DW_CC_hi_user: return "DW_CC_hi_user";
+ case DW_CC_GNU_borland_fastcall_i386: return "DW_CC_GNU_borland_fastcall_i386";
+ case DW_CC_BORLAND_safecall: return "DW_CC_BORLAND_safecall";
+ case DW_CC_BORLAND_stdcall: return "DW_CC_BORLAND_stdcall";
+ case DW_CC_BORLAND_pascal: return "DW_CC_BORLAND_pascal";
+ case DW_CC_BORLAND_msfastcall: return "DW_CC_BORLAND_msfastcall";
+ case DW_CC_BORLAND_msreturn: return "DW_CC_BORLAND_msreturn";
+ case DW_CC_BORLAND_thiscall: return "DW_CC_BORLAND_thiscall";
+ case DW_CC_BORLAND_fastcall: return "DW_CC_BORLAND_fastcall";
}
return nullptr;
}
@@ -442,10 +468,21 @@ const char *llvm::dwarf::MacinfoString(unsigned Encoding) {
case DW_MACINFO_start_file: return "DW_MACINFO_start_file";
case DW_MACINFO_end_file: return "DW_MACINFO_end_file";
case DW_MACINFO_vendor_ext: return "DW_MACINFO_vendor_ext";
+ case DW_MACINFO_invalid: return "DW_MACINFO_invalid";
}
return nullptr;
}
+unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) {
+ return StringSwitch<unsigned>(MacinfoString)
+ .Case("DW_MACINFO_define", DW_MACINFO_define)
+ .Case("DW_MACINFO_undef", DW_MACINFO_undef)
+ .Case("DW_MACINFO_start_file", DW_MACINFO_start_file)
+ .Case("DW_MACINFO_end_file", DW_MACINFO_end_file)
+ .Case("DW_MACINFO_vendor_ext", DW_MACINFO_vendor_ext)
+ .Default(DW_MACINFO_invalid);
+}
+
const char *llvm::dwarf::CallFrameString(unsigned Encoding) {
switch (Encoding) {
case DW_CFA_nop: return "DW_CFA_nop";
diff --git a/contrib/llvm/lib/Support/ErrorHandling.cpp b/contrib/llvm/lib/Support/ErrorHandling.cpp
index a25e21a..2808bd3 100644
--- a/contrib/llvm/lib/Support/ErrorHandling.cpp
+++ b/contrib/llvm/lib/Support/ErrorHandling.cpp
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ErrorHandling.h"
-#include "llvm-c/Core.h"
+#include "llvm-c/ErrorHandling.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h"
diff --git a/contrib/llvm/lib/Support/FileOutputBuffer.cpp b/contrib/llvm/lib/Support/FileOutputBuffer.cpp
index 307ff09..651e679 100644
--- a/contrib/llvm/lib/Support/FileOutputBuffer.cpp
+++ b/contrib/llvm/lib/Support/FileOutputBuffer.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/Signals.h"
#include <system_error>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
@@ -34,10 +35,8 @@ FileOutputBuffer::~FileOutputBuffer() {
sys::fs::remove(Twine(TempPath));
}
-std::error_code
-FileOutputBuffer::create(StringRef FilePath, size_t Size,
- std::unique_ptr<FileOutputBuffer> &Result,
- unsigned Flags) {
+ErrorOr<std::unique_ptr<FileOutputBuffer>>
+FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) {
// If file already exists, it must be a regular file (to be mappable).
sys::fs::file_status Stat;
std::error_code EC = sys::fs::status(FilePath, Stat);
@@ -76,6 +75,8 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size,
if (EC)
return EC;
+ sys::RemoveFileOnSignal(TempFilePath);
+
#ifndef LLVM_ON_WIN32
// On Windows, CreateFileMapping (the mmap function on Windows)
// automatically extends the underlying file. We don't need to
@@ -95,10 +96,9 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size,
if (Ret)
return std::error_code(errno, std::generic_category());
- Result.reset(
+ std::unique_ptr<FileOutputBuffer> Buf(
new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath));
-
- return std::error_code();
+ return std::move(Buf);
}
std::error_code FileOutputBuffer::commit() {
@@ -107,6 +107,8 @@ std::error_code FileOutputBuffer::commit() {
// Rename file to final name.
- return sys::fs::rename(Twine(TempPath), Twine(FinalPath));
+ std::error_code EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath));
+ sys::DontRemoveFileOnSignal(TempPath);
+ return EC;
}
} // namespace
diff --git a/contrib/llvm/lib/Support/FoldingSet.cpp b/contrib/llvm/lib/Support/FoldingSet.cpp
index b8538ff..bb0ec2d 100644
--- a/contrib/llvm/lib/Support/FoldingSet.cpp
+++ b/contrib/llvm/lib/Support/FoldingSet.cpp
@@ -232,9 +232,29 @@ FoldingSetImpl::FoldingSetImpl(unsigned Log2InitSize) {
Buckets = AllocateBuckets(NumBuckets);
NumNodes = 0;
}
+
+FoldingSetImpl::FoldingSetImpl(FoldingSetImpl &&Arg)
+ : Buckets(Arg.Buckets), NumBuckets(Arg.NumBuckets), NumNodes(Arg.NumNodes) {
+ Arg.Buckets = nullptr;
+ Arg.NumBuckets = 0;
+ Arg.NumNodes = 0;
+}
+
+FoldingSetImpl &FoldingSetImpl::operator=(FoldingSetImpl &&RHS) {
+ free(Buckets); // This may be null if the set is in a moved-from state.
+ Buckets = RHS.Buckets;
+ NumBuckets = RHS.NumBuckets;
+ NumNodes = RHS.NumNodes;
+ RHS.Buckets = nullptr;
+ RHS.NumBuckets = 0;
+ RHS.NumNodes = 0;
+ return *this;
+}
+
FoldingSetImpl::~FoldingSetImpl() {
free(Buckets);
}
+
void FoldingSetImpl::clear() {
// Set all but the last bucket to null pointers.
memset(Buckets, 0, NumBuckets*sizeof(void*));
diff --git a/contrib/llvm/lib/Support/GraphWriter.cpp b/contrib/llvm/lib/Support/GraphWriter.cpp
index a9b0220..d0e1d50 100644
--- a/contrib/llvm/lib/Support/GraphWriter.cpp
+++ b/contrib/llvm/lib/Support/GraphWriter.cpp
@@ -103,7 +103,7 @@ struct GraphSession {
bool TryFindProgram(StringRef Names, std::string &ProgramPath) {
raw_string_ostream Log(LogBuffer);
SmallVector<StringRef, 8> parts;
- Names.split(parts, "|");
+ Names.split(parts, '|');
for (auto Name : parts) {
if (ErrorOr<std::string> P = sys::findProgramByName(Name)) {
ProgramPath = *P;
@@ -189,61 +189,87 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg);
}
- enum PSViewerKind { PSV_None, PSV_OSXOpen, PSV_XDGOpen, PSV_Ghostview };
- PSViewerKind PSViewer = PSV_None;
+ enum ViewerKind {
+ VK_None,
+ VK_OSXOpen,
+ VK_XDGOpen,
+ VK_Ghostview,
+ VK_CmdStart
+ };
+ ViewerKind Viewer = VK_None;
#ifdef __APPLE__
- if (!PSViewer && S.TryFindProgram("open", ViewerPath))
- PSViewer = PSV_OSXOpen;
+ if (!Viewer && S.TryFindProgram("open", ViewerPath))
+ Viewer = VK_OSXOpen;
+#endif
+ if (!Viewer && S.TryFindProgram("gv", ViewerPath))
+ Viewer = VK_Ghostview;
+ if (!Viewer && S.TryFindProgram("xdg-open", ViewerPath))
+ Viewer = VK_XDGOpen;
+#ifdef LLVM_ON_WIN32
+ if (!Viewer && S.TryFindProgram("cmd", ViewerPath)) {
+ Viewer = VK_CmdStart;
+ }
#endif
- if (!PSViewer && S.TryFindProgram("gv", ViewerPath))
- PSViewer = PSV_Ghostview;
- if (!PSViewer && S.TryFindProgram("xdg-open", ViewerPath))
- PSViewer = PSV_XDGOpen;
- // PostScript graph generator + PostScript viewer
+ // PostScript or PDF graph generator + PostScript/PDF viewer
std::string GeneratorPath;
- if (PSViewer &&
+ if (Viewer &&
(S.TryFindProgram(getProgramName(program), GeneratorPath) ||
S.TryFindProgram("dot|fdp|neato|twopi|circo", GeneratorPath))) {
- std::string PSFilename = Filename + ".ps";
+ std::string OutputFilename =
+ Filename + (Viewer == VK_CmdStart ? ".pdf" : ".ps");
std::vector<const char *> args;
args.push_back(GeneratorPath.c_str());
- args.push_back("-Tps");
+ if (Viewer == VK_CmdStart)
+ args.push_back("-Tpdf");
+ else
+ args.push_back("-Tps");
args.push_back("-Nfontname=Courier");
args.push_back("-Gsize=7.5,10");
args.push_back(Filename.c_str());
args.push_back("-o");
- args.push_back(PSFilename.c_str());
+ args.push_back(OutputFilename.c_str());
args.push_back(nullptr);
errs() << "Running '" << GeneratorPath << "' program... ";
- if (ExecGraphViewer(GeneratorPath, args, Filename, wait, ErrMsg))
+ if (ExecGraphViewer(GeneratorPath, args, Filename, true, ErrMsg))
return true;
+ // The lifetime of StartArg must include the call of ExecGraphViewer
+ // because the args are passed as vector of char*.
+ std::string StartArg;
+
args.clear();
args.push_back(ViewerPath.c_str());
- switch (PSViewer) {
- case PSV_OSXOpen:
+ switch (Viewer) {
+ case VK_OSXOpen:
args.push_back("-W");
- args.push_back(PSFilename.c_str());
+ args.push_back(OutputFilename.c_str());
break;
- case PSV_XDGOpen:
+ case VK_XDGOpen:
wait = false;
- args.push_back(PSFilename.c_str());
+ args.push_back(OutputFilename.c_str());
break;
- case PSV_Ghostview:
+ case VK_Ghostview:
args.push_back("--spartan");
- args.push_back(PSFilename.c_str());
+ args.push_back(OutputFilename.c_str());
+ break;
+ case VK_CmdStart:
+ args.push_back("/S");
+ args.push_back("/C");
+ StartArg =
+ (StringRef("start ") + (wait ? "/WAIT " : "") + OutputFilename).str();
+ args.push_back(StartArg.c_str());
break;
- case PSV_None:
+ case VK_None:
llvm_unreachable("Invalid viewer");
}
args.push_back(nullptr);
ErrMsg.clear();
- return ExecGraphViewer(ViewerPath, args, PSFilename, wait, ErrMsg);
+ return ExecGraphViewer(ViewerPath, args, OutputFilename, wait, ErrMsg);
}
// dotty
diff --git a/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp
index 1bd1fe2..c0f9e07 100644
--- a/contrib/llvm/lib/Support/Host.cpp
+++ b/contrib/llvm/lib/Support/Host.cpp
@@ -368,8 +368,14 @@ StringRef sys::getHostCPUName() {
// Broadwell:
case 61:
+ case 71:
return "broadwell";
+ // Skylake:
+ case 78:
+ case 94:
+ return "skylake";
+
case 28: // Most 45 nm Intel Atom processors
case 38: // 45 nm Atom Lincroft
case 39: // 32 nm Atom Medfield
@@ -381,6 +387,8 @@ StringRef sys::getHostCPUName() {
case 55:
case 74:
case 77:
+ case 90:
+ case 93:
return "silvermont";
default: // Unknown family 6 CPU, try to guess.
@@ -689,7 +697,7 @@ StringRef sys::getHostCPUName() {
if (Lines[I].startswith("features")) {
size_t Pos = Lines[I].find(":");
if (Pos != StringRef::npos) {
- Lines[I].drop_front(Pos + 1).split(CPUFeatures, " ");
+ Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
break;
}
}
@@ -766,14 +774,17 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
// If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
// indicates that the AVX registers will be saved and restored on context
// switch, then we have full AVX support.
- bool HasAVX = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
- !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
- Features["avx"] = HasAVX;
- Features["fma"] = HasAVX && (ECX >> 12) & 1;
- Features["f16c"] = HasAVX && (ECX >> 29) & 1;
+ bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
+ !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
+ Features["avx"] = HasAVXSave;
+ Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
+ Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
+
+ // Only enable XSAVE if OS has enabled support for saving YMM state.
+ Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
// AVX512 requires additional context to be saved by the OS.
- bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
+ bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
unsigned MaxExtLevel;
GetX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
@@ -783,15 +794,15 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
- Features["xop"] = HasAVX && HasExtLeaf1 && ((ECX >> 11) & 1);
- Features["fma4"] = HasAVX && HasExtLeaf1 && ((ECX >> 16) & 1);
+ Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
+ Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
bool HasLeaf7 = MaxLevel >= 7 &&
!GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
// AVX2 is only supported if we have the OS save support from AVX.
- Features["avx2"] = HasAVX && HasLeaf7 && (EBX >> 5) & 1;
+ Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
@@ -801,6 +812,8 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
+ // Enable protection keys
+ Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
// AVX512 is only supported if the OS supports the context save for it.
Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
@@ -811,6 +824,14 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
+ bool HasLeafD = MaxLevel >= 0xd &&
+ !GetX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
+
+ // Only enable XSAVE if OS has enabled support for saving YMM state.
+ Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
+ Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
+ Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
+
return true;
}
#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
@@ -832,7 +853,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
// Look for the CPU features.
for (unsigned I = 0, E = Lines.size(); I != E; ++I)
if (Lines[I].startswith("Features")) {
- Lines[I].split(CPUFeatures, " ");
+ Lines[I].split(CPUFeatures, ' ');
break;
}
diff --git a/contrib/llvm/lib/Support/JamCRC.cpp b/contrib/llvm/lib/Support/JamCRC.cpp
new file mode 100644
index 0000000..bc21c91
--- /dev/null
+++ b/contrib/llvm/lib/Support/JamCRC.cpp
@@ -0,0 +1,96 @@
+//===-- JamCRC.cpp - Cyclic Redundancy Check --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an implementation of JamCRC.
+//
+//===----------------------------------------------------------------------===//
+//
+// The implementation technique is the one mentioned in:
+// D. V. Sarwate. 1988. Computation of cyclic redundancy checks via table
+// look-up. Commun. ACM 31, 8 (August 1988)
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/JamCRC.h"
+
+using namespace llvm;
+
+static const uint32_t CRCTable[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+void JamCRC::update(ArrayRef<char> Data) {
+ for (char Byte : Data) {
+ int TableIdx = (CRC ^ Byte) & 0xff;
+ CRC = CRCTable[TableIdx] ^ (CRC >> 8);
+ }
+}
diff --git a/contrib/llvm/lib/Support/Locale.cpp b/contrib/llvm/lib/Support/Locale.cpp
index d5cb72b..53bc0e3 100644
--- a/contrib/llvm/lib/Support/Locale.cpp
+++ b/contrib/llvm/lib/Support/Locale.cpp
@@ -1,3 +1,4 @@
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Locale.h"
#include "llvm/Support/Unicode.h"
diff --git a/contrib/llvm/lib/Support/ManagedStatic.cpp b/contrib/llvm/lib/Support/ManagedStatic.cpp
index b8fb284..9868207 100644
--- a/contrib/llvm/lib/Support/ManagedStatic.cpp
+++ b/contrib/llvm/lib/Support/ManagedStatic.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#include <cassert>
diff --git a/contrib/llvm/lib/Support/MemoryBuffer.cpp b/contrib/llvm/lib/Support/MemoryBuffer.cpp
index d09ef3a..faee10b 100644
--- a/contrib/llvm/lib/Support/MemoryBuffer.cpp
+++ b/contrib/llvm/lib/Support/MemoryBuffer.cpp
@@ -162,13 +162,14 @@ MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) {
}
ErrorOr<std::unique_ptr<MemoryBuffer>>
-MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize) {
+MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize,
+ bool RequiresNullTerminator) {
SmallString<256> NameBuf;
StringRef NameRef = Filename.toStringRef(NameBuf);
if (NameRef == "-")
return getSTDIN();
- return getFile(Filename, FileSize);
+ return getFile(Filename, FileSize, RequiresNullTerminator);
}
ErrorOr<std::unique_ptr<MemoryBuffer>>
diff --git a/contrib/llvm/lib/Support/Path.cpp b/contrib/llvm/lib/Support/Path.cpp
index cf46738..4952f59 100644
--- a/contrib/llvm/lib/Support/Path.cpp
+++ b/contrib/llvm/lib/Support/Path.cpp
@@ -455,17 +455,15 @@ void append(SmallVectorImpl<char> &path, const Twine &a,
if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
- for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
- e = components.end();
- i != e; ++i) {
+ for (auto &component : components) {
bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
- bool component_has_sep = !i->empty() && is_separator((*i)[0]);
- bool is_root_name = has_root_name(*i);
+ bool component_has_sep = !component.empty() && is_separator(component[0]);
+ bool is_root_name = has_root_name(component);
if (path_has_sep) {
// Strip separators from beginning of component.
- size_t loc = i->find_first_not_of(separators);
- StringRef c = i->substr(loc);
+ size_t loc = component.find_first_not_of(separators);
+ StringRef c = component.substr(loc);
// Append it.
path.append(c.begin(), c.end());
@@ -477,7 +475,7 @@ void append(SmallVectorImpl<char> &path, const Twine &a,
path.push_back(preferred_separator);
}
- path.append(i->begin(), i->end());
+ path.append(component.begin(), component.end());
}
}
@@ -661,8 +659,51 @@ bool is_absolute(const Twine &path) {
return rootDir && rootName;
}
-bool is_relative(const Twine &path) {
- return !is_absolute(path);
+bool is_relative(const Twine &path) { return !is_absolute(path); }
+
+StringRef remove_leading_dotslash(StringRef Path) {
+ // Remove leading "./" (or ".//" or "././" etc.)
+ while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1])) {
+ Path = Path.substr(2);
+ while (Path.size() > 0 && is_separator(Path[0]))
+ Path = Path.substr(1);
+ }
+ return Path;
+}
+
+static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot) {
+ SmallVector<StringRef, 16> components;
+
+ // Skip the root path, then look for traversal in the components.
+ StringRef rel = path::relative_path(path);
+ for (StringRef C : llvm::make_range(path::begin(rel), path::end(rel))) {
+ if (C == ".")
+ continue;
+ if (remove_dot_dot) {
+ if (C == "..") {
+ if (!components.empty())
+ components.pop_back();
+ continue;
+ }
+ }
+ components.push_back(C);
+ }
+
+ SmallString<256> buffer = path::root_path(path);
+ for (StringRef C : components)
+ path::append(buffer, C);
+ return buffer;
+}
+
+bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot) {
+ StringRef p(path.data(), path.size());
+
+ SmallString<256> result = remove_dots(p, remove_dot_dot);
+ if (result == path)
+ return false;
+
+ path.swap(result);
+ return true;
}
} // end namespace path
@@ -732,7 +773,9 @@ std::error_code createUniqueDirectory(const Twine &Prefix,
true, 0, FS_Dir);
}
-std::error_code make_absolute(SmallVectorImpl<char> &path) {
+static std::error_code make_absolute(const Twine &current_directory,
+ SmallVectorImpl<char> &path,
+ bool use_current_directory) {
StringRef p(path.data(), path.size());
bool rootDirectory = path::has_root_directory(p),
@@ -748,7 +791,9 @@ std::error_code make_absolute(SmallVectorImpl<char> &path) {
// All of the following conditions will need the current directory.
SmallString<128> current_dir;
- if (std::error_code ec = current_path(current_dir))
+ if (use_current_directory)
+ current_directory.toVector(current_dir);
+ else if (std::error_code ec = current_path(current_dir))
return ec;
// Relative path. Prepend the current directory.
@@ -785,12 +830,22 @@ std::error_code make_absolute(SmallVectorImpl<char> &path) {
"occurred above!");
}
-std::error_code create_directories(const Twine &Path, bool IgnoreExisting) {
+std::error_code make_absolute(const Twine &current_directory,
+ SmallVectorImpl<char> &path) {
+ return make_absolute(current_directory, path, true);
+}
+
+std::error_code make_absolute(SmallVectorImpl<char> &path) {
+ return make_absolute(Twine(), path, false);
+}
+
+std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
+ perms Perms) {
SmallString<128> PathStorage;
StringRef P = Path.toStringRef(PathStorage);
// Be optimistic and try to create the directory
- std::error_code EC = create_directory(P, IgnoreExisting);
+ std::error_code EC = create_directory(P, IgnoreExisting, Perms);
// If we succeeded, or had any error other than the parent not existing, just
// return it.
if (EC != errc::no_such_file_or_directory)
@@ -802,10 +857,10 @@ std::error_code create_directories(const Twine &Path, bool IgnoreExisting) {
if (Parent.empty())
return EC;
- if ((EC = create_directories(Parent)))
+ if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
return EC;
- return create_directory(P, IgnoreExisting);
+ return create_directory(P, IgnoreExisting, Perms);
}
std::error_code copy_file(const Twine &From, const Twine &To) {
@@ -889,8 +944,7 @@ std::error_code is_other(const Twine &Path, bool &Result) {
}
void directory_entry::replace_filename(const Twine &filename, file_status st) {
- SmallString<128> path(Path.begin(), Path.end());
- path::remove_filename(path);
+ SmallString<128> path = path::parent_path(Path);
path::append(path, filename);
Path = path.str();
Status = st;
@@ -940,7 +994,8 @@ file_magic identify_magic(StringRef Magic) {
break;
case '!':
if (Magic.size() >= 8)
- if (memcmp(Magic.data(),"!<arch>\n",8) == 0)
+ if (memcmp(Magic.data(), "!<arch>\n", 8) == 0 ||
+ memcmp(Magic.data(), "!<thin>\n", 8) == 0)
return file_magic::archive;
break;
@@ -1074,3 +1129,20 @@ std::error_code directory_entry::status(file_status &result) const {
#if defined(LLVM_ON_WIN32)
#include "Windows/Path.inc"
#endif
+
+namespace llvm {
+namespace sys {
+namespace path {
+
+bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1,
+ const Twine &Path2, const Twine &Path3) {
+ if (getUserCacheDir(Result)) {
+ append(Result, Path1, Path2, Path3);
+ return true;
+ }
+ return false;
+}
+
+} // end namespace path
+} // end namsspace sys
+} // end namespace llvm
diff --git a/contrib/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
index f9f8cab..05b3e31 100644
--- a/contrib/llvm/lib/Support/PrettyStackTrace.cpp
+++ b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm-c/Core.h"
+#include "llvm-c/ErrorHandling.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/Compiler.h"
@@ -154,6 +154,20 @@ void llvm::EnablePrettyStackTrace() {
#endif
}
+const void* llvm::SavePrettyStackState() {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ return PrettyStackTraceHead;
+#else
+ return nullptr;
+#endif
+}
+
+void llvm::RestorePrettyStackState(const void* Top) {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top;
+#endif
+}
+
void LLVMEnablePrettyStackTrace() {
EnablePrettyStackTrace();
}
diff --git a/contrib/llvm/lib/Support/Signals.cpp b/contrib/llvm/lib/Support/Signals.cpp
index a117893..3dc6b7c 100644
--- a/contrib/llvm/lib/Support/Signals.cpp
+++ b/contrib/llvm/lib/Support/Signals.cpp
@@ -12,8 +12,21 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Signals.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/StringSaver.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
namespace llvm {
using namespace sys;
@@ -23,6 +36,131 @@ using namespace sys;
//=== independent code.
//===----------------------------------------------------------------------===//
+static ManagedStatic<std::vector<std::pair<void (*)(void *), void *>>>
+ CallBacksToRun;
+void sys::RunSignalHandlers() {
+ if (!CallBacksToRun.isConstructed())
+ return;
+ for (auto &I : *CallBacksToRun)
+ I.first(I.second);
+ CallBacksToRun->clear();
+}
+}
+
+using namespace llvm;
+
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+ const char **Modules, intptr_t *Offsets,
+ const char *MainExecutableName,
+ StringSaver &StrPool);
+
+/// Format a pointer value as hexadecimal. Zero pad it out so its always the
+/// same width.
+static FormattedNumber format_ptr(void *PC) {
+ // Each byte is two hex digits plus 2 for the 0x prefix.
+ unsigned PtrWidth = 2 + 2 * sizeof(void *);
+ return format_hex((uint64_t)PC, PtrWidth);
+}
+
+static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
+ llvm::raw_ostream &OS)
+ LLVM_ATTRIBUTE_USED;
+
+/// Helper that launches llvm-symbolizer and symbolizes a backtrace.
+static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
+ llvm::raw_ostream &OS) {
+ // FIXME: Subtract necessary number from StackTrace entries to turn return addresses
+ // into actual instruction addresses.
+ // Use llvm-symbolizer tool to symbolize the stack traces.
+ ErrorOr<std::string> LLVMSymbolizerPathOrErr =
+ sys::findProgramByName("llvm-symbolizer");
+ if (!LLVMSymbolizerPathOrErr)
+ return false;
+ const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
+ // We don't know argv0 or the address of main() at this point, but try
+ // to guess it anyway (it's possible on some platforms).
+ std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr);
+ if (MainExecutableName.empty() ||
+ MainExecutableName.find("llvm-symbolizer") != std::string::npos)
+ return false;
+
+ BumpPtrAllocator Allocator;
+ StringSaver StrPool(Allocator);
+ std::vector<const char *> Modules(Depth, nullptr);
+ std::vector<intptr_t> Offsets(Depth, 0);
+ if (!findModulesAndOffsets(StackTrace, Depth, Modules.data(), Offsets.data(),
+ MainExecutableName.c_str(), StrPool))
+ return false;
+ int InputFD;
+ SmallString<32> InputFile, OutputFile;
+ sys::fs::createTemporaryFile("symbolizer-input", "", InputFD, InputFile);
+ sys::fs::createTemporaryFile("symbolizer-output", "", OutputFile);
+ FileRemover InputRemover(InputFile.c_str());
+ FileRemover OutputRemover(OutputFile.c_str());
+
+ {
+ raw_fd_ostream Input(InputFD, true);
+ for (int i = 0; i < Depth; i++) {
+ if (Modules[i])
+ Input << Modules[i] << " " << (void*)Offsets[i] << "\n";
+ }
+ }
+
+ StringRef InputFileStr(InputFile);
+ StringRef OutputFileStr(OutputFile);
+ StringRef StderrFileStr;
+ const StringRef *Redirects[] = {&InputFileStr, &OutputFileStr,
+ &StderrFileStr};
+ const char *Args[] = {"llvm-symbolizer", "--functions=linkage", "--inlining",
+#ifdef LLVM_ON_WIN32
+ // Pass --relative-address on Windows so that we don't
+ // have to add ImageBase from PE file.
+ // FIXME: Make this the default for llvm-symbolizer.
+ "--relative-address",
+#endif
+ "--demangle", nullptr};
+ int RunResult =
+ sys::ExecuteAndWait(LLVMSymbolizerPath, Args, nullptr, Redirects);
+ if (RunResult != 0)
+ return false;
+
+ // This report format is based on the sanitizer stack trace printer. See
+ // sanitizer_stacktrace_printer.cc in compiler-rt.
+ auto OutputBuf = MemoryBuffer::getFile(OutputFile.c_str());
+ if (!OutputBuf)
+ return false;
+ StringRef Output = OutputBuf.get()->getBuffer();
+ SmallVector<StringRef, 32> Lines;
+ Output.split(Lines, "\n");
+ auto CurLine = Lines.begin();
+ int frame_no = 0;
+ for (int i = 0; i < Depth; i++) {
+ if (!Modules[i]) {
+ OS << '#' << frame_no++ << ' ' << format_ptr(StackTrace[i]) << '\n';
+ continue;
+ }
+ // Read pairs of lines (function name and file/line info) until we
+ // encounter empty line.
+ for (;;) {
+ if (CurLine == Lines.end())
+ return false;
+ StringRef FunctionName = *CurLine++;
+ if (FunctionName.empty())
+ break;
+ OS << '#' << frame_no++ << ' ' << format_ptr(StackTrace[i]) << ' ';
+ if (!FunctionName.startswith("??"))
+ OS << FunctionName << ' ';
+ if (CurLine == Lines.end())
+ return false;
+ StringRef FileLineInfo = *CurLine++;
+ if (!FileLineInfo.startswith("??"))
+ OS << FileLineInfo;
+ else
+ OS << "(" << Modules[i] << '+' << format_hex(Offsets[i], 0) << ")";
+ OS << "\n";
+ }
+ }
+ return true;
}
// Include the platform-specific parts of this class.
diff --git a/contrib/llvm/lib/Support/Statistic.cpp b/contrib/llvm/lib/Support/Statistic.cpp
index 56c3b0f..e49d1cb 100644
--- a/contrib/llvm/lib/Support/Statistic.cpp
+++ b/contrib/llvm/lib/Support/Statistic.cpp
@@ -24,6 +24,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
@@ -33,9 +34,6 @@
#include <cstring>
using namespace llvm;
-// CreateInfoOutputFile - Return a file stream to print our output on.
-namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
-
/// -stats - Command line option to cause transformations to emit stats about
/// what they did.
///
@@ -144,20 +142,18 @@ void llvm::PrintStatistics() {
if (Stats.Stats.empty()) return;
// Get the stream to write to.
- raw_ostream &OutStream = *CreateInfoOutputFile();
- PrintStatistics(OutStream);
- delete &OutStream; // Close the file.
+ std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
+ PrintStatistics(*OutStream);
+
#else
// Check if the -stats option is set instead of checking
// !Stats.Stats.empty(). In release builds, Statistics operators
// do nothing, so stats are never Registered.
if (Enabled) {
// Get the stream to write to.
- raw_ostream &OutStream = *CreateInfoOutputFile();
- OutStream << "Statistics are disabled. "
- << "Build with asserts or with -DLLVM_ENABLE_STATS\n";
- OutStream.flush();
- delete &OutStream; // Close the file.
+ std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
+ (*OutStream) << "Statistics are disabled. "
+ << "Build with asserts or with -DLLVM_ENABLE_STATS\n";
}
#endif
}
diff --git a/contrib/llvm/lib/Support/StringRef.cpp b/contrib/llvm/lib/Support/StringRef.cpp
index ddece08..7ecff29 100644
--- a/contrib/llvm/lib/Support/StringRef.cpp
+++ b/contrib/llvm/lib/Support/StringRef.cpp
@@ -140,37 +140,44 @@ std::string StringRef::upper() const {
/// \return - The index of the first occurrence of \arg Str, or npos if not
/// found.
size_t StringRef::find(StringRef Str, size_t From) const {
+ if (From > Length)
+ return npos;
+
+ const char *Needle = Str.data();
size_t N = Str.size();
- if (N > Length)
+ if (N == 0)
+ return From;
+
+ size_t Size = Length - From;
+ if (Size < N)
return npos;
+ const char *Start = Data + From;
+ const char *Stop = Start + (Size - N + 1);
+
// For short haystacks or unsupported needles fall back to the naive algorithm
- if (Length < 16 || N > 255 || N == 0) {
- for (size_t e = Length - N + 1, i = std::min(From, e); i != e; ++i)
- if (substr(i, N).equals(Str))
- return i;
+ if (Size < 16 || N > 255) {
+ do {
+ if (std::memcmp(Start, Needle, N) == 0)
+ return Start - Data;
+ ++Start;
+ } while (Start < Stop);
return npos;
}
- if (From >= Length)
- return npos;
-
// Build the bad char heuristic table, with uint8_t to reduce cache thrashing.
uint8_t BadCharSkip[256];
std::memset(BadCharSkip, N, 256);
for (unsigned i = 0; i != N-1; ++i)
BadCharSkip[(uint8_t)Str[i]] = N-1-i;
- unsigned Len = Length-From, Pos = From;
- while (Len >= N) {
- if (substr(Pos, N).equals(Str)) // See if this is the correct substring.
- return Pos;
+ do {
+ if (std::memcmp(Start, Needle, N) == 0)
+ return Start - Data;
// Otherwise skip the appropriate number of bytes.
- uint8_t Skip = BadCharSkip[(uint8_t)(*this)[Pos+N-1]];
- Len -= Skip;
- Pos += Skip;
- }
+ Start += BadCharSkip[(uint8_t)Start[N-1]];
+ } while (Start < Stop);
return npos;
}
@@ -274,24 +281,56 @@ StringRef::size_type StringRef::find_last_not_of(StringRef Chars,
}
void StringRef::split(SmallVectorImpl<StringRef> &A,
- StringRef Separators, int MaxSplit,
+ StringRef Separator, int MaxSplit,
bool KeepEmpty) const {
- StringRef rest = *this;
-
- // rest.data() is used to distinguish cases like "a," that splits into
- // "a" + "" and "a" that splits into "a" + 0.
- for (int splits = 0;
- rest.data() != nullptr && (MaxSplit < 0 || splits < MaxSplit);
- ++splits) {
- std::pair<StringRef, StringRef> p = rest.split(Separators);
-
- if (KeepEmpty || p.first.size() != 0)
- A.push_back(p.first);
- rest = p.second;
+ StringRef S = *this;
+
+ // Count down from MaxSplit. When MaxSplit is -1, this will just split
+ // "forever". This doesn't support splitting more than 2^31 times
+ // intentionally; if we ever want that we can make MaxSplit a 64-bit integer
+ // but that seems unlikely to be useful.
+ while (MaxSplit-- != 0) {
+ size_t Idx = S.find(Separator);
+ if (Idx == npos)
+ break;
+
+ // Push this split.
+ if (KeepEmpty || Idx > 0)
+ A.push_back(S.slice(0, Idx));
+
+ // Jump forward.
+ S = S.slice(Idx + Separator.size(), npos);
+ }
+
+ // Push the tail.
+ if (KeepEmpty || !S.empty())
+ A.push_back(S);
+}
+
+void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator,
+ int MaxSplit, bool KeepEmpty) const {
+ StringRef S = *this;
+
+ // Count down from MaxSplit. When MaxSplit is -1, this will just split
+ // "forever". This doesn't support splitting more than 2^31 times
+ // intentionally; if we ever want that we can make MaxSplit a 64-bit integer
+ // but that seems unlikely to be useful.
+ while (MaxSplit-- != 0) {
+ size_t Idx = S.find(Separator);
+ if (Idx == npos)
+ break;
+
+ // Push this split.
+ if (KeepEmpty || Idx > 0)
+ A.push_back(S.slice(0, Idx));
+
+ // Jump forward.
+ S = S.slice(Idx + 1, npos);
}
- // If we have a tail left, add it.
- if (rest.data() != nullptr && (rest.size() != 0 || KeepEmpty))
- A.push_back(rest);
+
+ // Push the tail.
+ if (KeepEmpty || !S.empty())
+ A.push_back(S);
}
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/Support/StringSaver.cpp b/contrib/llvm/lib/Support/StringSaver.cpp
index d6b84e5..bbc1fd2 100644
--- a/contrib/llvm/lib/Support/StringSaver.cpp
+++ b/contrib/llvm/lib/Support/StringSaver.cpp
@@ -11,7 +11,7 @@
using namespace llvm;
-const char *StringSaver::saveImpl(StringRef S) {
+const char *StringSaver::save(StringRef S) {
char *P = Alloc.Allocate<char>(S.size() + 1);
memcpy(P, S.data(), S.size());
P[S.size()] = '\0';
diff --git a/contrib/llvm/lib/Support/TargetParser.cpp b/contrib/llvm/lib/Support/TargetParser.cpp
index 4d4c041..337532e 100644
--- a/contrib/llvm/lib/Support/TargetParser.cpp
+++ b/contrib/llvm/lib/Support/TargetParser.cpp
@@ -16,9 +16,11 @@
#include "llvm/Support/TargetParser.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
#include <cctype>
using namespace llvm;
+using namespace ARM;
namespace {
@@ -26,36 +28,19 @@ namespace {
// features they correspond to (use getFPUFeatures).
// FIXME: TableGen this.
// The entries must appear in the order listed in ARM::FPUKind for correct indexing
-struct {
- const char * Name;
+static const struct {
+ const char *NameCStr;
+ size_t NameLength;
ARM::FPUKind ID;
ARM::FPUVersion FPUVersion;
ARM::NeonSupportLevel NeonSupport;
ARM::FPURestriction Restriction;
+
+ StringRef getName() const { return StringRef(NameCStr, NameLength); }
} FPUNames[] = {
- { "invalid", ARM::FK_INVALID, ARM::FV_NONE, ARM::NS_None, ARM::FR_None},
- { "none", ARM::FK_NONE, ARM::FV_NONE, ARM::NS_None, ARM::FR_None},
- { "vfp", ARM::FK_VFP, ARM::FV_VFPV2, ARM::NS_None, ARM::FR_None},
- { "vfpv2", ARM::FK_VFPV2, ARM::FV_VFPV2, ARM::NS_None, ARM::FR_None},
- { "vfpv3", ARM::FK_VFPV3, ARM::FV_VFPV3, ARM::NS_None, ARM::FR_None},
- { "vfpv3-fp16", ARM::FK_VFPV3_FP16, ARM::FV_VFPV3_FP16, ARM::NS_None, ARM::FR_None},
- { "vfpv3-d16", ARM::FK_VFPV3_D16, ARM::FV_VFPV3, ARM::NS_None, ARM::FR_D16},
- { "vfpv3-d16-fp16", ARM::FK_VFPV3_D16_FP16, ARM::FV_VFPV3_FP16, ARM::NS_None, ARM::FR_D16},
- { "vfpv3xd", ARM::FK_VFPV3XD, ARM::FV_VFPV3, ARM::NS_None, ARM::FR_SP_D16},
- { "vfpv3xd-fp16", ARM::FK_VFPV3XD_FP16, ARM::FV_VFPV3_FP16, ARM::NS_None, ARM::FR_SP_D16},
- { "vfpv4", ARM::FK_VFPV4, ARM::FV_VFPV4, ARM::NS_None, ARM::FR_None},
- { "vfpv4-d16", ARM::FK_VFPV4_D16, ARM::FV_VFPV4, ARM::NS_None, ARM::FR_D16},
- { "fpv4-sp-d16", ARM::FK_FPV4_SP_D16, ARM::FV_VFPV4, ARM::NS_None, ARM::FR_SP_D16},
- { "fpv5-d16", ARM::FK_FPV5_D16, ARM::FV_VFPV5, ARM::NS_None, ARM::FR_D16},
- { "fpv5-sp-d16", ARM::FK_FPV5_SP_D16, ARM::FV_VFPV5, ARM::NS_None, ARM::FR_SP_D16},
- { "fp-armv8", ARM::FK_FP_ARMV8, ARM::FV_VFPV5, ARM::NS_None, ARM::FR_None},
- { "neon", ARM::FK_NEON, ARM::FV_VFPV3, ARM::NS_Neon, ARM::FR_None},
- { "neon-fp16", ARM::FK_NEON_FP16, ARM::FV_VFPV3_FP16, ARM::NS_Neon, ARM::FR_None},
- { "neon-vfpv4", ARM::FK_NEON_VFPV4, ARM::FV_VFPV4, ARM::NS_Neon, ARM::FR_None},
- { "neon-fp-armv8", ARM::FK_NEON_FP_ARMV8, ARM::FV_VFPV5, ARM::NS_Neon, ARM::FR_None},
- { "crypto-neon-fp-armv8",
- ARM::FK_CRYPTO_NEON_FP_ARMV8, ARM::FV_VFPV5, ARM::NS_Crypto, ARM::FR_None},
- { "softvfp", ARM::FK_SOFTVFP, ARM::FV_NONE, ARM::NS_None, ARM::FR_None},
+#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
+ { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
+#include "llvm/Support/ARMTargetParser.def"
};
// List of canonical arch names (use getArchSynonym).
@@ -66,165 +51,79 @@ struct {
// of the triples and are not conforming with their official names.
// Check to see if the expectation should be changed.
// FIXME: TableGen this.
-struct {
- const char *Name;
+static const struct {
+ const char *NameCStr;
+ size_t NameLength;
+ const char *CPUAttrCStr;
+ size_t CPUAttrLength;
+ const char *SubArchCStr;
+ size_t SubArchLength;
+ unsigned DefaultFPU;
+ unsigned ArchBaseExtensions;
ARM::ArchKind ID;
- const char *CPUAttr; // CPU class in build attributes.
- const char *SubArch; // Sub-Arch name.
ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
+
+ StringRef getName() const { return StringRef(NameCStr, NameLength); }
+
+ // CPU class in build attributes.
+ StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
+
+ // Sub-Arch name.
+ StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
} ARCHNames[] = {
- { "invalid", ARM::AK_INVALID, nullptr, nullptr, ARMBuildAttrs::CPUArch::Pre_v4 },
- { "armv2", ARM::AK_ARMV2, "2", "v2", ARMBuildAttrs::CPUArch::Pre_v4 },
- { "armv2a", ARM::AK_ARMV2A, "2A", "v2a", ARMBuildAttrs::CPUArch::Pre_v4 },
- { "armv3", ARM::AK_ARMV3, "3", "v3", ARMBuildAttrs::CPUArch::Pre_v4 },
- { "armv3m", ARM::AK_ARMV3M, "3M", "v3m", ARMBuildAttrs::CPUArch::Pre_v4 },
- { "armv4", ARM::AK_ARMV4, "4", "v4", ARMBuildAttrs::CPUArch::v4 },
- { "armv4t", ARM::AK_ARMV4T, "4T", "v4t", ARMBuildAttrs::CPUArch::v4T },
- { "armv5t", ARM::AK_ARMV5T, "5T", "v5", ARMBuildAttrs::CPUArch::v5T },
- { "armv5te", ARM::AK_ARMV5TE, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE },
- { "armv5tej", ARM::AK_ARMV5TEJ, "5TEJ", "v5e", ARMBuildAttrs::CPUArch::v5TEJ },
- { "armv6", ARM::AK_ARMV6, "6", "v6", ARMBuildAttrs::CPUArch::v6 },
- { "armv6k", ARM::AK_ARMV6K, "6K", "v6k", ARMBuildAttrs::CPUArch::v6K },
- { "armv6t2", ARM::AK_ARMV6T2, "6T2", "v6t2", ARMBuildAttrs::CPUArch::v6T2 },
- { "armv6z", ARM::AK_ARMV6Z, "6Z", "v6z", ARMBuildAttrs::CPUArch::v6KZ },
- { "armv6zk", ARM::AK_ARMV6ZK, "6ZK", "v6zk", ARMBuildAttrs::CPUArch::v6KZ },
- { "armv6-m", ARM::AK_ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M },
- { "armv6s-m", ARM::AK_ARMV6SM, "6S-M", "v6sm", ARMBuildAttrs::CPUArch::v6S_M },
- { "armv7-a", ARM::AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7 },
- { "armv7-r", ARM::AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7 },
- { "armv7-m", ARM::AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7 },
- { "armv7e-m", ARM::AK_ARMV7EM, "7E-M", "v7em", ARMBuildAttrs::CPUArch::v7E_M },
- { "armv8-a", ARM::AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8 },
- { "armv8.1-a", ARM::AK_ARMV8_1A, "8.1-A", "v8.1a", ARMBuildAttrs::CPUArch::v8 },
- // Non-standard Arch names.
- { "iwmmxt", ARM::AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE },
- { "iwmmxt2", ARM::AK_IWMMXT2, "iwmmxt2", "", ARMBuildAttrs::CPUArch::v5TE },
- { "xscale", ARM::AK_XSCALE, "xscale", "", ARMBuildAttrs::CPUArch::v5TE },
- { "armv5", ARM::AK_ARMV5, "5T", "v5", ARMBuildAttrs::CPUArch::v5T },
- { "armv5e", ARM::AK_ARMV5E, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE },
- { "armv6j", ARM::AK_ARMV6J, "6J", "v6", ARMBuildAttrs::CPUArch::v6 },
- { "armv6hl", ARM::AK_ARMV6HL, "6-M", "v6hl", ARMBuildAttrs::CPUArch::v6_M },
- { "armv7", ARM::AK_ARMV7, "7", "v7", ARMBuildAttrs::CPUArch::v7 },
- { "armv7l", ARM::AK_ARMV7L, "7-L", "v7l", ARMBuildAttrs::CPUArch::v7 },
- { "armv7hl", ARM::AK_ARMV7HL, "7-L", "v7hl", ARMBuildAttrs::CPUArch::v7 },
- { "armv7s", ARM::AK_ARMV7S, "7-S", "v7s", ARMBuildAttrs::CPUArch::v7 }
+#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
+ {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
+ sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR},
+#include "llvm/Support/ARMTargetParser.def"
};
+
// List of Arch Extension names.
// FIXME: TableGen this.
-struct {
- const char *Name;
- ARM::ArchExtKind ID;
+static const struct {
+ const char *NameCStr;
+ size_t NameLength;
+ unsigned ID;
+ const char *Feature;
+ const char *NegFeature;
+
+ StringRef getName() const { return StringRef(NameCStr, NameLength); }
} ARCHExtNames[] = {
- { "invalid", ARM::AEK_INVALID },
- { "crc", ARM::AEK_CRC },
- { "crypto", ARM::AEK_CRYPTO },
- { "fp", ARM::AEK_FP },
- { "idiv", ARM::AEK_HWDIV },
- { "mp", ARM::AEK_MP },
- { "simd", ARM::AEK_SIMD },
- { "sec", ARM::AEK_SEC },
- { "virt", ARM::AEK_VIRT },
- { "os", ARM::AEK_OS },
- { "iwmmxt", ARM::AEK_IWMMXT },
- { "iwmmxt2", ARM::AEK_IWMMXT2 },
- { "maverick", ARM::AEK_MAVERICK },
- { "xscale", ARM::AEK_XSCALE }
+#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
+ { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
+#include "llvm/Support/ARMTargetParser.def"
};
+
+// List of HWDiv names (use getHWDivSynonym) and which architectural
+// features they correspond to (use getHWDivFeatures).
+// FIXME: TableGen this.
+static const struct {
+ const char *NameCStr;
+ size_t NameLength;
+ unsigned ID;
+
+ StringRef getName() const { return StringRef(NameCStr, NameLength); }
+} HWDivNames[] = {
+#define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
+#include "llvm/Support/ARMTargetParser.def"
+};
+
// List of CPU names and their arches.
// The same CPU can have multiple arches and can be default on multiple arches.
// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
// When this becomes table-generated, we'd probably need two tables.
// FIXME: TableGen this.
-struct {
- const char *Name;
+static const struct {
+ const char *NameCStr;
+ size_t NameLength;
ARM::ArchKind ArchID;
- bool Default;
+ bool Default; // is $Name the default CPU for $ArchID ?
+ unsigned DefaultExtensions;
+
+ StringRef getName() const { return StringRef(NameCStr, NameLength); }
} CPUNames[] = {
- { "arm2", ARM::AK_ARMV2, true },
- { "arm3", ARM::AK_ARMV2A, true },
- { "arm6", ARM::AK_ARMV3, true },
- { "arm7m", ARM::AK_ARMV3M, true },
- { "arm8", ARM::AK_ARMV4, false },
- { "arm810", ARM::AK_ARMV4, false },
- { "strongarm", ARM::AK_ARMV4, true },
- { "strongarm110", ARM::AK_ARMV4, false },
- { "strongarm1100", ARM::AK_ARMV4, false },
- { "strongarm1110", ARM::AK_ARMV4, false },
- { "arm7tdmi", ARM::AK_ARMV4T, true },
- { "arm7tdmi-s", ARM::AK_ARMV4T, false },
- { "arm710t", ARM::AK_ARMV4T, false },
- { "arm720t", ARM::AK_ARMV4T, false },
- { "arm9", ARM::AK_ARMV4T, false },
- { "arm9tdmi", ARM::AK_ARMV4T, false },
- { "arm920", ARM::AK_ARMV4T, false },
- { "arm920t", ARM::AK_ARMV4T, false },
- { "arm922t", ARM::AK_ARMV4T, false },
- { "arm9312", ARM::AK_ARMV4T, false },
- { "arm940t", ARM::AK_ARMV4T, false },
- { "ep9312", ARM::AK_ARMV4T, false },
- { "arm10tdmi", ARM::AK_ARMV5T, true },
- { "arm1020t", ARM::AK_ARMV5T, false },
- { "arm9e", ARM::AK_ARMV5TE, false },
- { "arm946e-s", ARM::AK_ARMV5TE, false },
- { "arm966e-s", ARM::AK_ARMV5TE, false },
- { "arm968e-s", ARM::AK_ARMV5TE, false },
- { "arm10e", ARM::AK_ARMV5TE, false },
- { "arm1020e", ARM::AK_ARMV5TE, false },
- { "arm1022e", ARM::AK_ARMV5TE, true },
- { "iwmmxt", ARM::AK_ARMV5TE, false },
- { "xscale", ARM::AK_ARMV5TE, false },
- { "arm926ej-s", ARM::AK_ARMV5TEJ, true },
- { "arm1136jf-s", ARM::AK_ARMV6, true },
- { "arm1176j-s", ARM::AK_ARMV6K, false },
- { "arm1176jz-s", ARM::AK_ARMV6K, false },
- { "mpcore", ARM::AK_ARMV6K, false },
- { "mpcorenovfp", ARM::AK_ARMV6K, false },
- { "arm1176jzf-s", ARM::AK_ARMV6K, true },
- { "arm1176jzf-s", ARM::AK_ARMV6Z, true },
- { "arm1176jzf-s", ARM::AK_ARMV6ZK, true },
- { "arm1156t2-s", ARM::AK_ARMV6T2, true },
- { "arm1156t2f-s", ARM::AK_ARMV6T2, false },
- { "cortex-m0", ARM::AK_ARMV6M, true },
- { "cortex-m0plus", ARM::AK_ARMV6M, false },
- { "cortex-m1", ARM::AK_ARMV6M, false },
- { "sc000", ARM::AK_ARMV6M, false },
- { "cortex-a5", ARM::AK_ARMV7A, false },
- { "cortex-a7", ARM::AK_ARMV7A, false },
- { "cortex-a8", ARM::AK_ARMV7A, true },
- { "cortex-a9", ARM::AK_ARMV7A, false },
- { "cortex-a12", ARM::AK_ARMV7A, false },
- { "cortex-a15", ARM::AK_ARMV7A, false },
- { "cortex-a17", ARM::AK_ARMV7A, false },
- { "krait", ARM::AK_ARMV7A, false },
- { "cortex-r4", ARM::AK_ARMV7R, true },
- { "cortex-r4f", ARM::AK_ARMV7R, false },
- { "cortex-r5", ARM::AK_ARMV7R, false },
- { "cortex-r7", ARM::AK_ARMV7R, false },
- { "sc300", ARM::AK_ARMV7M, false },
- { "cortex-m3", ARM::AK_ARMV7M, true },
- { "cortex-m4", ARM::AK_ARMV7EM, true },
- { "cortex-m7", ARM::AK_ARMV7EM, false },
- { "cortex-a53", ARM::AK_ARMV8A, true },
- { "cortex-a57", ARM::AK_ARMV8A, false },
- { "cortex-a72", ARM::AK_ARMV8A, false },
- { "cyclone", ARM::AK_ARMV8A, false },
- { "generic", ARM::AK_ARMV8_1A, true },
- // Non-standard Arch names.
- { "iwmmxt", ARM::AK_IWMMXT, true },
- { "xscale", ARM::AK_XSCALE, true },
- { "arm10tdmi", ARM::AK_ARMV5, true },
- { "arm1022e", ARM::AK_ARMV5E, true },
- { "arm1136j-s", ARM::AK_ARMV6J, true },
- { "arm1136jz-s", ARM::AK_ARMV6J, false },
- { "cortex-m0", ARM::AK_ARMV6SM, true },
- { "arm1176jzf-s", ARM::AK_ARMV6HL, true },
- { "cortex-a8", ARM::AK_ARMV7, true },
- { "cortex-a8", ARM::AK_ARMV7L, true },
- { "cortex-a8", ARM::AK_ARMV7HL, true },
- { "cortex-m4", ARM::AK_ARMV7EM, true },
- { "swift", ARM::AK_ARMV7S, true },
- // Invalid CPU
- { "invalid", ARM::AK_INVALID, true }
+#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+ { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
+#include "llvm/Support/ARMTargetParser.def"
};
} // namespace
@@ -233,33 +132,93 @@ struct {
// Information by ID
// ======================================================= //
-const char *ARMTargetParser::getFPUName(unsigned FPUKind) {
+StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
if (FPUKind >= ARM::FK_LAST)
- return nullptr;
- return FPUNames[FPUKind].Name;
+ return StringRef();
+ return FPUNames[FPUKind].getName();
}
-unsigned ARMTargetParser::getFPUVersion(unsigned FPUKind) {
+unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
if (FPUKind >= ARM::FK_LAST)
return 0;
return FPUNames[FPUKind].FPUVersion;
}
-unsigned ARMTargetParser::getFPUNeonSupportLevel(unsigned FPUKind) {
+unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
if (FPUKind >= ARM::FK_LAST)
return 0;
return FPUNames[FPUKind].NeonSupport;
}
-unsigned ARMTargetParser::getFPURestriction(unsigned FPUKind) {
+unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
if (FPUKind >= ARM::FK_LAST)
return 0;
return FPUNames[FPUKind].Restriction;
}
-bool ARMTargetParser::getFPUFeatures(unsigned FPUKind,
+unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
+ if (CPU == "generic")
+ return ARCHNames[ArchKind].DefaultFPU;
+
+ return StringSwitch<unsigned>(CPU)
+#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+ .Case(NAME, DEFAULT_FPU)
+#include "llvm/Support/ARMTargetParser.def"
+ .Default(ARM::FK_INVALID);
+}
+
+unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
+ if (CPU == "generic")
+ return ARCHNames[ArchKind].ArchBaseExtensions;
+
+ return StringSwitch<unsigned>(CPU)
+#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+ .Case(NAME, ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT)
+#include "llvm/Support/ARMTargetParser.def"
+ .Default(ARM::AEK_INVALID);
+}
+
+bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
+ std::vector<const char *> &Features) {
+
+ if (HWDivKind == ARM::AEK_INVALID)
+ return false;
+
+ if (HWDivKind & ARM::AEK_HWDIVARM)
+ Features.push_back("+hwdiv-arm");
+ else
+ Features.push_back("-hwdiv-arm");
+
+ if (HWDivKind & ARM::AEK_HWDIV)
+ Features.push_back("+hwdiv");
+ else
+ Features.push_back("-hwdiv");
+
+ return true;
+}
+
+bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
std::vector<const char *> &Features) {
+ if (Extensions == ARM::AEK_INVALID)
+ return false;
+
+ if (Extensions & ARM::AEK_CRC)
+ Features.push_back("+crc");
+ else
+ Features.push_back("-crc");
+
+ if (Extensions & ARM::AEK_DSP)
+ Features.push_back("+dsp");
+ else
+ Features.push_back("-dsp");
+
+ return getHWDivFeatures(Extensions, Features);
+}
+
+bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
+ std::vector<const char *> &Features) {
+
if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
return false;
@@ -323,6 +282,7 @@ bool ARMTargetParser::getFPUFeatures(unsigned FPUKind,
// crypto includes neon, so we handle this similarly to FPU version.
switch (FPUNames[FPUKind].NeonSupport) {
case ARM::NS_Crypto:
+ Features.push_back("+neon");
Features.push_back("+crypto");
break;
case ARM::NS_Neon:
@@ -338,88 +298,127 @@ bool ARMTargetParser::getFPUFeatures(unsigned FPUKind,
return true;
}
-const char *ARMTargetParser::getArchName(unsigned ArchKind) {
+StringRef llvm::ARM::getArchName(unsigned ArchKind) {
if (ArchKind >= ARM::AK_LAST)
- return nullptr;
- return ARCHNames[ArchKind].Name;
+ return StringRef();
+ return ARCHNames[ArchKind].getName();
}
-const char *ARMTargetParser::getCPUAttr(unsigned ArchKind) {
+StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
if (ArchKind >= ARM::AK_LAST)
- return nullptr;
- return ARCHNames[ArchKind].CPUAttr;
+ return StringRef();
+ return ARCHNames[ArchKind].getCPUAttr();
}
-const char *ARMTargetParser::getSubArch(unsigned ArchKind) {
+StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
if (ArchKind >= ARM::AK_LAST)
- return nullptr;
- return ARCHNames[ArchKind].SubArch;
+ return StringRef();
+ return ARCHNames[ArchKind].getSubArch();
}
-unsigned ARMTargetParser::getArchAttr(unsigned ArchKind) {
+unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
if (ArchKind >= ARM::AK_LAST)
return ARMBuildAttrs::CPUArch::Pre_v4;
return ARCHNames[ArchKind].ArchAttr;
}
-const char *ARMTargetParser::getArchExtName(unsigned ArchExtKind) {
- if (ArchExtKind >= ARM::AEK_LAST)
- return nullptr;
- return ARCHExtNames[ArchExtKind].Name;
+StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
+ for (const auto AE : ARCHExtNames) {
+ if (ArchExtKind == AE.ID)
+ return AE.getName();
+ }
+ return StringRef();
}
-const char *ARMTargetParser::getDefaultCPU(StringRef Arch) {
+const char *llvm::ARM::getArchExtFeature(StringRef ArchExt) {
+ if (ArchExt.startswith("no")) {
+ StringRef ArchExtBase(ArchExt.substr(2));
+ for (const auto AE : ARCHExtNames) {
+ if (AE.NegFeature && ArchExtBase == AE.getName())
+ return AE.NegFeature;
+ }
+ }
+ for (const auto AE : ARCHExtNames) {
+ if (AE.Feature && ArchExt == AE.getName())
+ return AE.Feature;
+ }
+
+ return nullptr;
+}
+
+StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
+ for (const auto D : HWDivNames) {
+ if (HWDivKind == D.ID)
+ return D.getName();
+ }
+ return StringRef();
+}
+
+StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
unsigned AK = parseArch(Arch);
if (AK == ARM::AK_INVALID)
- return nullptr;
+ return StringRef();
// Look for multiple AKs to find the default for pair AK+Name.
for (const auto CPU : CPUNames) {
if (CPU.ArchID == AK && CPU.Default)
- return CPU.Name;
+ return CPU.getName();
}
- return nullptr;
+
+ // If we can't find a default then target the architecture instead
+ return "generic";
}
// ======================================================= //
// Parsers
// ======================================================= //
-StringRef ARMTargetParser::getFPUSynonym(StringRef FPU) {
+static StringRef getHWDivSynonym(StringRef HWDiv) {
+ return StringSwitch<StringRef>(HWDiv)
+ .Case("thumb,arm", "arm,thumb")
+ .Default(HWDiv);
+}
+
+static StringRef getFPUSynonym(StringRef FPU) {
return StringSwitch<StringRef>(FPU)
- .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
- .Case("vfp2", "vfpv2")
- .Case("vfp3", "vfpv3")
- .Case("vfp4", "vfpv4")
- .Case("vfp3-d16", "vfpv3-d16")
- .Case("vfp4-d16", "vfpv4-d16")
- .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
- .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
- .Case("fp5-sp-d16", "fpv5-sp-d16")
- .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
- // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
- .Case("neon-vfpv3", "neon")
- .Default(FPU);
+ .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
+ .Case("vfp2", "vfpv2")
+ .Case("vfp3", "vfpv3")
+ .Case("vfp4", "vfpv4")
+ .Case("vfp3-d16", "vfpv3-d16")
+ .Case("vfp4-d16", "vfpv4-d16")
+ .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
+ .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
+ .Case("fp5-sp-d16", "fpv5-sp-d16")
+ .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
+ // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
+ .Case("neon-vfpv3", "neon")
+ .Default(FPU);
}
-StringRef ARMTargetParser::getArchSynonym(StringRef Arch) {
+static StringRef getArchSynonym(StringRef Arch) {
return StringSwitch<StringRef>(Arch)
- .Case("v6sm", "v6s-m")
- .Case("v6m", "v6-m")
- .Case("v7a", "v7-a")
- .Case("v7r", "v7-r")
- .Case("v7m", "v7-m")
- .Case("v7em", "v7e-m")
- .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
- .Case("v8.1a", "v8.1-a")
- .Default(Arch);
+ .Case("v5", "v5t")
+ .Case("v5e", "v5te")
+ .Case("v6j", "v6")
+ .Case("v6hl", "v6k")
+ .Cases("v6m", "v6sm", "v6s-m", "v6-m")
+ .Cases("v6z", "v6zk", "v6kz")
+ .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
+ .Case("v7r", "v7-r")
+ .Case("v7m", "v7-m")
+ .Case("v7em", "v7e-m")
+ .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
+ .Case("v8.1a", "v8.1-a")
+ .Case("v8.2a", "v8.2-a")
+ .Default(Arch);
}
// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
// "v.+", if the latter, return unmodified string, minus 'eb'.
// If invalid, return empty string.
-StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
+StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
size_t offset = StringRef::npos;
StringRef A = Arch;
StringRef Error = "";
@@ -436,7 +435,7 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
// AArch64 uses "_be", not "eb" suffix.
if (A.find("eb") != StringRef::npos)
return Error;
- if (A.substr(offset,3) == "_be")
+ if (A.substr(offset, 3) == "_be")
offset += 3;
}
@@ -456,7 +455,7 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
// Only match non-marketing names
if (offset != StringRef::npos) {
- // Must start with 'vN'.
+ // Must start with 'vN'.
if (A[0] != 'v' || !std::isdigit(A[1]))
return Error;
// Can't have an extra 'eb'.
@@ -468,56 +467,64 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
return A;
}
-unsigned ARMTargetParser::parseFPU(StringRef FPU) {
+unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
+ StringRef Syn = getHWDivSynonym(HWDiv);
+ for (const auto D : HWDivNames) {
+ if (Syn == D.getName())
+ return D.ID;
+ }
+ return ARM::AEK_INVALID;
+}
+
+unsigned llvm::ARM::parseFPU(StringRef FPU) {
StringRef Syn = getFPUSynonym(FPU);
for (const auto F : FPUNames) {
- if (Syn == F.Name)
+ if (Syn == F.getName())
return F.ID;
}
return ARM::FK_INVALID;
}
// Allows partial match, ex. "v7a" matches "armv7a".
-unsigned ARMTargetParser::parseArch(StringRef Arch) {
+unsigned llvm::ARM::parseArch(StringRef Arch) {
Arch = getCanonicalArchName(Arch);
StringRef Syn = getArchSynonym(Arch);
for (const auto A : ARCHNames) {
- if (StringRef(A.Name).endswith(Syn))
+ if (A.getName().endswith(Syn))
return A.ID;
}
return ARM::AK_INVALID;
}
-unsigned ARMTargetParser::parseArchExt(StringRef ArchExt) {
+unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
for (const auto A : ARCHExtNames) {
- if (ArchExt == A.Name)
+ if (ArchExt == A.getName())
return A.ID;
}
return ARM::AEK_INVALID;
}
-unsigned ARMTargetParser::parseCPUArch(StringRef CPU) {
+unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
for (const auto C : CPUNames) {
- if (CPU == C.Name)
+ if (CPU == C.getName())
return C.ArchID;
}
return ARM::AK_INVALID;
}
// ARM, Thumb, AArch64
-unsigned ARMTargetParser::parseArchISA(StringRef Arch) {
+unsigned llvm::ARM::parseArchISA(StringRef Arch) {
return StringSwitch<unsigned>(Arch)
.StartsWith("aarch64", ARM::IK_AARCH64)
- .StartsWith("arm64", ARM::IK_AARCH64)
- .StartsWith("thumb", ARM::IK_THUMB)
- .StartsWith("arm", ARM::IK_ARM)
+ .StartsWith("arm64", ARM::IK_AARCH64)
+ .StartsWith("thumb", ARM::IK_THUMB)
+ .StartsWith("arm", ARM::IK_ARM)
.Default(ARM::EK_INVALID);
}
// Little/Big endian
-unsigned ARMTargetParser::parseArchEndian(StringRef Arch) {
- if (Arch.startswith("armeb") ||
- Arch.startswith("thumbeb") ||
+unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
+ if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
Arch.startswith("aarch64_be"))
return ARM::EK_BIG;
@@ -535,29 +542,29 @@ unsigned ARMTargetParser::parseArchEndian(StringRef Arch) {
}
// Profile A/R/M
-unsigned ARMTargetParser::parseArchProfile(StringRef Arch) {
+unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
Arch = getCanonicalArchName(Arch);
- switch(parseArch(Arch)) {
+ switch (parseArch(Arch)) {
case ARM::AK_ARMV6M:
case ARM::AK_ARMV7M:
- case ARM::AK_ARMV6SM:
case ARM::AK_ARMV7EM:
return ARM::PK_M;
case ARM::AK_ARMV7R:
return ARM::PK_R;
- case ARM::AK_ARMV7:
case ARM::AK_ARMV7A:
+ case ARM::AK_ARMV7K:
case ARM::AK_ARMV8A:
case ARM::AK_ARMV8_1A:
+ case ARM::AK_ARMV8_2A:
return ARM::PK_A;
}
return ARM::PK_INVALID;
}
// Version number (ex. v7 = 7).
-unsigned ARMTargetParser::parseArchVersion(StringRef Arch) {
+unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
Arch = getCanonicalArchName(Arch);
- switch(parseArch(Arch)) {
+ switch (parseArch(Arch)) {
case ARM::AK_ARMV2:
case ARM::AK_ARMV2A:
return 2;
@@ -567,36 +574,29 @@ unsigned ARMTargetParser::parseArchVersion(StringRef Arch) {
case ARM::AK_ARMV4:
case ARM::AK_ARMV4T:
return 4;
- case ARM::AK_ARMV5:
case ARM::AK_ARMV5T:
case ARM::AK_ARMV5TE:
case ARM::AK_IWMMXT:
case ARM::AK_IWMMXT2:
case ARM::AK_XSCALE:
- case ARM::AK_ARMV5E:
case ARM::AK_ARMV5TEJ:
return 5;
case ARM::AK_ARMV6:
- case ARM::AK_ARMV6J:
case ARM::AK_ARMV6K:
case ARM::AK_ARMV6T2:
- case ARM::AK_ARMV6Z:
- case ARM::AK_ARMV6ZK:
+ case ARM::AK_ARMV6KZ:
case ARM::AK_ARMV6M:
- case ARM::AK_ARMV6SM:
- case ARM::AK_ARMV6HL:
return 6;
- case ARM::AK_ARMV7:
case ARM::AK_ARMV7A:
case ARM::AK_ARMV7R:
case ARM::AK_ARMV7M:
- case ARM::AK_ARMV7L:
- case ARM::AK_ARMV7HL:
case ARM::AK_ARMV7S:
case ARM::AK_ARMV7EM:
+ case ARM::AK_ARMV7K:
return 7;
case ARM::AK_ARMV8A:
case ARM::AK_ARMV8_1A:
+ case ARM::AK_ARMV8_2A:
return 8;
}
return 0;
diff --git a/contrib/llvm/lib/Support/ThreadPool.cpp b/contrib/llvm/lib/Support/ThreadPool.cpp
new file mode 100644
index 0000000..d4dcb2e
--- /dev/null
+++ b/contrib/llvm/lib/Support/ThreadPool.cpp
@@ -0,0 +1,155 @@
+//==-- llvm/Support/ThreadPool.cpp - A ThreadPool implementation -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a crude C++11 based thread pool.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ThreadPool.h"
+
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#if LLVM_ENABLE_THREADS
+
+// Default to std::thread::hardware_concurrency
+ThreadPool::ThreadPool() : ThreadPool(std::thread::hardware_concurrency()) {}
+
+ThreadPool::ThreadPool(unsigned ThreadCount)
+ : ActiveThreads(0), EnableFlag(true) {
+ // Create ThreadCount threads that will loop forever, wait on QueueCondition
+ // for tasks to be queued or the Pool to be destroyed.
+ Threads.reserve(ThreadCount);
+ for (unsigned ThreadID = 0; ThreadID < ThreadCount; ++ThreadID) {
+ Threads.emplace_back([&] {
+ while (true) {
+ PackagedTaskTy Task;
+ {
+ std::unique_lock<std::mutex> LockGuard(QueueLock);
+ // Wait for tasks to be pushed in the queue
+ QueueCondition.wait(LockGuard,
+ [&] { return !EnableFlag || !Tasks.empty(); });
+ // Exit condition
+ if (!EnableFlag && Tasks.empty())
+ return;
+ // Yeah, we have a task, grab it and release the lock on the queue
+
+ // We first need to signal that we are active before popping the queue
+ // in order for wait() to properly detect that even if the queue is
+ // empty, there is still a task in flight.
+ {
+ ++ActiveThreads;
+ std::unique_lock<std::mutex> LockGuard(CompletionLock);
+ }
+ Task = std::move(Tasks.front());
+ Tasks.pop();
+ }
+ // Run the task we just grabbed
+#ifndef _MSC_VER
+ Task();
+#else
+ Task(/* unused */ false);
+#endif
+
+ {
+ // Adjust `ActiveThreads`, in case someone waits on ThreadPool::wait()
+ std::unique_lock<std::mutex> LockGuard(CompletionLock);
+ --ActiveThreads;
+ }
+
+ // Notify task completion, in case someone waits on ThreadPool::wait()
+ CompletionCondition.notify_all();
+ }
+ });
+ }
+}
+
+void ThreadPool::wait() {
+ // Wait for all threads to complete and the queue to be empty
+ std::unique_lock<std::mutex> LockGuard(CompletionLock);
+ CompletionCondition.wait(LockGuard,
+ [&] { return Tasks.empty() && !ActiveThreads; });
+}
+
+std::shared_future<ThreadPool::VoidTy> ThreadPool::asyncImpl(TaskTy Task) {
+ /// Wrap the Task in a packaged_task to return a future object.
+ PackagedTaskTy PackagedTask(std::move(Task));
+ auto Future = PackagedTask.get_future();
+ {
+ // Lock the queue and push the new task
+ std::unique_lock<std::mutex> LockGuard(QueueLock);
+
+ // Don't allow enqueueing after disabling the pool
+ assert(EnableFlag && "Queuing a thread during ThreadPool destruction");
+
+ Tasks.push(std::move(PackagedTask));
+ }
+ QueueCondition.notify_one();
+ return Future.share();
+}
+
+// The destructor joins all threads, waiting for completion.
+ThreadPool::~ThreadPool() {
+ {
+ std::unique_lock<std::mutex> LockGuard(QueueLock);
+ EnableFlag = false;
+ }
+ QueueCondition.notify_all();
+ for (auto &Worker : Threads)
+ Worker.join();
+}
+
+#else // LLVM_ENABLE_THREADS Disabled
+
+ThreadPool::ThreadPool() : ThreadPool(0) {}
+
+// No threads are launched, issue a warning if ThreadCount is not 0
+ThreadPool::ThreadPool(unsigned ThreadCount)
+ : ActiveThreads(0) {
+ if (ThreadCount) {
+ errs() << "Warning: request a ThreadPool with " << ThreadCount
+ << " threads, but LLVM_ENABLE_THREADS has been turned off\n";
+ }
+}
+
+void ThreadPool::wait() {
+ // Sequential implementation running the tasks
+ while (!Tasks.empty()) {
+ auto Task = std::move(Tasks.front());
+ Tasks.pop();
+#ifndef _MSC_VER
+ Task();
+#else
+ Task(/* unused */ false);
+#endif
+ }
+}
+
+std::shared_future<ThreadPool::VoidTy> ThreadPool::asyncImpl(TaskTy Task) {
+#ifndef _MSC_VER
+ // Get a Future with launch::deferred execution using std::async
+ auto Future = std::async(std::launch::deferred, std::move(Task)).share();
+ // Wrap the future so that both ThreadPool::wait() can operate and the
+ // returned future can be sync'ed on.
+ PackagedTaskTy PackagedTask([Future]() { Future.get(); });
+#else
+ auto Future = std::async(std::launch::deferred, std::move(Task), false).share();
+ PackagedTaskTy PackagedTask([Future](bool) -> bool { Future.get(); return false; });
+#endif
+ Tasks.push(std::move(PackagedTask));
+ return Future;
+}
+
+ThreadPool::~ThreadPool() {
+ wait();
+}
+
+#endif
diff --git a/contrib/llvm/lib/Support/TimeValue.cpp b/contrib/llvm/lib/Support/TimeValue.cpp
index 136b93e..94a4c01 100644
--- a/contrib/llvm/lib/Support/TimeValue.cpp
+++ b/contrib/llvm/lib/Support/TimeValue.cpp
@@ -15,6 +15,7 @@
#include "llvm/Config/config.h"
namespace llvm {
+
using namespace sys;
const TimeValue::SecondsType
@@ -22,8 +23,7 @@ const TimeValue::SecondsType
const TimeValue::SecondsType
TimeValue::Win32ZeroTimeSeconds = -12591158400ULL;
-void
-TimeValue::normalize( void ) {
+void TimeValue::normalize() {
if ( nanos_ >= NANOSECONDS_PER_SECOND ) {
do {
seconds_++;
@@ -45,7 +45,7 @@ TimeValue::normalize( void ) {
}
}
-}
+} // namespace llvm
/// Include the platform-specific portion of TimeValue class
#ifdef LLVM_ON_UNIX
diff --git a/contrib/llvm/lib/Support/Timer.cpp b/contrib/llvm/lib/Support/Timer.cpp
index d7b6515..414f559 100644
--- a/contrib/llvm/lib/Support/Timer.cpp
+++ b/contrib/llvm/lib/Support/Timer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Timer.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
@@ -22,9 +23,6 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-// CreateInfoOutputFile - Return a file stream to print our output on.
-namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
-
// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy
// of constructor/destructor ordering being unspecified by C++. Basically the
// problem is that a Statistic object gets destroyed, which ends up calling
@@ -52,28 +50,27 @@ namespace {
cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
}
-// CreateInfoOutputFile - Return a file stream to print our output on.
-raw_ostream *llvm::CreateInfoOutputFile() {
+// Return a file stream to print our output on.
+std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() {
const std::string &OutputFilename = getLibSupportInfoOutputFilename();
if (OutputFilename.empty())
- return new raw_fd_ostream(2, false); // stderr.
+ return llvm::make_unique<raw_fd_ostream>(2, false); // stderr.
if (OutputFilename == "-")
- return new raw_fd_ostream(1, false); // stdout.
-
+ return llvm::make_unique<raw_fd_ostream>(1, false); // stdout.
+
// Append mode is used because the info output file is opened and closed
// each time -stats or -time-passes wants to print output to it. To
// compensate for this, the test-suite Makefiles have code to delete the
// info output file before running commands which write to it.
std::error_code EC;
- raw_ostream *Result = new raw_fd_ostream(OutputFilename, EC,
- sys::fs::F_Append | sys::fs::F_Text);
+ auto Result = llvm::make_unique<raw_fd_ostream>(
+ OutputFilename, EC, sys::fs::F_Append | sys::fs::F_Text);
if (!EC)
return Result;
-
+
errs() << "Error opening info-output-file '"
<< OutputFilename << " for appending!\n";
- delete Result;
- return new raw_fd_ostream(2, false); // stderr.
+ return llvm::make_unique<raw_fd_ostream>(2, false); // stderr.
}
@@ -99,17 +96,13 @@ static TimerGroup *getDefaultTimerGroup() {
//===----------------------------------------------------------------------===//
void Timer::init(StringRef N) {
- assert(!TG && "Timer already initialized");
- Name.assign(N.begin(), N.end());
- Started = false;
- TG = getDefaultTimerGroup();
- TG->addTimer(*this);
+ init(N, *getDefaultTimerGroup());
}
void Timer::init(StringRef N, TimerGroup &tg) {
assert(!TG && "Timer already initialized");
Name.assign(N.begin(), N.end());
- Started = false;
+ Running = Triggered = false;
TG = &tg;
TG->addTimer(*this);
}
@@ -142,25 +135,22 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
return Result;
}
-static ManagedStatic<std::vector<Timer*> > ActiveTimers;
-
void Timer::startTimer() {
- Started = true;
- ActiveTimers->push_back(this);
- Time -= TimeRecord::getCurrentTime(true);
+ assert(!Running && "Cannot start a running timer");
+ Running = Triggered = true;
+ StartTime = TimeRecord::getCurrentTime(true);
}
void Timer::stopTimer() {
+ assert(Running && "Cannot stop a paused timer");
+ Running = false;
Time += TimeRecord::getCurrentTime(false);
+ Time -= StartTime;
+}
- if (ActiveTimers->back() == this) {
- ActiveTimers->pop_back();
- } else {
- std::vector<Timer*>::iterator I =
- std::find(ActiveTimers->begin(), ActiveTimers->end(), this);
- assert(I != ActiveTimers->end() && "stop but no startTimer?");
- ActiveTimers->erase(I);
- }
+void Timer::clear() {
+ Running = Triggered = false;
+ Time = StartTime = TimeRecord();
}
static void printVal(double Val, double Total, raw_ostream &OS) {
@@ -278,8 +268,8 @@ void TimerGroup::removeTimer(Timer &T) {
sys::SmartScopedLock<true> L(*TimerLock);
// If the timer was started, move its data to TimersToPrint.
- if (T.Started)
- TimersToPrint.push_back(std::make_pair(T.Time, T.Name));
+ if (T.hasTriggered())
+ TimersToPrint.emplace_back(T.Time, T.Name);
T.TG = nullptr;
@@ -292,10 +282,9 @@ void TimerGroup::removeTimer(Timer &T) {
// them were started.
if (FirstTimer || TimersToPrint.empty())
return;
-
- raw_ostream *OutStream = CreateInfoOutputFile();
+
+ std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
PrintQueuedTimers(*OutStream);
- delete OutStream; // Close the file.
}
void TimerGroup::addTimer(Timer &T) {
@@ -314,8 +303,8 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
std::sort(TimersToPrint.begin(), TimersToPrint.end());
TimeRecord Total;
- for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
- Total += TimersToPrint[i].first;
+ for (auto &RecordNamePair : TimersToPrint)
+ Total += RecordNamePair.first;
// Print out timing header.
OS << "===" << std::string(73, '-') << "===\n";
@@ -365,12 +354,11 @@ void TimerGroup::print(raw_ostream &OS) {
// See if any of our timers were started, if so add them to TimersToPrint and
// reset them.
for (Timer *T = FirstTimer; T; T = T->Next) {
- if (!T->Started) continue;
- TimersToPrint.push_back(std::make_pair(T->Time, T->Name));
+ if (!T->hasTriggered()) continue;
+ TimersToPrint.emplace_back(T->Time, T->Name);
// Clear out the time.
- T->Started = 0;
- T->Time = TimeRecord();
+ T->clear();
}
// If any timers were started, print the group.
diff --git a/contrib/llvm/lib/Support/Triple.cpp b/contrib/llvm/lib/Support/Triple.cpp
index c6646fb..3bb1116 100644
--- a/contrib/llvm/lib/Support/Triple.cpp
+++ b/contrib/llvm/lib/Support/Triple.cpp
@@ -25,6 +25,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case aarch64_be: return "aarch64_be";
case arm: return "arm";
case armeb: return "armeb";
+ case avr: return "avr";
case bpfel: return "bpfel";
case bpfeb: return "bpfeb";
case hexagon: return "hexagon";
@@ -80,6 +81,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case thumb:
case thumbeb: return "arm";
+ case avr: return "avr";
+
case ppc64:
case ppc64le:
case ppc: return "ppc";
@@ -124,8 +127,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case spir64: return "spir";
case kalimba: return "kalimba";
case shave: return "shave";
- case wasm32: return "wasm32";
- case wasm64: return "wasm64";
+ case wasm32:
+ case wasm64: return "wasm";
}
}
@@ -144,6 +147,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) {
case MipsTechnologies: return "mti";
case NVIDIA: return "nvidia";
case CSR: return "csr";
+ case Myriad: return "myriad";
}
llvm_unreachable("Invalid VendorType!");
@@ -177,6 +181,9 @@ const char *Triple::getOSTypeName(OSType Kind) {
case NVCL: return "nvcl";
case AMDHSA: return "amdhsa";
case PS4: return "ps4";
+ case ELFIAMCU: return "elfiamcu";
+ case TvOS: return "tvos";
+ case WatchOS: return "watchos";
}
llvm_unreachable("Invalid OSType");
@@ -196,6 +203,8 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case MSVC: return "msvc";
case Itanium: return "itanium";
case Cygnus: return "cygnus";
+ case AMDOpenCL: return "amdopencl";
+ case CoreCLR: return "coreclr";
}
llvm_unreachable("Invalid EnvironmentType!");
@@ -224,6 +233,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
.Case("arm", arm)
.Case("armeb", armeb)
+ .Case("avr", avr)
.StartsWith("bpf", BPFArch)
.Case("mips", mips)
.Case("mipsel", mipsel)
@@ -265,8 +275,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
}
static Triple::ArchType parseARMArch(StringRef ArchName) {
- unsigned ISA = ARMTargetParser::parseArchISA(ArchName);
- unsigned ENDIAN = ARMTargetParser::parseArchEndian(ArchName);
+ unsigned ISA = ARM::parseArchISA(ArchName);
+ unsigned ENDIAN = ARM::parseArchEndian(ArchName);
Triple::ArchType arch = Triple::UnknownArch;
switch (ENDIAN) {
@@ -300,7 +310,7 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
}
}
- ArchName = ARMTargetParser::getCanonicalArchName(ArchName);
+ ArchName = ARM::getCanonicalArchName(ArchName);
if (ArchName.empty())
return Triple::UnknownArch;
@@ -310,8 +320,8 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
return Triple::UnknownArch;
// Thumb only for v6m
- unsigned Profile = ARMTargetParser::parseArchProfile(ArchName);
- unsigned Version = ARMTargetParser::parseArchVersion(ArchName);
+ unsigned Profile = ARM::parseArchProfile(ArchName);
+ unsigned Version = ARM::parseArchVersion(ArchName);
if (Profile == ARM::PK_M && Version == 6) {
if (ENDIAN == ARM::EK_BIG)
return Triple::thumbeb;
@@ -323,10 +333,7 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
}
static Triple::ArchType parseArch(StringRef ArchName) {
- Triple::ArchType ARMArch(parseARMArch(ArchName));
- Triple::ArchType BPFArch(parseBPFArch(ArchName));
-
- return StringSwitch<Triple::ArchType>(ArchName)
+ auto AT = StringSwitch<Triple::ArchType>(ArchName)
.Cases("i386", "i486", "i586", "i686", Triple::x86)
// FIXME: Do we need to support these?
.Cases("i786", "i886", "i986", Triple::x86)
@@ -336,9 +343,14 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("powerpc64le", Triple::ppc64le)
.Case("xscale", Triple::arm)
.Case("xscaleeb", Triple::armeb)
- .StartsWith("arm", ARMArch)
- .StartsWith("thumb", ARMArch)
- .StartsWith("aarch64", ARMArch)
+ .Case("aarch64", Triple::aarch64)
+ .Case("aarch64_be", Triple::aarch64_be)
+ .Case("arm64", Triple::aarch64)
+ .Case("arm", Triple::arm)
+ .Case("armeb", Triple::armeb)
+ .Case("thumb", Triple::thumb)
+ .Case("thumbeb", Triple::thumbeb)
+ .Case("avr", Triple::avr)
.Case("msp430", Triple::msp430)
.Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
.Cases("mipsel", "mipsallegrexel", Triple::mipsel)
@@ -346,7 +358,6 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("mips64el", Triple::mips64el)
.Case("r600", Triple::r600)
.Case("amdgcn", Triple::amdgcn)
- .StartsWith("bpf", BPFArch)
.Case("hexagon", Triple::hexagon)
.Case("s390x", Triple::systemz)
.Case("sparc", Triple::sparc)
@@ -369,6 +380,18 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("wasm32", Triple::wasm32)
.Case("wasm64", Triple::wasm64)
.Default(Triple::UnknownArch);
+
+ // Some architectures require special parsing logic just to compute the
+ // ArchType result.
+ if (AT == Triple::UnknownArch) {
+ if (ArchName.startswith("arm") || ArchName.startswith("thumb") ||
+ ArchName.startswith("aarch64"))
+ return parseARMArch(ArchName);
+ if (ArchName.startswith("bpf"))
+ return parseBPFArch(ArchName);
+ }
+
+ return AT;
}
static Triple::VendorType parseVendor(StringRef VendorName) {
@@ -384,6 +407,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
.Case("mti", Triple::MipsTechnologies)
.Case("nvidia", Triple::NVIDIA)
.Case("csr", Triple::CSR)
+ .Case("myriad", Triple::Myriad)
.Default(Triple::UnknownVendor);
}
@@ -414,6 +438,9 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("nvcl", Triple::NVCL)
.StartsWith("amdhsa", Triple::AMDHSA)
.StartsWith("ps4", Triple::PS4)
+ .StartsWith("elfiamcu", Triple::ELFIAMCU)
+ .StartsWith("tvos", Triple::TvOS)
+ .StartsWith("watchos", Triple::WatchOS)
.Default(Triple::UnknownOS);
}
@@ -430,6 +457,8 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
.StartsWith("msvc", Triple::MSVC)
.StartsWith("itanium", Triple::Itanium)
.StartsWith("cygnus", Triple::Cygnus)
+ .StartsWith("amdopencl", Triple::AMDOpenCL)
+ .StartsWith("coreclr", Triple::CoreCLR)
.Default(Triple::UnknownEnvironment);
}
@@ -442,7 +471,7 @@ static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
}
static Triple::SubArchType parseSubArch(StringRef SubArchName) {
- StringRef ARMSubArch = ARMTargetParser::getCanonicalArchName(SubArchName);
+ StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName);
// For now, this is the small part. Early return.
if (ARMSubArch.empty())
@@ -453,14 +482,12 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
.Default(Triple::NoSubArch);
// ARM sub arch.
- switch(ARMTargetParser::parseArch(ARMSubArch)) {
+ switch(ARM::parseArch(ARMSubArch)) {
case ARM::AK_ARMV4:
return Triple::NoSubArch;
case ARM::AK_ARMV4T:
return Triple::ARMSubArch_v4t;
- case ARM::AK_ARMV5:
case ARM::AK_ARMV5T:
- case ARM::AK_ARMV5E:
return Triple::ARMSubArch_v5;
case ARM::AK_ARMV5TE:
case ARM::AK_IWMMXT:
@@ -469,24 +496,19 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
case ARM::AK_ARMV5TEJ:
return Triple::ARMSubArch_v5te;
case ARM::AK_ARMV6:
- case ARM::AK_ARMV6J:
- case ARM::AK_ARMV6Z:
return Triple::ARMSubArch_v6;
case ARM::AK_ARMV6K:
- case ARM::AK_ARMV6ZK:
- case ARM::AK_ARMV6HL:
+ case ARM::AK_ARMV6KZ:
return Triple::ARMSubArch_v6k;
case ARM::AK_ARMV6T2:
return Triple::ARMSubArch_v6t2;
case ARM::AK_ARMV6M:
- case ARM::AK_ARMV6SM:
return Triple::ARMSubArch_v6m;
- case ARM::AK_ARMV7:
case ARM::AK_ARMV7A:
case ARM::AK_ARMV7R:
- case ARM::AK_ARMV7L:
- case ARM::AK_ARMV7HL:
return Triple::ARMSubArch_v7;
+ case ARM::AK_ARMV7K:
+ return Triple::ARMSubArch_v7k;
case ARM::AK_ARMV7M:
return Triple::ARMSubArch_v7m;
case ARM::AK_ARMV7S:
@@ -497,6 +519,8 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
return Triple::ARMSubArch_v8;
case ARM::AK_ARMV8_1A:
return Triple::ARMSubArch_v8_1a;
+ case ARM::AK_ARMV8_2A:
+ return Triple::ARMSubArch_v8_2a;
default:
return Triple::NoSubArch;
}
@@ -514,20 +538,53 @@ static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
switch (T.getArch()) {
- default:
- break;
+ case Triple::UnknownArch:
+ case Triple::aarch64:
+ case Triple::arm:
+ case Triple::thumb:
+ case Triple::x86:
+ case Triple::x86_64:
+ if (T.isOSDarwin())
+ return Triple::MachO;
+ else if (T.isOSWindows())
+ return Triple::COFF;
+ return Triple::ELF;
+
+ case Triple::aarch64_be:
+ case Triple::amdgcn:
+ case Triple::amdil:
+ case Triple::amdil64:
+ case Triple::armeb:
+ case Triple::avr:
+ case Triple::bpfeb:
+ case Triple::bpfel:
case Triple::hexagon:
+ case Triple::hsail:
+ case Triple::hsail64:
+ case Triple::kalimba:
+ case Triple::le32:
+ case Triple::le64:
case Triple::mips:
- case Triple::mipsel:
case Triple::mips64:
case Triple::mips64el:
+ case Triple::mipsel:
+ case Triple::msp430:
+ case Triple::nvptx:
+ case Triple::nvptx64:
+ case Triple::ppc64le:
case Triple::r600:
- case Triple::amdgcn:
+ case Triple::shave:
case Triple::sparc:
+ case Triple::sparcel:
case Triple::sparcv9:
+ case Triple::spir:
+ case Triple::spir64:
case Triple::systemz:
+ case Triple::tce:
+ case Triple::thumbeb:
+ case Triple::wasm32:
+ case Triple::wasm64:
case Triple::xcore:
- case Triple::ppc64le:
return Triple::ELF;
case Triple::ppc:
@@ -536,12 +593,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
return Triple::MachO;
return Triple::ELF;
}
-
- if (T.isOSDarwin())
- return Triple::MachO;
- else if (T.isOSWindows())
- return Triple::COFF;
- return Triple::ELF;
+ llvm_unreachable("unknown architecture");
}
/// \brief Construct a triple from the string representation provided.
@@ -549,14 +601,27 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
/// This stores the string representation and parses the various pieces into
/// enum members.
Triple::Triple(const Twine &Str)
- : Data(Str.str()),
- Arch(parseArch(getArchName())),
- SubArch(parseSubArch(getArchName())),
- Vendor(parseVendor(getVendorName())),
- OS(parseOS(getOSName())),
- Environment(parseEnvironment(getEnvironmentName())),
- ObjectFormat(parseFormat(getEnvironmentName())) {
- if (ObjectFormat == Triple::UnknownObjectFormat)
+ : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch),
+ Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment),
+ ObjectFormat(UnknownObjectFormat) {
+ // Do minimal parsing by hand here.
+ SmallVector<StringRef, 4> Components;
+ StringRef(Data).split(Components, '-', /*MaxSplit*/ 3);
+ if (Components.size() > 0) {
+ Arch = parseArch(Components[0]);
+ SubArch = parseSubArch(Components[0]);
+ if (Components.size() > 1) {
+ Vendor = parseVendor(Components[1]);
+ if (Components.size() > 2) {
+ OS = parseOS(Components[2]);
+ if (Components.size() > 3) {
+ Environment = parseEnvironment(Components[3]);
+ ObjectFormat = parseFormat(Components[3]);
+ }
+ }
+ }
+ }
+ if (ObjectFormat == UnknownObjectFormat)
ObjectFormat = getDefaultFormat(*this);
}
@@ -601,7 +666,7 @@ std::string Triple::normalize(StringRef Str) {
// Parse into components.
SmallVector<StringRef, 4> Components;
- Str.split(Components, "-");
+ Str.split(Components, '-');
// If the first component corresponds to a known architecture, preferentially
// use it for the architecture. If the second component corresponds to a
@@ -889,6 +954,8 @@ bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
return false;
break;
case IOS:
+ case TvOS:
+ case WatchOS:
// Ignore the version from the triple. This is only handled because the
// the clang driver combines OS X and IOS support into a common Darwin
// toolchain that wants to know the OS X version number even when targeting
@@ -916,11 +983,38 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
Micro = 0;
break;
case IOS:
+ case TvOS:
getOSVersion(Major, Minor, Micro);
// Default to 5.0 (or 7.0 for arm64).
if (Major == 0)
Major = (getArch() == aarch64) ? 7 : 5;
break;
+ case WatchOS:
+ llvm_unreachable("conflicting triple info");
+ }
+}
+
+void Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const {
+ switch (getOS()) {
+ default: llvm_unreachable("unexpected OS for Darwin triple");
+ case Darwin:
+ case MacOSX:
+ // Ignore the version from the triple. This is only handled because the
+ // the clang driver combines OS X and IOS support into a common Darwin
+ // toolchain that wants to know the iOS version number even when targeting
+ // OS X.
+ Major = 2;
+ Minor = 0;
+ Micro = 0;
+ break;
+ case WatchOS:
+ getOSVersion(Major, Minor, Micro);
+ if (Major == 0)
+ Major = 2;
+ break;
+ case IOS:
+ llvm_unreachable("conflicting triple info");
}
}
@@ -993,6 +1087,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::UnknownArch:
return 0;
+ case llvm::Triple::avr:
case llvm::Triple::msp430:
return 16;
@@ -1062,6 +1157,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::aarch64:
case Triple::aarch64_be:
case Triple::amdgcn:
+ case Triple::avr:
case Triple::bpfel:
case Triple::bpfeb:
case Triple::msp430:
@@ -1116,6 +1212,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::UnknownArch:
case Triple::arm:
case Triple::armeb:
+ case Triple::avr:
case Triple::hexagon:
case Triple::kalimba:
case Triple::msp430:
@@ -1172,6 +1269,7 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::amdgcn:
case Triple::amdil64:
case Triple::amdil:
+ case Triple::avr:
case Triple::hexagon:
case Triple::hsail64:
case Triple::hsail:
@@ -1244,6 +1342,7 @@ Triple Triple::getLittleEndianArchVariant() const {
case Triple::amdil64:
case Triple::amdil:
case Triple::arm:
+ case Triple::avr:
case Triple::bpfel:
case Triple::hexagon:
case Triple::hsail64:
@@ -1281,10 +1380,10 @@ Triple Triple::getLittleEndianArchVariant() const {
return T;
}
-const char *Triple::getARMCPUForArch(StringRef MArch) const {
+StringRef Triple::getARMCPUForArch(StringRef MArch) const {
if (MArch.empty())
MArch = getArchName();
- MArch = ARMTargetParser::getCanonicalArchName(MArch);
+ MArch = ARM::getCanonicalArchName(MArch);
// Some defaults are forced.
switch (getOS()) {
@@ -1296,15 +1395,21 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
case llvm::Triple::Win32:
// FIXME: this is invalid for WindowsCE
return "cortex-a9";
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::WatchOS:
+ if (MArch == "v7k")
+ return "cortex-a7";
+ break;
default:
break;
}
if (MArch.empty())
- return nullptr;
+ return StringRef();
- const char *CPU = ARMTargetParser::getDefaultCPU(MArch);
- if (CPU)
+ StringRef CPU = ARM::getDefaultCPU(MArch);
+ if (!CPU.empty())
return CPU;
// If no specific architecture version is requested, return the minimum CPU
diff --git a/contrib/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm/lib/Support/Unix/Memory.inc
index c421ee8..d703191 100644
--- a/contrib/llvm/lib/Support/Unix/Memory.inc
+++ b/contrib/llvm/lib/Support/Unix/Memory.inc
@@ -50,9 +50,8 @@ int getPosixProtectionFlags(unsigned Flags) {
return PROT_READ | PROT_WRITE;
case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
return PROT_READ | PROT_EXEC;
- case llvm::sys::Memory::MF_READ |
- llvm::sys::Memory::MF_WRITE |
- llvm::sys::Memory::MF_EXEC:
+ case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE |
+ llvm::sys::Memory::MF_EXEC:
return PROT_READ | PROT_WRITE | PROT_EXEC;
case llvm::sys::Memory::MF_EXEC:
#if defined(__FreeBSD__)
@@ -153,6 +152,7 @@ Memory::releaseMappedMemory(MemoryBlock &M) {
std::error_code
Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
+ static const size_t PageSize = Process::getPageSize();
if (M.Address == nullptr || M.Size == 0)
return std::error_code();
@@ -161,7 +161,7 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
int Protect = getPosixProtectionFlags(Flags);
- int Result = ::mprotect(M.Address, M.Size, Protect);
+ int Result = ::mprotect((void*)((uintptr_t)M.Address & ~(PageSize-1)), PageSize*((M.Size+PageSize-1)/PageSize), Protect);
if (Result != 0)
return std::error_code(errno, std::generic_category());
@@ -181,7 +181,7 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
std::string *ErrMsg) {
if (NumBytes == 0) return MemoryBlock();
- size_t PageSize = Process::getPageSize();
+ static const size_t PageSize = Process::getPageSize();
size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
@@ -265,15 +265,12 @@ bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
}
bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
-#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
if (M.Address == 0 || M.Size == 0) return false;
Memory::InvalidateInstructionCache(M.Address, M.Size);
+#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
(vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
return KERN_SUCCESS == kr;
-#elif defined(__arm__) || defined(__aarch64__)
- Memory::InvalidateInstructionCache(M.Address, M.Size);
- return true;
#else
return true;
#endif
diff --git a/contrib/llvm/lib/Support/Unix/Path.inc b/contrib/llvm/lib/Support/Unix/Path.inc
index 973d010..d85c37a 100644
--- a/contrib/llvm/lib/Support/Unix/Path.inc
+++ b/contrib/llvm/lib/Support/Unix/Path.inc
@@ -75,12 +75,12 @@ test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
char fullpath[PATH_MAX];
snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin);
- if (realpath(fullpath, ret) == NULL)
- return (1);
+ if (!realpath(fullpath, ret))
+ return 1;
if (stat(fullpath, &sb) != 0)
- return (1);
+ return 1;
- return (0);
+ return 0;
}
static char *
@@ -91,34 +91,34 @@ getprogpath(char ret[PATH_MAX], const char *bin)
/* First approach: absolute path. */
if (bin[0] == '/') {
if (test_dir(ret, "/", bin) == 0)
- return (ret);
- return (NULL);
+ return ret;
+ return nullptr;
}
/* Second approach: relative path. */
- if (strchr(bin, '/') != NULL) {
+ if (strchr(bin, '/')) {
char cwd[PATH_MAX];
- if (getcwd(cwd, PATH_MAX) == NULL)
- return (NULL);
+ if (!getcwd(cwd, PATH_MAX))
+ return nullptr;
if (test_dir(ret, cwd, bin) == 0)
- return (ret);
- return (NULL);
+ return ret;
+ return nullptr;
}
/* Third approach: $PATH */
- if ((pv = getenv("PATH")) == NULL)
- return (NULL);
+ if ((pv = getenv("PATH")) == nullptr)
+ return nullptr;
s = pv = strdup(pv);
- if (pv == NULL)
- return (NULL);
- while ((t = strsep(&s, ":")) != NULL) {
+ if (!pv)
+ return nullptr;
+ while ((t = strsep(&s, ":")) != nullptr) {
if (test_dir(ret, t, bin) == 0) {
free(pv);
- return (ret);
+ return ret;
}
}
free(pv);
- return (NULL);
+ return nullptr;
}
#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__
@@ -153,8 +153,8 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
return std::string(exe_path, len);
} else {
// Fall back to the classical detection.
- if (getprogpath(exe_path, argv0) != NULL)
- return exe_path;
+ if (getprogpath(exe_path, argv0))
+ return exe_path;
}
#elif defined(HAVE_DLFCN_H)
// Use dladdr to get executable path if available.
@@ -219,11 +219,12 @@ std::error_code current_path(SmallVectorImpl<char> &result) {
return std::error_code();
}
-std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
+std::error_code create_directory(const Twine &path, bool IgnoreExisting,
+ perms Perms) {
SmallString<128> path_storage;
StringRef p = path.toNullTerminatedStringRef(path_storage);
- if (::mkdir(p.begin(), S_IRWXU | S_IRWXG) == -1) {
+ if (::mkdir(p.begin(), Perms) == -1) {
if (errno != EEXIST || !IgnoreExisting)
return std::error_code(errno, std::generic_category());
}
@@ -324,6 +325,10 @@ std::error_code access(const Twine &Path, AccessMode Mode) {
return std::error_code();
}
+bool can_execute(const Twine &Path) {
+ return !access(Path, AccessMode::Execute);
+}
+
bool equivalent(file_status A, file_status B) {
assert(status_known(A) && status_known(B));
return A.fs_st_dev == B.fs_st_dev &&
@@ -555,6 +560,54 @@ bool home_directory(SmallVectorImpl<char> &result) {
return false;
}
+static bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) {
+ #if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
+ // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
+ // macros defined in <unistd.h> on darwin >= 9
+ int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR
+ : _CS_DARWIN_USER_CACHE_DIR;
+ size_t ConfLen = confstr(ConfName, nullptr, 0);
+ if (ConfLen > 0) {
+ do {
+ Result.resize(ConfLen);
+ ConfLen = confstr(ConfName, Result.data(), Result.size());
+ } while (ConfLen > 0 && ConfLen != Result.size());
+
+ if (ConfLen > 0) {
+ assert(Result.back() == 0);
+ Result.pop_back();
+ return true;
+ }
+
+ Result.clear();
+ }
+ #endif
+ return false;
+}
+
+static bool getUserCacheDir(SmallVectorImpl<char> &Result) {
+ // First try using XDS_CACHE_HOME env variable,
+ // as specified in XDG Base Directory Specification at
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ if (const char *XdsCacheDir = std::getenv("XDS_CACHE_HOME")) {
+ Result.clear();
+ Result.append(XdsCacheDir, XdsCacheDir + strlen(XdsCacheDir));
+ return true;
+ }
+
+ // Try Darwin configuration query
+ if (getDarwinConfDir(false, Result))
+ return true;
+
+ // Use "$HOME/.cache" if $HOME is available
+ if (home_directory(Result)) {
+ append(Result, ".cache");
+ return true;
+ }
+
+ return false;
+}
+
static const char *getEnvTempDir() {
// Check whether the temporary directory is specified by an environment
// variable.
@@ -589,27 +642,8 @@ void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
}
}
-#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
- // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
- // macros defined in <unistd.h> on darwin >= 9
- int ConfName = ErasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
- : _CS_DARWIN_USER_CACHE_DIR;
- size_t ConfLen = confstr(ConfName, nullptr, 0);
- if (ConfLen > 0) {
- do {
- Result.resize(ConfLen);
- ConfLen = confstr(ConfName, Result.data(), Result.size());
- } while (ConfLen > 0 && ConfLen != Result.size());
-
- if (ConfLen > 0) {
- assert(Result.back() == 0);
- Result.pop_back();
- return;
- }
-
- Result.clear();
- }
-#endif
+ if (getDarwinConfDir(ErasedOnReboot, Result))
+ return;
const char *RequestedDir = getDefaultTempDir(ErasedOnReboot);
Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
diff --git a/contrib/llvm/lib/Support/Unix/Process.inc b/contrib/llvm/lib/Support/Unix/Process.inc
index df13bd2..27083ee 100644
--- a/contrib/llvm/lib/Support/Unix/Process.inc
+++ b/contrib/llvm/lib/Support/Unix/Process.inc
@@ -430,13 +430,18 @@ const char *Process::ResetColor() {
#if !defined(HAVE_DECL_ARC4RANDOM) || !HAVE_DECL_ARC4RANDOM
static unsigned GetRandomNumberSeed() {
// Attempt to get the initial seed from /dev/urandom, if possible.
- if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) {
+ int urandomFD = open("/dev/urandom", O_RDONLY);
+
+ if (urandomFD != -1) {
unsigned seed;
- int count = ::fread((void *)&seed, sizeof(seed), 1, RandomSource);
- ::fclose(RandomSource);
+ // Don't use a buffered read to avoid reading more data
+ // from /dev/urandom than we need.
+ int count = read(urandomFD, (void *)&seed, sizeof(seed));
+
+ close(urandomFD);
// Return the seed if the read was successful.
- if (count == 1)
+ if (count == sizeof(seed))
return seed;
}
diff --git a/contrib/llvm/lib/Support/Unix/Program.inc b/contrib/llvm/lib/Support/Unix/Program.inc
index 8947b62..a8d1fe3 100644
--- a/contrib/llvm/lib/Support/Unix/Program.inc
+++ b/contrib/llvm/lib/Support/Unix/Program.inc
@@ -323,7 +323,6 @@ namespace llvm {
ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
bool WaitUntilTerminates, std::string *ErrMsg) {
-#ifdef HAVE_SYS_WAIT_H
struct sigaction Act, Old;
assert(PI.Pid && "invalid pid to wait on, process not started?");
@@ -417,12 +416,6 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
// signal during execution as opposed to failing to execute.
WaitResult.ReturnCode = -2;
}
-#else
- if (ErrMsg)
- *ErrMsg = "Program::Wait is not implemented on this platform yet!";
- ProcessInfo WaitResult;
- WaitResult.ReturnCode = -2;
-#endif
return WaitResult;
}
diff --git a/contrib/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm/lib/Support/Unix/Signals.inc
index bfe2a3a..061cdb3 100644
--- a/contrib/llvm/lib/Support/Unix/Signals.inc
+++ b/contrib/llvm/lib/Support/Unix/Signals.inc
@@ -17,7 +17,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Program.h"
@@ -25,7 +24,6 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>
-#include <vector>
#if HAVE_EXECINFO_H
# include <execinfo.h> // For backtrace().
#endif
@@ -58,8 +56,6 @@ static ManagedStatic<SmartMutex<true> > SignalsMutex;
static void (*InterruptFunction)() = nullptr;
static ManagedStatic<std::vector<std::string>> FilesToRemove;
-static ManagedStatic<std::vector<std::pair<void (*)(void *), void *>>>
- CallBacksToRun;
// IntSigs - Signals that represent requested termination. There's no bug
// or failure, or if there is, it's not our direct responsibility. For whatever
@@ -90,12 +86,11 @@ static unsigned NumRegisteredSignals = 0;
static struct {
struct sigaction SA;
int SigNo;
-} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])];
+} RegisteredSignalInfo[array_lengthof(IntSigs) + array_lengthof(KillSigs)];
static void RegisterHandler(int Signal) {
- assert(NumRegisteredSignals <
- sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) &&
+ assert(NumRegisteredSignals < array_lengthof(RegisteredSignalInfo) &&
"Out of space for signal handlers!");
struct sigaction NewHandler;
@@ -117,7 +112,7 @@ static void RegisterHandlers() {
// during handling an actual signal because you can't safely call new in a
// signal handler.
*SignalsMutex;
-
+
// If the handlers are already registered, we're done.
if (NumRegisteredSignals != 0) return;
@@ -148,9 +143,6 @@ static void RemoveFilesToRemove() {
// memory.
std::vector<std::string>& FilesToRemoveRef = *FilesToRemove;
for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) {
- // We rely on a std::string implementation for which repeated calls to
- // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these
- // strings to try to ensure this is safe.
const char *path = FilesToRemoveRef[i].c_str();
// Get the status so we can determine if it's a file or directory. If we
@@ -164,7 +156,7 @@ static void RemoveFilesToRemove() {
// super-user permissions.
if (!S_ISREG(buf.st_mode))
continue;
-
+
// Otherwise, remove the file. We ignore any errors here as there is nothing
// else we can do.
unlink(path);
@@ -205,11 +197,7 @@ static RETSIGTYPE SignalHandler(int Sig) {
}
// Otherwise if it is a fault (like SEGV) run any handler.
- if (CallBacksToRun.isConstructed()) {
- auto &CallBacksToRunRef = *CallBacksToRun;
- for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
- CallBacksToRunRef[i].first(CallBacksToRunRef[i].second);
- }
+ llvm::sys::RunSignalHandlers();
#ifdef __s390__
// On S/390, certain signals are delivered with PSW Address pointing to
@@ -239,21 +227,7 @@ bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
std::string* ErrMsg) {
{
sys::SmartScopedLock<true> Guard(*SignalsMutex);
- std::vector<std::string>& FilesToRemoveRef = *FilesToRemove;
- std::string *OldPtr =
- FilesToRemoveRef.empty() ? nullptr : &FilesToRemoveRef[0];
- FilesToRemoveRef.push_back(Filename);
-
- // We want to call 'c_str()' on every std::string in this vector so that if
- // the underlying implementation requires a re-allocation, it happens here
- // rather than inside of the signal handler. If we see the vector grow, we
- // have to call it on every entry. If it remains in place, we only need to
- // call it on the latest one.
- if (OldPtr == &FilesToRemoveRef[0])
- FilesToRemoveRef.back().c_str();
- else
- for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i)
- FilesToRemoveRef[i].c_str();
+ FilesToRemove->push_back(Filename);
}
RegisterHandlers();
@@ -268,13 +242,6 @@ void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {
std::vector<std::string>::iterator I = FilesToRemove->end();
if (RI != FilesToRemove->rend())
I = FilesToRemove->erase(RI.base()-1);
-
- // We need to call c_str() on every element which would have been moved by
- // the erase. These elements, in a C++98 implementation where c_str()
- // requires a reallocation on the first call may have had the call to c_str()
- // made on insertion become invalid by being copied down an element.
- for (std::vector<std::string>::iterator E = FilesToRemove->end(); I != E; ++I)
- I->c_str();
}
/// AddSignalHandler - Add a function to be called when a signal is delivered
@@ -285,10 +252,9 @@ void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
RegisterHandlers();
}
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
-
-#if HAVE_LINK_H && (defined(__linux__) || defined(__FreeBSD__) || \
- defined(__FreeBSD_kernel__) || defined(__NetBSD__))
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) && HAVE_LINK_H && \
+ (defined(__linux__) || defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || defined(__NetBSD__))
struct DlIteratePhdrData {
void **StackTrace;
int depth;
@@ -321,108 +287,27 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
return 0;
}
+/// If this is an ELF platform, we can find all loaded modules and their virtual
+/// addresses with dl_iterate_phdr.
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
- const char *MainExecutableName) {
+ const char *MainExecutableName,
+ StringSaver &StrPool) {
DlIteratePhdrData data = {StackTrace, Depth, true,
Modules, Offsets, MainExecutableName};
dl_iterate_phdr(dl_iterate_phdr_cb, &data);
return true;
}
#else
+/// This platform does not have dl_iterate_phdr, so we do not yet know how to
+/// find all loaded DSOs.
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
- const char *MainExecutableName) {
+ const char *MainExecutableName,
+ StringSaver &StrPool) {
return false;
}
-#endif
-
-static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
- llvm::raw_ostream &OS) {
- // FIXME: Subtract necessary number from StackTrace entries to turn return addresses
- // into actual instruction addresses.
- // Use llvm-symbolizer tool to symbolize the stack traces.
- ErrorOr<std::string> LLVMSymbolizerPathOrErr =
- sys::findProgramByName("llvm-symbolizer");
- if (!LLVMSymbolizerPathOrErr)
- return false;
- const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
- // We don't know argv0 or the address of main() at this point, but try
- // to guess it anyway (it's possible on some platforms).
- std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr);
- if (MainExecutableName.empty() ||
- MainExecutableName.find("llvm-symbolizer") != std::string::npos)
- return false;
-
- std::vector<const char *> Modules(Depth, nullptr);
- std::vector<intptr_t> Offsets(Depth, 0);
- if (!findModulesAndOffsets(StackTrace, Depth, Modules.data(), Offsets.data(),
- MainExecutableName.c_str()))
- return false;
- int InputFD;
- SmallString<32> InputFile, OutputFile;
- sys::fs::createTemporaryFile("symbolizer-input", "", InputFD, InputFile);
- sys::fs::createTemporaryFile("symbolizer-output", "", OutputFile);
- FileRemover InputRemover(InputFile.c_str());
- FileRemover OutputRemover(OutputFile.c_str());
-
- {
- raw_fd_ostream Input(InputFD, true);
- for (int i = 0; i < Depth; i++) {
- if (Modules[i])
- Input << Modules[i] << " " << (void*)Offsets[i] << "\n";
- }
- }
-
- StringRef InputFileStr(InputFile);
- StringRef OutputFileStr(OutputFile);
- StringRef StderrFileStr;
- const StringRef *Redirects[] = {&InputFileStr, &OutputFileStr,
- &StderrFileStr};
- const char *Args[] = {"llvm-symbolizer", "--functions=linkage", "--inlining",
- "--demangle", nullptr};
- int RunResult =
- sys::ExecuteAndWait(LLVMSymbolizerPath, Args, nullptr, Redirects);
- if (RunResult != 0)
- return false;
-
- auto OutputBuf = MemoryBuffer::getFile(OutputFile.c_str());
- if (!OutputBuf)
- return false;
- StringRef Output = OutputBuf.get()->getBuffer();
- SmallVector<StringRef, 32> Lines;
- Output.split(Lines, "\n");
- auto CurLine = Lines.begin();
- int frame_no = 0;
- for (int i = 0; i < Depth; i++) {
- if (!Modules[i]) {
- OS << format("#%d %p\n", frame_no++, StackTrace[i]);
- continue;
- }
- // Read pairs of lines (function name and file/line info) until we
- // encounter empty line.
- for (;;) {
- if (CurLine == Lines.end())
- return false;
- StringRef FunctionName = *CurLine++;
- if (FunctionName.empty())
- break;
- OS << format("#%d %p ", frame_no++, StackTrace[i]);
- if (!FunctionName.startswith("??"))
- OS << format("%s ", FunctionName.str().c_str());
- if (CurLine == Lines.end())
- return false;
- StringRef FileLineInfo = *CurLine++;
- if (!FileLineInfo.startswith("??"))
- OS << format("%s", FileLineInfo.str().c_str());
- else
- OS << format("(%s+%p)", Modules[i], (void *)Offsets[i]);
- OS << "\n";
- }
- }
- return true;
-}
-#endif // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#endif // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) && ...
// PrintStackTrace - In the case of a program crash or fault, print out a stack
// trace so that the user has an indication of why and where we died.
diff --git a/contrib/llvm/lib/Support/Unix/Unix.h b/contrib/llvm/lib/Support/Unix/Unix.h
index e16a226..871e612 100644
--- a/contrib/llvm/lib/Support/Unix/Unix.h
+++ b/contrib/llvm/lib/Support/Unix/Unix.h
@@ -29,6 +29,7 @@
#include <cstring>
#include <string>
#include <sys/types.h>
+#include <sys/wait.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -43,22 +44,10 @@
#endif
#include <time.h>
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-#endif
-
-#ifndef WIFEXITED
-# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif
-
/// This function builds an error message into \p ErrMsg using the \p prefix
/// string and the Unix error number given by \p errnum. If errnum is -1, the
/// default then the value of errno is used.
diff --git a/contrib/llvm/lib/Support/Valgrind.cpp b/contrib/llvm/lib/Support/Valgrind.cpp
index facf8d9..8d852a6 100644
--- a/contrib/llvm/lib/Support/Valgrind.cpp
+++ b/contrib/llvm/lib/Support/Valgrind.cpp
@@ -15,6 +15,7 @@
#include "llvm/Support/Valgrind.h"
#include "llvm/Config/config.h"
+#include <cstddef>
#if HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>
@@ -52,23 +53,3 @@ void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
}
#endif // !HAVE_VALGRIND_VALGRIND_H
-
-// These functions require no implementation, tsan just looks at the arguments
-// they're called with. However, they are required to be weak as some other
-// application or library may already be providing these definitions for the
-// same reason we are.
-extern "C" {
-LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
- const volatile void *cv);
-void AnnotateHappensAfter(const char *file, int line, const volatile void *cv) {
-}
-LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
- const volatile void *cv);
-void AnnotateHappensBefore(const char *file, int line,
- const volatile void *cv) {}
-LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
-void AnnotateIgnoreWritesBegin(const char *file, int line) {}
-LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
-void AnnotateIgnoreWritesEnd(const char *file, int line) {}
-}
-
diff --git a/contrib/llvm/lib/Support/Windows/COM.inc b/contrib/llvm/lib/Support/Windows/COM.inc
index 0c50d6f..54f3ecf 100644
--- a/contrib/llvm/lib/Support/Windows/COM.inc
+++ b/contrib/llvm/lib/Support/Windows/COM.inc
@@ -1,4 +1,4 @@
-//===- llvm/Support/Windows/COM.inc - Windows COM Implementation *- C++ -*-===//
+//==- llvm/Support/Windows/COM.inc - Windows COM Implementation -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
index d38f197..17418b0 100644
--- a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
+++ b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
@@ -76,14 +76,14 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
SmallVector<wchar_t, MAX_PATH> filenameUnicode;
if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
SetLastError(ec.value());
- MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16: ");
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16");
return DynamicLibrary();
}
HMODULE a_handle = LoadLibraryW(filenameUnicode.data());
if (a_handle == 0) {
- MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't open");
return DynamicLibrary();
}
diff --git a/contrib/llvm/lib/Support/Windows/Memory.inc b/contrib/llvm/lib/Support/Windows/Memory.inc
index 4b2ff2e..7eab9ff 100644
--- a/contrib/llvm/lib/Support/Windows/Memory.inc
+++ b/contrib/llvm/lib/Support/Windows/Memory.inc
@@ -192,14 +192,14 @@ static DWORD getProtection(const void *addr) {
bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
if (!setRangeWritable(M.Address, M.Size)) {
- return MakeErrMsg(ErrMsg, "Cannot set memory to writeable: ");
+ return MakeErrMsg(ErrMsg, "Cannot set memory to writeable");
}
return true;
}
bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
if (!setRangeExecutable(M.Address, M.Size)) {
- return MakeErrMsg(ErrMsg, "Cannot set memory to executable: ");
+ return MakeErrMsg(ErrMsg, "Cannot set memory to executable");
}
return true;
}
diff --git a/contrib/llvm/lib/Support/Windows/Path.inc b/contrib/llvm/lib/Support/Windows/Path.inc
index 72da7c5..4e48412 100644
--- a/contrib/llvm/lib/Support/Windows/Path.inc
+++ b/contrib/llvm/lib/Support/Windows/Path.inc
@@ -182,7 +182,8 @@ std::error_code current_path(SmallVectorImpl<char> &result) {
return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result);
}
-std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
+std::error_code create_directory(const Twine &path, bool IgnoreExisting,
+ perms Perms) {
SmallVector<wchar_t, 128> path_utf16;
if (std::error_code ec = widenPath(path, path_utf16))
@@ -252,17 +253,34 @@ std::error_code rename(const Twine &from, const Twine &to) {
return ec;
std::error_code ec = std::error_code();
+
+ // Retry while we see ERROR_ACCESS_DENIED.
+ // System scanners (eg. indexer) might open the source file when it is written
+ // and closed.
+
for (int i = 0; i < 2000; i++) {
+ // Try ReplaceFile first, as it is able to associate a new data stream with
+ // the destination even if the destination file is currently open.
+ if (::ReplaceFileW(wide_to.begin(), wide_from.begin(), NULL, 0, NULL, NULL))
+ return std::error_code();
+
+ // We get ERROR_FILE_NOT_FOUND if the destination file is missing.
+ // MoveFileEx can handle this case.
+ DWORD ReplaceError = ::GetLastError();
+ ec = mapWindowsError(ReplaceError);
+ if (ReplaceError != ERROR_ACCESS_DENIED &&
+ ReplaceError != ERROR_FILE_NOT_FOUND &&
+ ReplaceError != ERROR_SHARING_VIOLATION)
+ break;
+
if (::MoveFileExW(wide_from.begin(), wide_to.begin(),
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
return std::error_code();
- DWORD LastError = ::GetLastError();
- ec = mapWindowsError(LastError);
- if (LastError != ERROR_ACCESS_DENIED)
- break;
- // Retry MoveFile() at ACCESS_DENIED.
- // System scanners (eg. indexer) might open the source file when
- // It is written and closed.
+
+ DWORD MoveError = ::GetLastError();
+ ec = mapWindowsError(MoveError);
+ if (MoveError != ERROR_ACCESS_DENIED) break;
+
::Sleep(1);
}
@@ -301,6 +319,11 @@ std::error_code access(const Twine &Path, AccessMode Mode) {
return std::error_code();
}
+bool can_execute(const Twine &Path) {
+ return !access(Path, AccessMode::Execute) ||
+ !access(Path + ".exe", AccessMode::Execute);
+}
+
bool equivalent(file_status A, file_status B) {
assert(status_known(A) && status_known(B));
return A.FileIndexHigh == B.FileIndexHigh &&
@@ -325,10 +348,12 @@ std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
static bool isReservedName(StringRef path) {
// This list of reserved names comes from MSDN, at:
// http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
- static const char *sReservedNames[] = { "nul", "con", "prn", "aux",
- "com1", "com2", "com3", "com4", "com5", "com6",
- "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
- "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" };
+ static const char *const sReservedNames[] = { "nul", "con", "prn", "aux",
+ "com1", "com2", "com3", "com4",
+ "com5", "com6", "com7", "com8",
+ "com9", "lpt1", "lpt2", "lpt3",
+ "lpt4", "lpt5", "lpt6", "lpt7",
+ "lpt8", "lpt9" };
// First, check to see if this is a device namespace, which always
// starts with \\.\, since device namespaces are not legal file paths.
@@ -643,9 +668,10 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD) {
if (std::error_code EC = widenPath(Name, PathUTF16))
return EC;
- HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ HANDLE H =
+ ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (H == INVALID_HANDLE_VALUE) {
DWORD LastError = ::GetLastError();
std::error_code EC = mapWindowsError(LastError);
@@ -728,30 +754,31 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
} // end namespace fs
namespace path {
-
-bool home_directory(SmallVectorImpl<char> &result) {
- wchar_t Path[MAX_PATH];
- if (::SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0,
- /*SHGFP_TYPE_CURRENT*/0, Path) != S_OK)
+static bool getKnownFolderPath(KNOWNFOLDERID folderId,
+ SmallVectorImpl<char> &result) {
+ wchar_t *path = nullptr;
+ if (::SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, nullptr, &path) != S_OK)
return false;
- if (UTF16ToUTF8(Path, ::wcslen(Path), result))
- return false;
+ bool ok = !UTF16ToUTF8(path, ::wcslen(path), result);
+ ::CoTaskMemFree(path);
+ return ok;
+}
- return true;
+bool getUserCacheDir(SmallVectorImpl<char> &Result) {
+ return getKnownFolderPath(FOLDERID_LocalAppData, Result);
}
-static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
- SmallVector<wchar_t, 128> NameUTF16;
- if (windows::UTF8ToUTF16(Var, NameUTF16))
- return false;
+bool home_directory(SmallVectorImpl<char> &result) {
+ return getKnownFolderPath(FOLDERID_Profile, result);
+}
+static bool getTempDirEnvVar(const wchar_t *Var, SmallVectorImpl<char> &Res) {
SmallVector<wchar_t, 1024> Buf;
size_t Size = 1024;
do {
Buf.reserve(Size);
- Size =
- GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
+ Size = GetEnvironmentVariableW(Var, Buf.data(), Buf.capacity());
if (Size == 0)
return false;
@@ -759,14 +786,12 @@ static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
} while (Size > Buf.capacity());
Buf.set_size(Size);
- if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
- return false;
- return true;
+ return !windows::UTF16ToUTF8(Buf.data(), Size, Res);
}
static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
- const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"};
- for (const char *Env : EnvironmentVariables) {
+ const wchar_t *EnvironmentVariables[] = {L"TMP", L"TEMP", L"USERPROFILE"};
+ for (auto *Env : EnvironmentVariables) {
if (getTempDirEnvVar(Env, Res))
return true;
}
@@ -777,13 +802,19 @@ void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
(void)ErasedOnReboot;
Result.clear();
- // Check whether the temporary directory is specified by an environment
- // variable.
- if (getTempDirEnvVar(Result))
+ // Check whether the temporary directory is specified by an environment var.
+ // This matches GetTempPath logic to some degree. GetTempPath is not used
+ // directly as it cannot handle evn var longer than 130 chars on Windows 7
+ // (fixed on Windows 8).
+ if (getTempDirEnvVar(Result)) {
+ assert(!Result.empty() && "Unexpected empty path");
+ native(Result); // Some Unix-like shells use Unix path separator in $TMP.
+ fs::make_absolute(Result); // Make it absolute if not already.
return;
+ }
// Fall back to a system default.
- const char *DefaultResult = "C:\\TEMP";
+ const char *DefaultResult = "C:\\Temp";
Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
}
} // end namespace path
diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc
index 8164956..dae35a8 100644
--- a/contrib/llvm/lib/Support/Windows/Process.inc
+++ b/contrib/llvm/lib/Support/Windows/Process.inc
@@ -417,16 +417,23 @@ const char *Process::ResetColor() {
return 0;
}
+// Include GetLastError() in a fatal error message.
+static void ReportLastErrorFatal(const char *Msg) {
+ std::string ErrMsg;
+ MakeErrMsg(&ErrMsg, Msg);
+ report_fatal_error(ErrMsg);
+}
+
unsigned Process::GetRandomNumber() {
HCRYPTPROV HCPC;
if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
- report_fatal_error("Could not acquire a cryptographic context");
+ ReportLastErrorFatal("Could not acquire a cryptographic context");
ScopedCryptContext CryptoProvider(HCPC);
unsigned Ret;
if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
reinterpret_cast<BYTE *>(&Ret)))
- report_fatal_error("Could not generate a random number");
+ ReportLastErrorFatal("Could not generate a random number");
return Ret;
}
diff --git a/contrib/llvm/lib/Support/Windows/Program.inc b/contrib/llvm/lib/Support/Windows/Program.inc
index c29d872..d4e14dd 100644
--- a/contrib/llvm/lib/Support/Windows/Program.inc
+++ b/contrib/llvm/lib/Support/Windows/Program.inc
@@ -75,8 +75,15 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name,
do {
U16Result.reserve(Len);
- Len = ::SearchPathW(Path, c_str(U16Name),
- U16Ext.empty() ? nullptr : c_str(U16Ext),
+ // Lets attach the extension manually. That is needed for files
+ // with a point in name like aaa.bbb. SearchPathW will not add extension
+ // from its argument to such files because it thinks they already had one.
+ SmallVector<wchar_t, MAX_PATH> U16NameExt;
+ if (std::error_code EC =
+ windows::UTF8ToUTF16(Twine(Name + Ext).str(), U16NameExt))
+ return EC;
+
+ Len = ::SearchPathW(Path, c_str(U16NameExt), nullptr,
U16Result.capacity(), U16Result.data(), nullptr);
} while (Len > U16Result.capacity());
@@ -132,7 +139,7 @@ static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
MakeErrMsg(ErrMsg, fname + ": Can't open file for " +
- (fd ? "input: " : "output: "));
+ (fd ? "input" : "output"));
}
return h;
@@ -251,6 +258,14 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
return false;
}
+ // can_execute may succeed by looking at Program + ".exe". CreateProcessW
+ // will implicitly add the .exe if we provide a command line without an
+ // executable path, but since we use an explicit executable, we have to add
+ // ".exe" ourselves.
+ SmallString<64> ProgramStorage;
+ if (!sys::fs::exists(Program))
+ Program = Twine(Program + ".exe").toStringRef(ProgramStorage);
+
// Windows wants a command line, not an array of args, to pass to the new
// process. We have to concatenate them all, while quoting the args that
// have embedded spaces (or are empty).
@@ -416,7 +431,7 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
if (SecondsToWait) {
if (!TerminateProcess(PI.ProcessHandle, 1)) {
if (ErrMsg)
- MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
+ MakeErrMsg(ErrMsg, "Failed to terminate timed-out program");
// -2 indicates a crash or timeout as opposed to failure to execute.
WaitResult.ReturnCode = -2;
@@ -441,7 +456,7 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
if (!rc) {
SetLastError(err);
if (ErrMsg)
- MakeErrMsg(ErrMsg, "Failed getting status for program.");
+ MakeErrMsg(ErrMsg, "Failed getting status for program");
// -2 indicates a crash or timeout as opposed to failure to execute.
WaitResult.ReturnCode = -2;
diff --git a/contrib/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm/lib/Support/Windows/Signals.inc
index 5c8c239..d109a66 100644
--- a/contrib/llvm/lib/Support/Windows/Signals.inc
+++ b/contrib/llvm/lib/Support/Windows/Signals.inc
@@ -14,7 +14,6 @@
#include <algorithm>
#include <signal.h>
#include <stdio.h>
-#include <vector>
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -136,6 +135,10 @@ typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
PDWORD, PIMAGEHLP_LINE64);
static fpSymGetLineFromAddr64 fSymGetLineFromAddr64;
+typedef BOOL(WINAPI *fpSymGetModuleInfo64)(HANDLE hProcess, DWORD64 dwAddr,
+ PIMAGEHLP_MODULE64 ModuleInfo);
+static fpSymGetModuleInfo64 fSymGetModuleInfo64;
+
typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
static fpSymFunctionTableAccess64 fSymFunctionTableAccess64;
@@ -145,6 +148,9 @@ static fpSymSetOptions fSymSetOptions;
typedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
static fpSymInitialize fSymInitialize;
+typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
+static fpEnumerateLoadedModules fEnumerateLoadedModules;
+
static bool load64BitDebugHelp(void) {
HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
if (hLib) {
@@ -156,14 +162,20 @@ static bool load64BitDebugHelp(void) {
::GetProcAddress(hLib, "SymGetSymFromAddr64");
fSymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
::GetProcAddress(hLib, "SymGetLineFromAddr64");
+ fSymGetModuleInfo64 = (fpSymGetModuleInfo64)
+ ::GetProcAddress(hLib, "SymGetModuleInfo64");
fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
::GetProcAddress(hLib, "SymFunctionTableAccess64");
fSymSetOptions = (fpSymSetOptions)::GetProcAddress(hLib, "SymSetOptions");
fSymInitialize = (fpSymInitialize)::GetProcAddress(hLib, "SymInitialize");
+ fEnumerateLoadedModules = (fpEnumerateLoadedModules)
+ ::GetProcAddress(hLib, "EnumerateLoadedModules64");
}
return fStackWalk64 && fSymInitialize && fSymSetOptions;
}
+using namespace llvm;
+
// Forward declare.
static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
@@ -172,7 +184,6 @@ static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
static void (*InterruptFunction)() = 0;
static std::vector<std::string> *FilesToRemove = NULL;
-static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
static bool RegisteredUnhandledExceptionFilter = false;
static bool CleanupExecuted = false;
static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
@@ -183,23 +194,106 @@ static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
static CRITICAL_SECTION CriticalSection;
static bool CriticalSectionInitialized = false;
-static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
- HANDLE hThread, STACKFRAME64 &StackFrame,
- CONTEXT *Context) {
- DWORD machineType;
+enum {
#if defined(_M_X64)
- machineType = IMAGE_FILE_MACHINE_AMD64;
+ NativeMachineType = IMAGE_FILE_MACHINE_AMD64
#else
- machineType = IMAGE_FILE_MACHINE_I386;
+ NativeMachineType = IMAGE_FILE_MACHINE_I386
#endif
+};
+
+static bool printStackTraceWithLLVMSymbolizer(llvm::raw_ostream &OS,
+ HANDLE hProcess, HANDLE hThread,
+ STACKFRAME64 &StackFrameOrig,
+ CONTEXT *ContextOrig) {
+ // StackWalk64 modifies the incoming stack frame and context, so copy them.
+ STACKFRAME64 StackFrame = StackFrameOrig;
+
+ // Copy the register context so that we don't modify it while we unwind. We
+ // could use InitializeContext + CopyContext, but that's only required to get
+ // at AVX registers, which typically aren't needed by StackWalk64. Reduce the
+ // flag set to indicate that there's less data.
+ CONTEXT Context = *ContextOrig;
+ Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
+
+ static void *StackTrace[256];
+ size_t Depth = 0;
+ while (fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame,
+ &Context, 0, fSymFunctionTableAccess64,
+ fSymGetModuleBase64, 0)) {
+ if (StackFrame.AddrFrame.Offset == 0)
+ break;
+ StackTrace[Depth++] = (void *)(uintptr_t)StackFrame.AddrPC.Offset;
+ if (Depth >= array_lengthof(StackTrace))
+ break;
+ }
+
+ return printSymbolizedStackTrace(&StackTrace[0], Depth, OS);
+}
+
+namespace {
+struct FindModuleData {
+ void **StackTrace;
+ int Depth;
+ const char **Modules;
+ intptr_t *Offsets;
+ StringSaver *StrPool;
+};
+}
+
+static BOOL CALLBACK findModuleCallback(WIN32_ELMCB_PCSTR ModuleName,
+ DWORD64 ModuleBase, ULONG ModuleSize,
+ void *VoidData) {
+ FindModuleData *Data = (FindModuleData*)VoidData;
+ intptr_t Beg = ModuleBase;
+ intptr_t End = Beg + ModuleSize;
+ for (int I = 0; I < Data->Depth; I++) {
+ if (Data->Modules[I])
+ continue;
+ intptr_t Addr = (intptr_t)Data->StackTrace[I];
+ if (Beg <= Addr && Addr < End) {
+ Data->Modules[I] = Data->StrPool->save(ModuleName);
+ Data->Offsets[I] = Addr - Beg;
+ }
+ }
+ return TRUE;
+}
+
+static bool findModulesAndOffsets(void **StackTrace, int Depth,
+ const char **Modules, intptr_t *Offsets,
+ const char *MainExecutableName,
+ StringSaver &StrPool) {
+ if (!fEnumerateLoadedModules)
+ return false;
+ FindModuleData Data;
+ Data.StackTrace = StackTrace;
+ Data.Depth = Depth;
+ Data.Modules = Modules;
+ Data.Offsets = Offsets;
+ Data.StrPool = &StrPool;
+ fEnumerateLoadedModules(GetCurrentProcess(), findModuleCallback, &Data);
+ return true;
+}
+static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
+ HANDLE hThread, STACKFRAME64 &StackFrame,
+ CONTEXT *Context) {
// Initialize the symbol handler.
fSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
fSymInitialize(hProcess, NULL, TRUE);
+ // Try llvm-symbolizer first. llvm-symbolizer knows how to deal with both PDBs
+ // and DWARF, so it should do a good job regardless of what debug info or
+ // linker is in use.
+ if (printStackTraceWithLLVMSymbolizer(OS, hProcess, hThread, StackFrame,
+ Context)) {
+ return;
+ }
+
while (true) {
- if (!fStackWalk64(machineType, hProcess, hThread, &StackFrame, Context, 0,
- fSymFunctionTableAccess64, fSymGetModuleBase64, 0)) {
+ if (!fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame,
+ Context, 0, fSymFunctionTableAccess64,
+ fSymGetModuleBase64, 0)) {
break;
}
@@ -311,10 +405,7 @@ static void RegisterHandler() {
// If we cannot load up the APIs (which would be unexpected as they should
// exist on every version of Windows we support), we will bail out since
// there would be nothing to report.
- if (!load64BitDebugHelp()) {
- assert(false && "These APIs should always be available");
- return;
- }
+ assert(load64BitDebugHelp() && "These APIs should always be available");
if (RegisteredUnhandledExceptionFilter) {
EnterCriticalSection(&CriticalSection);
@@ -404,7 +495,6 @@ extern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord);
#endif
void llvm::sys::PrintStackTrace(raw_ostream &OS) {
-
STACKFRAME64 StackFrame = {};
CONTEXT Context = {};
::RtlCaptureContext(&Context);
@@ -436,8 +526,6 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) {
/// to the process. The handler can have a cookie passed to it to identify
/// what instance of the handler it is.
void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
- if (CallBacksToRun == 0)
- CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
RegisterHandler();
LeaveCriticalSection(&CriticalSection);
@@ -454,17 +542,12 @@ static void Cleanup() {
CleanupExecuted = true;
// FIXME: open files cannot be deleted.
-
if (FilesToRemove != NULL)
while (!FilesToRemove->empty()) {
llvm::sys::fs::remove(FilesToRemove->back());
FilesToRemove->pop_back();
}
-
- if (CallBacksToRun)
- for (auto &I : *CallBacksToRun)
- I.first(I.second);
-
+ llvm::sys::RunSignalHandlers();
LeaveCriticalSection(&CriticalSection);
}
diff --git a/contrib/llvm/lib/Support/Windows/WindowsSupport.h b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
index 5bb0b8d..34d961b 100644
--- a/contrib/llvm/lib/Support/Windows/WindowsSupport.h
+++ b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
@@ -26,12 +26,13 @@
#undef _WIN32_WINNT
#undef _WIN32_IE
-// Require at least Windows XP(5.1) API.
-#define _WIN32_WINNT 0x0501
-#define _WIN32_IE 0x0600 // MinGW at it again.
+// Require at least Windows 7 API.
+#define _WIN32_WINNT 0x0601
+#define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed.
#define WIN32_LEAN_AND_MEAN
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h" // Get build system configuration settings
@@ -47,13 +48,16 @@ inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
if (!ErrMsg)
return true;
char *buffer = NULL;
+ DWORD LastError = GetLastError();
DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, LastError, 0, (LPSTR)&buffer, 1, NULL);
if (R)
- *ErrMsg = prefix + buffer;
+ *ErrMsg = prefix + ": " + buffer;
else
- *ErrMsg = prefix + "Unknown error";
+ *ErrMsg = prefix + ": Unknown error";
+ *ErrMsg += " (0x" + llvm::utohexstr(LastError) + ")";
LocalFree(buffer);
return R != 0;
diff --git a/contrib/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm/lib/Support/YAMLParser.cpp
index d55da5e..c4384ca 100644
--- a/contrib/llvm/lib/Support/YAMLParser.cpp
+++ b/contrib/llvm/lib/Support/YAMLParser.cpp
@@ -801,7 +801,7 @@ Token &Scanner::peekNext() {
removeStaleSimpleKeyCandidates();
SimpleKey SK;
- SK.Tok = TokenQueue.front();
+ SK.Tok = TokenQueue.begin();
if (std::find(SimpleKeys.begin(), SimpleKeys.end(), SK)
== SimpleKeys.end())
break;
@@ -962,10 +962,8 @@ void Scanner::skip(uint32_t Distance) {
bool Scanner::isBlankOrBreak(StringRef::iterator Position) {
if (Position == End)
return false;
- if ( *Position == ' ' || *Position == '\t'
- || *Position == '\r' || *Position == '\n')
- return true;
- return false;
+ return *Position == ' ' || *Position == '\t' || *Position == '\r' ||
+ *Position == '\n';
}
bool Scanner::consumeLineBreakIfPresent() {
@@ -1163,7 +1161,7 @@ bool Scanner::scanFlowCollectionStart(bool IsSequence) {
TokenQueue.push_back(T);
// [ and { may begin a simple key.
- saveSimpleKeyCandidate(TokenQueue.back(), Column - 1, false);
+ saveSimpleKeyCandidate(--TokenQueue.end(), Column - 1, false);
// And may also be followed by a simple key.
IsSimpleKeyAllowed = true;
@@ -1326,7 +1324,7 @@ bool Scanner::scanFlowScalar(bool IsDoubleQuoted) {
T.Range = StringRef(Start, Current - Start);
TokenQueue.push_back(T);
- saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+ saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
IsSimpleKeyAllowed = false;
@@ -1404,7 +1402,7 @@ bool Scanner::scanPlainScalar() {
TokenQueue.push_back(T);
// Plain scalars can be simple keys.
- saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+ saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
IsSimpleKeyAllowed = false;
@@ -1439,7 +1437,7 @@ bool Scanner::scanAliasOrAnchor(bool IsAlias) {
TokenQueue.push_back(T);
// Alias and anchors can be simple keys.
- saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+ saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
IsSimpleKeyAllowed = false;
@@ -1669,7 +1667,7 @@ bool Scanner::scanTag() {
TokenQueue.push_back(T);
// Tags can be simple keys.
- saveSimpleKeyCandidate(TokenQueue.back(), ColStart, false);
+ saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
IsSimpleKeyAllowed = false;
diff --git a/contrib/llvm/lib/Support/YAMLTraits.cpp b/contrib/llvm/lib/Support/YAMLTraits.cpp
index 6b59a16..2aa6e9b 100644
--- a/contrib/llvm/lib/Support/YAMLTraits.cpp
+++ b/contrib/llvm/lib/Support/YAMLTraits.cpp
@@ -332,17 +332,12 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
StringRef KeyStr = SN->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
- unsigned Len = StringStorage.size();
- char *Buf = StringAllocator.Allocate<char>(Len);
- memcpy(Buf, &StringStorage[0], Len);
- KeyStr = StringRef(Buf, Len);
+ KeyStr = StringStorage.str().copy(StringAllocator);
}
return llvm::make_unique<ScalarHNode>(N, KeyStr);
} else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
- StringRef Value = BSN->getValue();
- char *Buf = StringAllocator.Allocate<char>(Value.size());
- memcpy(Buf, Value.data(), Value.size());
- return llvm::make_unique<ScalarHNode>(N, StringRef(Buf, Value.size()));
+ StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
+ return llvm::make_unique<ScalarHNode>(N, ValueCopy);
} else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
auto SQHNode = llvm::make_unique<SequenceHNode>(N);
for (Node &SN : *SQ) {
@@ -365,10 +360,7 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
StringRef KeyStr = KeyScalar->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
- unsigned Len = StringStorage.size();
- char *Buf = StringAllocator.Allocate<char>(Len);
- memcpy(Buf, &StringStorage[0], Len);
- KeyStr = StringRef(Buf, Len);
+ KeyStr = StringStorage.str().copy(StringAllocator);
}
auto ValueHNode = this->createHNodes(KVN.getValue());
if (EC)
diff --git a/contrib/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm/lib/Support/raw_ostream.cpp
index 42f830b..57c7ac3 100644
--- a/contrib/llvm/lib/Support/raw_ostream.cpp
+++ b/contrib/llvm/lib/Support/raw_ostream.cpp
@@ -517,7 +517,7 @@ raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
/// closes the file when the stream is destroyed.
raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered)
: raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose),
- Error(false), UseAtomicWrites(false) {
+ Error(false) {
if (FD < 0 ) {
ShouldClose = false;
return;
@@ -568,21 +568,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
pos += Size;
do {
- ssize_t ret;
-
- // Check whether we should attempt to use atomic writes.
- if (LLVM_LIKELY(!UseAtomicWrites)) {
- ret = ::write(FD, Ptr, Size);
- } else {
- // Use ::writev() where available.
-#if defined(HAVE_WRITEV)
- const void *Addr = static_cast<const void *>(Ptr);
- struct iovec IOV = {const_cast<void *>(Addr), Size };
- ret = ::writev(FD, &IOV, 1);
-#else
- ret = ::write(FD, Ptr, Size);
-#endif
- }
+ ssize_t ret = ::write(FD, Ptr, Size);
if (ret < 0) {
// If it's a recoverable error, swallow it and retry the write.
@@ -755,72 +741,15 @@ void raw_string_ostream::write_impl(const char *Ptr, size_t Size) {
// raw_svector_ostream
//===----------------------------------------------------------------------===//
-// The raw_svector_ostream implementation uses the SmallVector itself as the
-// buffer for the raw_ostream. We guarantee that the raw_ostream buffer is
-// always pointing past the end of the vector, but within the vector
-// capacity. This allows raw_ostream to write directly into the correct place,
-// and we only need to set the vector size when the data is flushed.
-
-raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O, unsigned)
- : OS(O) {}
+uint64_t raw_svector_ostream::current_pos() const { return OS.size(); }
-raw_svector_ostream::raw_svector_ostream(SmallVectorImpl<char> &O) : OS(O) {
- init();
-}
-
-void raw_svector_ostream::init() {
- // Set up the initial external buffer. We make sure that the buffer has at
- // least 128 bytes free; raw_ostream itself only requires 64, but we want to
- // make sure that we don't grow the buffer unnecessarily on destruction (when
- // the data is flushed). See the FIXME below.
- OS.reserve(OS.size() + 128);
- SetBuffer(OS.end(), OS.capacity() - OS.size());
-}
-
-raw_svector_ostream::~raw_svector_ostream() {
- // FIXME: Prevent resizing during this flush().
- flush();
+void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
+ OS.append(Ptr, Ptr + Size);
}
void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
uint64_t Offset) {
- flush();
- memcpy(OS.begin() + Offset, Ptr, Size);
-}
-
-/// resync - This is called when the SmallVector we're appending to is changed
-/// outside of the raw_svector_ostream's control. It is only safe to do this
-/// if the raw_svector_ostream has previously been flushed.
-void raw_svector_ostream::resync() {
- assert(GetNumBytesInBuffer() == 0 && "Didn't flush before mutating vector");
-
- if (OS.capacity() - OS.size() < 64)
- OS.reserve(OS.capacity() * 2);
- SetBuffer(OS.end(), OS.capacity() - OS.size());
-}
-
-void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
- if (Ptr == OS.end()) {
- // Grow the buffer to include the scratch area without copying.
- size_t NewSize = OS.size() + Size;
- assert(NewSize <= OS.capacity() && "Invalid write_impl() call!");
- OS.set_size(NewSize);
- } else {
- assert(!GetNumBytesInBuffer());
- OS.append(Ptr, Ptr + Size);
- }
-
- OS.reserve(OS.size() + 64);
- SetBuffer(OS.end(), OS.capacity() - OS.size());
-}
-
-uint64_t raw_svector_ostream::current_pos() const {
- return OS.size();
-}
-
-StringRef raw_svector_ostream::str() {
- flush();
- return StringRef(OS.begin(), OS.size());
+ memcpy(OS.data() + Offset, Ptr, Size);
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud