aboutsummaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
authorEli Bendersky <eliben@chromium.org>2013-07-15 16:09:15 -0700
committerEli Bendersky <eliben@chromium.org>2013-07-15 16:09:15 -0700
commitc6cf05cb5108f356dde97c01ee4188b0671d4542 (patch)
tree436fdc2a55296d3c202e7ef11f31be3be53efb5f /lib/Support
parentc75199c649c739aade160289d93f257edc798cde (diff)
parent7dfcb84fc16b3bf6b2379713b53090757f0a45f9 (diff)
Merge commit '7dfcb84fc16b3bf6b2379713b53090757f0a45f9'
Conflicts: docs/LangRef.rst include/llvm/CodeGen/CallingConvLower.h include/llvm/IRReader/IRReader.h include/llvm/Target/TargetMachine.h lib/CodeGen/CallingConvLower.cpp lib/IRReader/IRReader.cpp lib/IRReader/LLVMBuild.txt lib/IRReader/Makefile lib/LLVMBuild.txt lib/Makefile lib/Support/MemoryBuffer.cpp lib/Support/Unix/PathV2.inc lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMSubtarget.cpp lib/Target/ARM/ARMTargetMachine.cpp lib/Target/Mips/CMakeLists.txt lib/Target/Mips/MipsDelaySlotFiller.cpp lib/Target/Mips/MipsISelLowering.cpp lib/Target/Mips/MipsInstrInfo.td lib/Target/Mips/MipsSubtarget.cpp lib/Target/Mips/MipsSubtarget.h lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrControl.td lib/Target/X86/X86InstrFormats.td lib/Transforms/IPO/ExtractGV.cpp lib/Transforms/InstCombine/InstCombineCompares.cpp lib/Transforms/Utils/SimplifyLibCalls.cpp test/CodeGen/X86/fast-isel-divrem.ll test/MC/ARM/data-in-code.ll tools/Makefile tools/llvm-extract/llvm-extract.cpp tools/llvm-link/CMakeLists.txt tools/opt/CMakeLists.txt tools/opt/LLVMBuild.txt tools/opt/Makefile tools/opt/opt.cpp
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp6
-rw-r--r--lib/Support/APInt.cpp8
-rw-r--r--lib/Support/CMakeLists.txt4
-rw-r--r--lib/Support/CommandLine.cpp236
-rw-r--r--lib/Support/Compression.cpp97
-rw-r--r--lib/Support/DataExtractor.cpp2
-rw-r--r--lib/Support/ErrorHandling.cpp16
-rw-r--r--lib/Support/FileOutputBuffer.cpp4
-rw-r--r--lib/Support/FoldingSet.cpp4
-rw-r--r--lib/Support/Host.cpp41
-rw-r--r--lib/Support/LockFileManager.cpp37
-rw-r--r--lib/Support/MemoryBuffer.cpp86
-rw-r--r--lib/Support/PathV2.cpp31
-rw-r--r--lib/Support/PrettyStackTrace.cpp6
-rw-r--r--lib/Support/Program.cpp11
-rw-r--r--lib/Support/SmallPtrSet.cpp24
-rw-r--r--lib/Support/Statistic.cpp18
-rw-r--r--lib/Support/Triple.cpp8
-rw-r--r--lib/Support/Unix/Memory.inc11
-rw-r--r--lib/Support/Unix/PathV2.inc26
-rw-r--r--lib/Support/Unix/Program.inc24
-rw-r--r--lib/Support/Unix/Signals.inc21
-rw-r--r--lib/Support/Unix/Watchdog.inc32
-rw-r--r--lib/Support/Watchdog.cpp23
-rw-r--r--lib/Support/Windows/PathV2.inc61
-rw-r--r--lib/Support/Windows/Program.inc71
-rw-r--r--lib/Support/Windows/Signals.inc22
-rw-r--r--lib/Support/Windows/Watchdog.inc24
-rw-r--r--lib/Support/YAMLParser.cpp2
-rw-r--r--lib/Support/raw_ostream.cpp9
30 files changed, 799 insertions, 166 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 5b68fbb270..6182e34150 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -3311,10 +3311,8 @@ namespace {
significand = significand.udiv(divisor);
- // Truncate the significand down to its active bit count, but
- // don't try to drop below 32.
- unsigned newPrecision = std::max(32U, significand.getActiveBits());
- significand = significand.trunc(newPrecision);
+ // Truncate the significand down to its active bit count.
+ significand = significand.trunc(significand.getActiveBits());
}
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 07cb057b48..e8534753b4 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -559,12 +559,12 @@ bool APInt::slt(const APInt& RHS) const {
if (lhsNeg) {
// Sign bit is set so perform two's complement to make it positive
lhs.flipAllBits();
- lhs++;
+ ++lhs;
}
if (rhsNeg) {
// Sign bit is set so perform two's complement to make it positive
rhs.flipAllBits();
- rhs++;
+ ++rhs;
}
// Now we have unsigned values to compare so do the comparison if necessary
@@ -2116,7 +2116,7 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
}
// If its negative, put it in two's complement form
if (isNeg) {
- (*this)--;
+ --(*this);
this->flipAllBits();
}
}
@@ -2197,7 +2197,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
// Flip the bits and add one to turn it into the equivalent positive
// value and put a '-' in the result.
Tmp.flipAllBits();
- Tmp++;
+ ++Tmp;
Str.push_back('-');
}
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index 5ba69fc3c8..01565c5776 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -7,6 +7,7 @@ add_llvm_library(LLVMSupport
BranchProbability.cpp
circular_raw_ostream.cpp
CommandLine.cpp
+ Compression.cpp
ConstantRange.cpp
ConvertUTF.c
ConvertUTFWrapper.cpp
@@ -83,6 +84,7 @@ add_llvm_library(LLVMSupport
Threading.cpp
TimeValue.cpp
Valgrind.cpp
+ Watchdog.cpp
Unix/Host.inc
Unix/Memory.inc
Unix/Mutex.inc
@@ -95,6 +97,7 @@ add_llvm_library(LLVMSupport
Unix/system_error.inc
Unix/ThreadLocal.inc
Unix/TimeValue.inc
+ Unix/Watchdog.inc
Windows/DynamicLibrary.inc
Windows/Host.inc
Windows/Memory.inc
@@ -108,4 +111,5 @@ add_llvm_library(LLVMSupport
Windows/system_error.inc
Windows/ThreadLocal.inc
Windows/TimeValue.inc
+ Windows/Watchdog.inc
)
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 53fcf06f82..18d3db527b 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -33,6 +33,7 @@
#include "llvm/Support/system_error.h"
#include <cerrno>
#include <cstdlib>
+#include <map>
using namespace llvm;
using namespace cl;
@@ -106,6 +107,17 @@ void Option::addArgument() {
MarkOptionsChanged();
}
+// This collects the different option categories that have been registered.
+typedef SmallPtrSet<OptionCategory*,16> OptionCatSet;
+static ManagedStatic<OptionCatSet> RegisteredOptionCategories;
+
+// Initialise the general option category.
+OptionCategory llvm::cl::GeneralCategory("General options");
+
+void OptionCategory::registerCategory()
+{
+ RegisteredOptionCategories->insert(this);
+}
//===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery.
@@ -1222,15 +1234,20 @@ sortOpts(StringMap<Option*> &OptMap,
namespace {
class HelpPrinter {
- size_t MaxArgLen;
- const Option *EmptyArg;
+protected:
const bool ShowHidden;
+ typedef SmallVector<std::pair<const char *, Option*>,128> StrOptionPairVector;
+ // Print the options. Opts is assumed to be alphabetically sorted.
+ virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ Opts[i].second->printOptionInfo(MaxArgLen);
+ }
public:
- explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {
- EmptyArg = 0;
- }
+ explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
+ virtual ~HelpPrinter() {}
+ // Invoke the printer.
void operator=(bool Value) {
if (Value == false) return;
@@ -1240,7 +1257,7 @@ public:
StringMap<Option*> OptMap;
GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
- SmallVector<std::pair<const char *, Option*>, 128> Opts;
+ StrOptionPairVector Opts;
sortOpts(OptMap, Opts, ShowHidden);
if (ProgramOverview)
@@ -1266,17 +1283,17 @@ public:
outs() << "\n\n";
// Compute the maximum argument length...
- MaxArgLen = 0;
+ size_t MaxArgLen = 0;
for (size_t i = 0, e = Opts.size(); i != e; ++i)
MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
outs() << "OPTIONS:\n";
- for (size_t i = 0, e = Opts.size(); i != e; ++i)
- Opts[i].second->printOptionInfo(MaxArgLen);
+ printOptions(Opts, MaxArgLen);
// Print any extra help the user has declared.
for (std::vector<const char *>::iterator I = MoreHelp->begin(),
- E = MoreHelp->end(); I != E; ++I)
+ E = MoreHelp->end();
+ I != E; ++I)
outs() << *I;
MoreHelp->clear();
@@ -1284,21 +1301,152 @@ public:
exit(1);
}
};
+
+class CategorizedHelpPrinter : public HelpPrinter {
+public:
+ explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}
+
+ // Helper function for printOptions().
+ // It shall return true if A's name should be lexographically
+ // ordered before B's name. It returns false otherwise.
+ static bool OptionCategoryCompare(OptionCategory *A, OptionCategory *B) {
+ int Length = strcmp(A->getName(), B->getName());
+ assert(Length != 0 && "Duplicate option categories");
+ return Length < 0;
+ }
+
+ // Make sure we inherit our base class's operator=()
+ using HelpPrinter::operator= ;
+
+protected:
+ virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
+ std::vector<OptionCategory *> SortedCategories;
+ std::map<OptionCategory *, std::vector<Option *> > CategorizedOptions;
+
+ // Collect registered option categories into vector in preperation for
+ // sorting.
+ for (OptionCatSet::const_iterator I = RegisteredOptionCategories->begin(),
+ E = RegisteredOptionCategories->end();
+ I != E; ++I)
+ SortedCategories.push_back(*I);
+
+ // Sort the different option categories alphabetically.
+ assert(SortedCategories.size() > 0 && "No option categories registered!");
+ std::sort(SortedCategories.begin(), SortedCategories.end(),
+ OptionCategoryCompare);
+
+ // Create map to empty vectors.
+ for (std::vector<OptionCategory *>::const_iterator
+ I = SortedCategories.begin(),
+ E = SortedCategories.end();
+ I != E; ++I)
+ CategorizedOptions[*I] = std::vector<Option *>();
+
+ // Walk through pre-sorted options and assign into categories.
+ // Because the options are already alphabetically sorted the
+ // options within categories will also be alphabetically sorted.
+ for (size_t I = 0, E = Opts.size(); I != E; ++I) {
+ Option *Opt = Opts[I].second;
+ assert(CategorizedOptions.count(Opt->Category) > 0 &&
+ "Option has an unregistered category");
+ CategorizedOptions[Opt->Category].push_back(Opt);
+ }
+
+ // Now do printing.
+ for (std::vector<OptionCategory *>::const_iterator
+ Category = SortedCategories.begin(),
+ E = SortedCategories.end();
+ Category != E; ++Category) {
+ // Hide empty categories for -help, but show for -help-hidden.
+ bool IsEmptyCategory = CategorizedOptions[*Category].size() == 0;
+ if (!ShowHidden && IsEmptyCategory)
+ continue;
+
+ // Print category information.
+ outs() << "\n";
+ outs() << (*Category)->getName() << ":\n";
+
+ // Check if description is set.
+ if ((*Category)->getDescription() != 0)
+ outs() << (*Category)->getDescription() << "\n\n";
+ else
+ outs() << "\n";
+
+ // When using -help-hidden explicitly state if the category has no
+ // options associated with it.
+ if (IsEmptyCategory) {
+ outs() << " This option category has no options.\n";
+ continue;
+ }
+ // Loop over the options in the category and print.
+ for (std::vector<Option *>::const_iterator
+ Opt = CategorizedOptions[*Category].begin(),
+ E = CategorizedOptions[*Category].end();
+ Opt != E; ++Opt)
+ (*Opt)->printOptionInfo(MaxArgLen);
+ }
+ }
+};
+
+// This wraps the Uncategorizing and Categorizing printers and decides
+// at run time which should be invoked.
+class HelpPrinterWrapper {
+private:
+ HelpPrinter &UncategorizedPrinter;
+ CategorizedHelpPrinter &CategorizedPrinter;
+
+public:
+ explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,
+ CategorizedHelpPrinter &CategorizedPrinter) :
+ UncategorizedPrinter(UncategorizedPrinter),
+ CategorizedPrinter(CategorizedPrinter) { }
+
+ // Invoke the printer.
+ void operator=(bool Value);
+};
+
} // End anonymous namespace
-// Define the two HelpPrinter instances that are used to print out help, or
-// help-hidden...
-//
-static HelpPrinter NormalPrinter(false);
-static HelpPrinter HiddenPrinter(true);
+// Declare the four HelpPrinter instances that are used to print out help, or
+// help-hidden as an uncategorized list or in categories.
+static HelpPrinter UncategorizedNormalPrinter(false);
+static HelpPrinter UncategorizedHiddenPrinter(true);
+static CategorizedHelpPrinter CategorizedNormalPrinter(false);
+static CategorizedHelpPrinter CategorizedHiddenPrinter(true);
+
+// Declare HelpPrinter wrappers that will decide whether or not to invoke
+// a categorizing help printer
+static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter,
+ CategorizedNormalPrinter);
+static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter,
+ CategorizedHiddenPrinter);
+
+// Define uncategorized help printers.
+// -help-list is hidden by default because if Option categories are being used
+// then -help behaves the same as -help-list.
static cl::opt<HelpPrinter, true, parser<bool> >
-HOp("help", cl::desc("Display available options (-help-hidden for more)"),
- cl::location(NormalPrinter), cl::ValueDisallowed);
+HLOp("help-list",
+ cl::desc("Display list of available options (-help-list-hidden for more)"),
+ cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed);
static cl::opt<HelpPrinter, true, parser<bool> >
+HLHOp("help-list-hidden",
+ cl::desc("Display list of all available options"),
+ cl::location(UncategorizedHiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+
+// Define uncategorized/categorized help printers. These printers change their
+// behaviour at runtime depending on whether one or more Option categories have
+// been declared.
+static cl::opt<HelpPrinterWrapper, true, parser<bool> >
+HOp("help", cl::desc("Display available options (-help-hidden for more)"),
+ cl::location(WrappedNormalPrinter), cl::ValueDisallowed);
+
+static cl::opt<HelpPrinterWrapper, true, parser<bool> >
HHOp("help-hidden", cl::desc("Display all available options"),
- cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+ cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+
+
static cl::opt<bool>
PrintOptions("print-options",
@@ -1310,6 +1458,24 @@ PrintAllOptions("print-all-options",
cl::desc("Print all option values after command line parsing"),
cl::Hidden, cl::init(false));
+void HelpPrinterWrapper::operator=(bool Value) {
+ if (Value == false)
+ return;
+
+ // Decide which printer to invoke. If more than one option category is
+ // registered then it is useful to show the categorized help instead of
+ // uncategorized help.
+ if (RegisteredOptionCategories->size() > 1) {
+ // unhide -help-list option so user can have uncategorized output if they
+ // want it.
+ HLOp.setHiddenFlag(NotHidden);
+
+ CategorizedPrinter = true; // Invoke categorized printer
+ }
+ else
+ UncategorizedPrinter = true; // Invoke uncategorized printer
+}
+
// Print the value of each option.
void cl::PrintOptionValues() {
if (!PrintOptions && !PrintAllOptions) return;
@@ -1397,14 +1563,22 @@ VersOp("version", cl::desc("Display the version of this program"),
cl::location(VersionPrinterInstance), cl::ValueDisallowed);
// Utility function for printing the help message.
-void cl::PrintHelpMessage() {
- // This looks weird, but it actually prints the help message. The
- // NormalPrinter variable is a HelpPrinter and the help gets printed when
- // its operator= is invoked. That's because the "normal" usages of the
- // help printer is to be assigned true/false depending on whether the
- // -help option was given or not. Since we're circumventing that we have
- // to make it look like -help was given, so we assign true.
- NormalPrinter = true;
+void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
+ // This looks weird, but it actually prints the help message. The Printers are
+ // types of HelpPrinter and the help gets printed when its operator= is
+ // invoked. That's because the "normal" usages of the help printer is to be
+ // assigned true/false depending on whether -help or -help-hidden was given or
+ // not. Since we're circumventing that we have to make it look like -help or
+ // -help-hidden were given, so we assign true.
+
+ if (!Hidden && !Categorized)
+ UncategorizedNormalPrinter = true;
+ else if (!Hidden && Categorized)
+ CategorizedNormalPrinter = true;
+ else if (Hidden && !Categorized)
+ UncategorizedHiddenPrinter = true;
+ else
+ CategorizedHiddenPrinter = true;
}
/// Utility function for printing version number.
@@ -1422,3 +1596,13 @@ void cl::AddExtraVersionPrinter(void (*func)()) {
ExtraVersionPrinters->push_back(func);
}
+
+void cl::getRegisteredOptions(StringMap<Option*> &Map)
+{
+ // Get all the options.
+ SmallVector<Option*, 4> PositionalOpts; //NOT USED
+ SmallVector<Option*, 4> SinkOpts; //NOT USED
+ assert(Map.size() == 0 && "StringMap must be empty");
+ GetOptionInfo(PositionalOpts, SinkOpts, Map);
+ return;
+}
diff --git a/lib/Support/Compression.cpp b/lib/Support/Compression.cpp
new file mode 100644
index 0000000000..fd8a8743ea
--- /dev/null
+++ b/lib/Support/Compression.cpp
@@ -0,0 +1,97 @@
+//===--- Compression.cpp - Compression implementation ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements compression functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Compression.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+using namespace llvm;
+
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
+static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) {
+ switch (Level) {
+ case zlib::NoCompression: return 0;
+ case zlib::BestSpeedCompression: return 1;
+ case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION;
+ case zlib::BestSizeCompression: return 9;
+ }
+ llvm_unreachable("Invalid zlib::CompressionLevel!");
+}
+
+static zlib::Status encodeZlibReturnValue(int ReturnValue) {
+ switch (ReturnValue) {
+ case Z_OK: return zlib::StatusOK;
+ case Z_MEM_ERROR: return zlib::StatusOutOfMemory;
+ case Z_BUF_ERROR: return zlib::StatusBufferTooShort;
+ case Z_STREAM_ERROR: return zlib::StatusInvalidArg;
+ case Z_DATA_ERROR: return zlib::StatusInvalidData;
+ default: llvm_unreachable("unknown zlib return status!");
+ }
+}
+
+bool zlib::isAvailable() { return true; }
+zlib::Status zlib::compress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &CompressedBuffer,
+ CompressionLevel Level) {
+ unsigned long CompressedSize = ::compressBound(InputBuffer.size());
+ OwningArrayPtr<char> TmpBuffer(new char[CompressedSize]);
+ int CLevel = encodeZlibCompressionLevel(Level);
+ Status Res = encodeZlibReturnValue(::compress2(
+ (Bytef *)TmpBuffer.get(), &CompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel));
+ if (Res == StatusOK) {
+ CompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
+ StringRef(TmpBuffer.get(), CompressedSize)));
+ // Tell MSan that memory initialized by zlib is valid.
+ __msan_unpoison(CompressedBuffer->getBufferStart(), CompressedSize);
+ }
+ return Res;
+}
+
+zlib::Status zlib::uncompress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ OwningArrayPtr<char> TmpBuffer(new char[UncompressedSize]);
+ Status Res = encodeZlibReturnValue(
+ ::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size()));
+ if (Res == StatusOK) {
+ UncompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
+ StringRef(TmpBuffer.get(), UncompressedSize)));
+ // Tell MSan that memory initialized by zlib is valid.
+ __msan_unpoison(UncompressedBuffer->getBufferStart(), UncompressedSize);
+ }
+ return Res;
+}
+
+#else
+bool zlib::isAvailable() { return false; }
+zlib::Status zlib::compress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &CompressedBuffer,
+ CompressionLevel Level) {
+ return zlib::StatusUnsupported;
+}
+zlib::Status zlib::uncompress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ return zlib::StatusUnsupported;
+}
+#endif
+
diff --git a/lib/Support/DataExtractor.cpp b/lib/Support/DataExtractor.cpp
index 3d5cce0535..a564d211b1 100644
--- a/lib/Support/DataExtractor.cpp
+++ b/lib/Support/DataExtractor.cpp
@@ -20,7 +20,7 @@ static T getU(uint32_t *offset_ptr, const DataExtractor *de,
uint32_t offset = *offset_ptr;
if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
std::memcpy(&val, &Data[offset], sizeof(val));
- if (sys::isLittleEndianHost() != isLittleEndian)
+ if (sys::IsLittleEndianHost != isLittleEndian)
val = sys::SwapByteOrder(val);
// Advance the offset
diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp
index d4382e54e0..f4b591e777 100644
--- a/lib/Support/ErrorHandling.cpp
+++ b/lib/Support/ErrorHandling.cpp
@@ -49,21 +49,21 @@ void llvm::remove_fatal_error_handler() {
ErrorHandler = 0;
}
-void llvm::report_fatal_error(const char *Reason) {
- report_fatal_error(Twine(Reason));
+void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) {
+ report_fatal_error(Twine(Reason), GenCrashDiag);
}
-void llvm::report_fatal_error(const std::string &Reason) {
- report_fatal_error(Twine(Reason));
+void llvm::report_fatal_error(const std::string &Reason, bool GenCrashDiag) {
+ report_fatal_error(Twine(Reason), GenCrashDiag);
}
-void llvm::report_fatal_error(StringRef Reason) {
- report_fatal_error(Twine(Reason));
+void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) {
+ report_fatal_error(Twine(Reason), GenCrashDiag);
}
-void llvm::report_fatal_error(const Twine &Reason) {
+void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
if (ErrorHandler) {
- ErrorHandler(ErrorHandlerUserData, Reason.str());
+ ErrorHandler(ErrorHandlerUserData, Reason.str(), GenCrashDiag);
} else {
// Blast the result out to stderr. We don't try hard to make sure this
// succeeds (e.g. handling EINTR) and we can't use errs() here because
diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp
index cd430f218b..1ee69b6023 100644
--- a/lib/Support/FileOutputBuffer.cpp
+++ b/lib/Support/FileOutputBuffer.cpp
@@ -70,8 +70,8 @@ error_code FileOutputBuffer::create(StringRef FilePath,
if (EC)
return EC;
- OwningPtr<mapped_file_region> MappedFile(
- new mapped_file_region(FD, mapped_file_region::readwrite, Size, 0, EC));
+ OwningPtr<mapped_file_region> MappedFile(new mapped_file_region(
+ FD, true, mapped_file_region::readwrite, Size, 0, EC));
if (EC)
return EC;
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
index 36e33b5aaf..145f12dc1e 100644
--- a/lib/Support/FoldingSet.cpp
+++ b/lib/Support/FoldingSet.cpp
@@ -101,7 +101,7 @@ void FoldingSetNodeID::AddString(StringRef String) {
// Otherwise do it the hard way.
// To be compatible with above bulk transfer, we need to take endianness
// into account.
- if (sys::isBigEndianHost()) {
+ if (sys::IsBigEndianHost) {
for (Pos += 4; Pos <= Size; Pos += 4) {
unsigned V = ((unsigned char)String[Pos - 4] << 24) |
((unsigned char)String[Pos - 3] << 16) |
@@ -110,7 +110,7 @@ void FoldingSetNodeID::AddString(StringRef String) {
Bits.push_back(V);
}
} else {
- assert(sys::isLittleEndianHost() && "Unexpected host endianness");
+ assert(sys::IsLittleEndianHost && "Unexpected host endianness");
for (Pos += 4; Pos <= Size; Pos += 4) {
unsigned V = ((unsigned char)String[Pos - 1] << 24) |
((unsigned char)String[Pos - 2] << 16) |
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp
index b9bbcb9322..a7c7a95800 100644
--- a/lib/Support/Host.cpp
+++ b/lib/Support/Host.cpp
@@ -112,6 +112,21 @@ static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX,
#endif
}
+static bool OSHasAVXSupport() {
+#if defined(__GNUC__)
+ // Check xgetbv; this uses a .byte sequence instead of the instruction
+ // directly because older assemblers do not include support for xgetbv and
+ // there is no easy way to conditionally compile based on the assembler used.
+ int rEAX, rEDX;
+ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (rEAX), "=d" (rEDX) : "c" (0));
+#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
+ unsigned long long rEAX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
+#else
+ int rEAX = 0; // Ensures we return false
+#endif
+ return (rEAX & 6) == 6;
+}
+
static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
unsigned &Model) {
Family = (EAX >> 8) & 0xf; // Bits 8 - 11
@@ -134,6 +149,11 @@ std::string sys::getHostCPUName() {
DetectX86FamilyModel(EAX, Family, Model);
bool HasSSE3 = (ECX & 0x1);
+ // 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.
+ const unsigned AVXBits = (1 << 27) | (1 << 28);
+ bool HasAVX = ((ECX & AVXBits) == AVXBits) && OSHasAVXSupport();
GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
bool Em64T = (EDX >> 29) & 0x1;
@@ -243,11 +263,15 @@ std::string sys::getHostCPUName() {
case 42: // Intel Core i7 processor. All processors are manufactured
// using the 32 nm process.
case 45:
- return "corei7-avx";
+ // Not all Sandy Bridge processors support AVX (such as the Pentium
+ // versions instead of the i7 versions).
+ return HasAVX ? "corei7-avx" : "corei7";
// Ivy Bridge:
case 58:
- return "core-avx-i";
+ // Not all Ivy Bridge processors support AVX (such as the Pentium
+ // versions instead of the i7 versions).
+ return HasAVX ? "core-avx-i" : "corei7";
case 28: // Most 45 nm Intel Atom processors
case 38: // 45 nm Atom Lincroft
@@ -331,10 +355,15 @@ std::string sys::getHostCPUName() {
case 20:
return "btver1";
case 21:
- if (Model <= 15)
- return "bdver1";
- else if (Model <= 31)
+ if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+ return "btver1";
+ if (Model > 15 && Model <= 31)
return "bdver2";
+ return "bdver1";
+ case 22:
+ if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+ return "btver1";
+ return "btver2";
default:
return "generic";
}
@@ -584,7 +613,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features){
#endif
std::string sys::getProcessTriple() {
- Triple PT(LLVM_HOSTTRIPLE);
+ Triple PT(LLVM_HOST_TRIPLE);
if (sizeof(void *) == 8 && PT.isArch32Bit())
PT = PT.get64BitArchVariant();
diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp
index f49d025c11..819d25546b 100644
--- a/lib/Support/LockFileManager.cpp
+++ b/lib/Support/LockFileManager.cpp
@@ -174,8 +174,8 @@ void LockFileManager::waitForUnlock() {
Interval.tv_sec = 0;
Interval.tv_nsec = 1000000;
#endif
- // Don't wait more than an hour for the file to appear.
- const unsigned MaxSeconds = 3600;
+ // Don't wait more than five minutes for the file to appear.
+ unsigned MaxSeconds = 300;
bool LockFileGone = false;
do {
// Sleep for the designated interval, to allow the owning process time to
@@ -187,21 +187,48 @@ void LockFileManager::waitForUnlock() {
#else
nanosleep(&Interval, NULL);
#endif
- // If the lock file no longer exists, wait for the actual file.
bool Exists = false;
+ bool LockFi