Index: lib/profile/InstrProfData.inc
===================================================================
--- lib/profile/InstrProfData.inc
+++ lib/profile/InstrProfData.inc
@@ -97,6 +97,7 @@
 #endif
 INSTR_PROF_RAW_HEADER(uint64_t, Magic, __llvm_profile_get_magic())
 INSTR_PROF_RAW_HEADER(uint64_t, Version, __llvm_profile_get_version())
+INSTR_PROF_RAW_HEADER(uint64_t, CounterSectionAlignment, CounterSectionAlignment)
 INSTR_PROF_RAW_HEADER(uint64_t, DataSize, DataSize)
 INSTR_PROF_RAW_HEADER(uint64_t, CountersSize, CountersSize)
 INSTR_PROF_RAW_HEADER(uint64_t, NamesSize,  NamesSize)
@@ -711,7 +712,7 @@
         (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129
 
 /* Raw profile format version (start from 1). */
-#define INSTR_PROF_RAW_VERSION 3
+#define INSTR_PROF_RAW_VERSION 4
 /* Indexed profile format version (start from 1). */
 #define INSTR_PROF_INDEX_VERSION 4
 /* Coverage mapping format vresion (start from 0). */
Index: lib/profile/InstrProfiling.h
===================================================================
--- lib/profile/InstrProfiling.h
+++ lib/profile/InstrProfiling.h
@@ -122,6 +122,8 @@
  * Sets the filename to be used for subsequent calls to
  * \a __llvm_profile_write_file().
  *
+ * This is incompatible with LLVM_PROFILE_ENABLE_MMAP.
+ *
  * \c Name is not copied, so it must remain valid.  Passing NULL resets the
  * filename logic to the default behaviour.
  */
@@ -134,13 +136,24 @@
  * Unless overridden, sets the filename to be used for subsequent calls to
  * \a __llvm_profile_write_file().
  *
+ * This is incompatible with LLVM_PROFILE_ENABLE_MMAP.
+ *
  * \c Name is not copied, so it must remain valid.  Passing NULL resets the
  * filename logic to the default behaviour (unless the \c LLVM_PROFILE_FILE
  * was set in which case it has no effect).
  */
 void __llvm_profile_override_default_filename(const char *Name);
 
-/*! \brief Register to write instrumentation data to file at exit. */
+/*! \brief Register a memory map to emit counter data continuously.
+ *
+ * Returns a non-zero value to indicate failure.
+ */
+int __llvm_profile_register_mmap(void);
+
+/*! \brief Register to write instrumentation data to file at exit.
+ *
+ * Returns a non-zero value to indicate failure.
+ */
 int __llvm_profile_register_write_file_atexit(void);
 
 /*! \brief Initialize file handling. */
Index: lib/profile/InstrProfilingBuffer.c
===================================================================
--- lib/profile/InstrProfilingBuffer.c
+++ lib/profile/InstrProfilingBuffer.c
@@ -46,7 +46,7 @@
 }
 
 COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {
-  return lprofWriteData(lprofBufferWriter, Buffer, 0, 0);
+  return lprofWriteData(lprofBufferWriter, Buffer, 1, 0, 0);
 }
 
 COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
@@ -54,6 +54,6 @@
     const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,
     const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) {
   return lprofWriteDataImpl(lprofBufferWriter, Buffer, DataBegin, DataEnd,
-                            CountersBegin, CountersEnd, 0, 0, NamesBegin,
+                            CountersBegin, CountersEnd, 1, 0, 0, NamesBegin,
                             NamesEnd);
 }
Index: lib/profile/InstrProfilingFile.c
===================================================================
--- lib/profile/InstrProfilingFile.c
+++ lib/profile/InstrProfilingFile.c
@@ -10,10 +10,24 @@
 #include "InstrProfiling.h"
 #include "InstrProfilingInternal.h"
 #include "InstrProfilingUtil.h"
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#if defined(_WIN32)
+#include "WindowsMMap.h"
+#else
+#include <sys/mman.h>
+#include <sys/file.h>
+#endif
+
+#ifdef COMPILER_RT_HAS_UNAME
+#include <sys/utsname.h>
+#endif
 
 #define UNCONST(ptr) ((void *)(uintptr_t)(ptr))
 
@@ -37,38 +51,111 @@
   return lprofCreateBufferIO(fileWriter, File, BufferSz);
 }
 
-static int writeFile(FILE *File) {
+static int writeFile(FILE *File, uint64_t CounterSectionAlignment,
+                     bool EmitValueProf) {
   const char *BufferSzStr = 0;
   uint64_t ValueDataSize = 0;
-  struct ValueProfData **ValueDataArray =
-      __llvm_profile_gather_value_data(&ValueDataSize);
+  struct ValueProfData **ValueDataArray = NULL;
+
   FreeHook = &free;
   CallocHook = &calloc;
-  BufferSzStr = getenv("LLVM_VP_BUFFER_SIZE");
-  if (BufferSzStr && BufferSzStr[0])
-    VPBufferSize = atoi(BufferSzStr);
-  return lprofWriteData(fileWriter, File, ValueDataArray, ValueDataSize);
+
+  if (EmitValueProf) {
+    BufferSzStr = getenv("LLVM_VP_BUFFER_SIZE");
+    if (BufferSzStr && BufferSzStr[0])
+      VPBufferSize = atoi(BufferSzStr);
+
+    ValueDataArray = __llvm_profile_gather_value_data(&ValueDataSize);
+  }
+
+  return lprofWriteData(fileWriter, File, CounterSectionAlignment,
+                        ValueDataArray, ValueDataSize);
 }
 
-static int writeFileWithName(const char *OutputName) {
+/*
+ * Write out a profile with the specificed counter section alignment.
+ *
+ * If \p EmitValueProf is true, emit any available value profile data.
+ *
+ * If \p CloseFile is true, the profile is closed after it's created.
+ *
+ * If \p CloseFile is false, the profile is kept locked and open. Its file
+ * stream is passed back to the caller via \p Stream.
+ *
+ * If \p HeaderOffset is non-null, it's set to the file offset to the header.
+ */
+static int writeFileWithName(const char *OutputName,
+                             uint64_t CounterSectionAlignment,
+                             bool EmitValueProf, bool CloseFile,
+                             FILE **Stream, off_t *HeaderOffset) {
   int RetVal;
   FILE *OutputFile;
+  int OFD;
   if (!OutputName || !OutputName[0])
     return -1;
 
   /* Append to the file to support profiling multiple shared objects. */
-  OutputFile = fopen(OutputName, "ab");
+  OutputFile = fopen(OutputName, "a+");
   if (!OutputFile)
     return -1;
 
-  RetVal = writeFile(OutputFile);
+  OFD = fileno(OutputFile);
+
+  if (!CloseFile) {
+    if (flock(OFD, LOCK_EX)) {
+      fclose(OutputFile);
+      return -1;
+    }
+  }
+
+  if (HeaderOffset) {
+    *HeaderOffset = ftello(OutputFile);
+    if (*HeaderOffset < 0 || *HeaderOffset % CounterSectionAlignment) {
+      flock(OFD, LOCK_UN);
+      fclose(OutputFile);
+      return -1;
+    }
+  }
+
+  RetVal = writeFile(OutputFile, CounterSectionAlignment, EmitValueProf);
+  if (RetVal) {
+    fclose(OutputFile);
+    return RetVal;
+  }
+
+  if (CloseFile)
+    fclose(OutputFile);
+  else if (!CloseFile && Stream)
+    *Stream = OutputFile;
 
-  fclose(OutputFile);
   return RetVal;
 }
 
 COMPILER_RT_WEAK int __llvm_profile_OwnsFilename = 0;
 COMPILER_RT_WEAK const char *__llvm_profile_CurrentFilename = NULL;
+COMPILER_RT_WEAK FILE *__llvm_profile_TruncateLockFile = NULL;
+COMPILER_RT_WEAK const char *__llvm_profile_TruncateLockFilename = NULL;
+
+static const char *getTruncateLockFilename(const char *Filename) {
+  unsigned TLFLen = strlen(Filename) + strlen(".lock") + 1;
+  char *TLF = malloc(TLFLen);
+  snprintf(TLF, TLFLen, "%s.lock", Filename);
+  return TLF;
+}
+
+static void removeTruncateLock(void) {
+  if (__llvm_profile_TruncateLockFile) {
+    flock(fileno(__llvm_profile_TruncateLockFile), LOCK_UN);
+    fclose(__llvm_profile_TruncateLockFile);
+    __llvm_profile_TruncateLockFile = NULL;
+  }
+
+  if (__llvm_profile_TruncateLockFilename) {
+    unlink(__llvm_profile_TruncateLockFilename);
+    free((void *)__llvm_profile_TruncateLockFilename);
+    __llvm_profile_TruncateLockFilename = NULL;
+  }
+}
 
 static void truncateCurrentFile(void) {
   const char *Filename;
@@ -86,6 +173,32 @@
     free(Copy);
   }
 
+  /* Open the truncate lock file. */
+  const char *TLFilename = getTruncateLockFilename(Filename);
+  FILE *TLFile = fopen(TLFilename, "w+");
+  if (!TLFile) {
+    free((void *)TLFilename);
+    return;
+  }
+
+  /* If this is a new file, we may need to drop a stale truncate lock. */
+  if (__llvm_profile_TruncateLockFilename &&
+      strcmp(__llvm_profile_TruncateLockFilename, TLFilename))
+    removeTruncateLock();
+
+  /* Try to acquire the truncate lock. */
+  int TLFD = fileno(TLFile);
+  if (flock(TLFD, LOCK_EX | LOCK_NB)) {
+    /* A previous initialization already truncated the profile. */
+    free((void *)TLFilename);
+    fclose(TLFile);
+    return;
+  }
+
+  __llvm_profile_TruncateLockFile = TLFile;
+  __llvm_profile_TruncateLockFilename = TLFilename;
+  atexit(removeTruncateLock);
+
   /* Truncate the file.  Later we'll reopen and append. */
   File = fopen(Filename, "w");
   if (!File)
@@ -96,7 +209,7 @@
 static void setFilename(const char *Filename, int OwnsFilename) {
   /* Check if this is a new filename and therefore needs truncation. */
   int NewFile = !__llvm_profile_CurrentFilename ||
-      (Filename && strcmp(Filename, __llvm_profile_CurrentFilename));
+                (Filename && strcmp(Filename, __llvm_profile_CurrentFilename));
   if (__llvm_profile_OwnsFilename)
     free(UNCONST(__llvm_profile_CurrentFilename));
 
@@ -196,7 +309,7 @@
   if (__llvm_profile_CurrentFilename)
     return;
 
-  /* Detect the filename and truncate. */
+  /* Detect the filename and truncate the profile if we haven't already. */
   setFilenameAutomatically();
 }
 
@@ -214,8 +327,8 @@
   setFilenamePossiblyWithPid(Filename);
 }
 
-COMPILER_RT_VISIBILITY
-int __llvm_profile_write_file(void) {
+static int writeFileImpl(uint64_t CounterSectionAlignment, bool EmitValueProf,
+                         bool CloseFile, FILE **Stream, off_t *HeaderOffset) {
   int rc;
 
   GetEnvHook = &getenv;
@@ -235,13 +348,20 @@
   }
 
   /* Write the file. */
-  rc = writeFileWithName(__llvm_profile_CurrentFilename);
+  rc =
+      writeFileWithName(__llvm_profile_CurrentFilename, CounterSectionAlignment,
+                        EmitValueProf, CloseFile, Stream, HeaderOffset);
   if (rc)
     PROF_ERR("LLVM Profile: Failed to write file \"%s\": %s\n",
-            __llvm_profile_CurrentFilename, strerror(errno));
+             __llvm_profile_CurrentFilename, strerror(errno));
   return rc;
 }
 
+COMPILER_RT_VISIBILITY
+int __llvm_profile_write_file(void) {
+  return writeFileImpl(1, true, true, NULL, NULL);
+}
+
 static void writeFileWithoutReturn(void) { __llvm_profile_write_file(); }
 
 COMPILER_RT_VISIBILITY
@@ -254,3 +374,85 @@
   HasBeenRegistered = 1;
   return atexit(writeFileWithoutReturn);
 }
+
+static size_t getPageSize() {
+#if _WIN32
+  SYSTEM_INFO SI;
+  GetSystemInfo(&SI);
+  return (size_t)SI.dwPageSize;
+#else
+  return (size_t)sysconf(_SC_PAGESIZE);
+#endif
+}
+
+static bool hasValueProfData(const __llvm_profile_data *DataBegin,
+                             const __llvm_profile_data *DataEnd) {
+  const __llvm_profile_data *I;
+  unsigned J;
+  for (I = DataBegin; I < DataEnd; ++I)
+    for (J = 0; J <= IPVK_Last; ++J)
+      if (I->NumValueSites[J])
+        return true;
+  return false;
+}
+
+COMPILER_RT_VISIBILITY
+int __llvm_profile_register_mmap() {
+  int FD;
+  FILE *Stream;
+  size_t PageSize;
+
+  off_t HeaderOffset = 0;
+
+  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
+  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
+  size_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
+  size_t DataSizeInBytes = DataSize * sizeof(__llvm_profile_data);
+
+  const uint64_t *CountersBegin = __llvm_profile_begin_counters();
+  const uint64_t *CountersEnd = __llvm_profile_end_counters();
+  size_t CountersSize = CountersEnd - CountersBegin;
+  off_t CountersOffset;
+  size_t CountersSizeInBytes;
+  void *CountersMMap;
+
+  CountersSizeInBytes = CountersSize * sizeof(uint64_t);
+
+  /* No data, no profile. */
+  if (!DataSize)
+    return 0;
+
+  /* We don't support mmap'ing out value profile data. */
+  if (hasValueProfData(DataBegin, DataEnd))
+    return -1;
+
+  PageSize = getPageSize();
+
+  if (!lprofCheckIfAligned((size_t)CountersBegin, PageSize))
+    return -1;
+
+  /* Write out an empty profile with a page-aligned counters section.
+   * Expect a locked file stream in \p Stream. */
+  if (writeFileImpl(PageSize, false, false, &Stream, &HeaderOffset))
+    return -1;
+
+  CountersOffset = lprofAlignTo(
+      HeaderOffset + sizeof(__llvm_profile_header) + DataSizeInBytes, PageSize);
+
+  FD = fileno(Stream);
+
+  CountersMMap =
+      mmap((void *)CountersBegin, lprofAlignTo(CountersSizeInBytes, PageSize),
+           PROT_READ | PROT_WRITE, MAP_FILE | MAP_FIXED | MAP_SHARED, FD,
+           CountersOffset);
+
+  if (CountersMMap == MAP_FAILED) {
+    /* The mmap failed. Truncate the profile back to its original length. */
+    ftruncate(FD, HeaderOffset);
+  }
+
+  flock(FD, LOCK_UN);
+  fclose(Stream);
+
+  return (CountersMMap == MAP_FAILED) ? -1 : 0;
+}
Index: lib/profile/InstrProfilingInternal.h
===================================================================
--- lib/profile/InstrProfilingInternal.h
+++ lib/profile/InstrProfilingInternal.h
@@ -99,6 +99,7 @@
                            void **WriterCtx);
 
 int lprofWriteData(WriterCallback Writer, void *WriterCtx,
+                   uint64_t CounterSectionAlignment,
                    struct ValueProfData **ValueDataArray,
                    const uint64_t ValueDataSize);
 int lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx,
@@ -106,6 +107,7 @@
                        const __llvm_profile_data *DataEnd,
                        const uint64_t *CountersBegin,
                        const uint64_t *CountersEnd,
+                       uint64_t CounterSectionAlignment,
                        struct ValueProfData **ValueDataBeginArray,
                        const uint64_t ValueDataSize, const char *NamesBegin,
                        const char *NamesEnd);
Index: lib/profile/InstrProfilingRuntime.cc
===================================================================
--- lib/profile/InstrProfilingRuntime.cc
+++ lib/profile/InstrProfilingRuntime.cc
@@ -11,16 +11,30 @@
 
 #include "InstrProfiling.h"
 
+#include <stdlib.h>
+#include <string.h>
+
 COMPILER_RT_VISIBILITY int __llvm_profile_runtime;
 }
 
 namespace {
 
+bool isMMapEnabled() {
+  const char *EnableMMap = getenv("LLVM_PROFILE_ENABLE_MMAP");
+  return EnableMMap && strlen(EnableMMap) && EnableMMap[0] != '0' &&
+         EnableMMap[0] != 'f';
+}
+
 class RegisterRuntime {
 public:
   RegisterRuntime() {
-    __llvm_profile_register_write_file_atexit();
     __llvm_profile_initialize_file();
+
+    if (isMMapEnabled())
+      if (!__llvm_profile_register_mmap())
+        return;
+
+    __llvm_profile_register_write_file_atexit();
   }
 };
 
Index: lib/profile/InstrProfilingUtil.h
===================================================================
--- lib/profile/InstrProfilingUtil.h
+++ lib/profile/InstrProfilingUtil.h
@@ -11,6 +11,7 @@
 #define PROFILE_INSTRPROFILINGUTIL_H
 
 #include <stddef.h>
+#include <stdbool.h>
 
 /*! \brief Create a directory tree. */
 void __llvm_profile_recursive_mkdir(char *Pathname);
@@ -24,4 +25,12 @@
 
 unsigned lprofBoolCmpXchg(void **Ptr, void *OldV, void *NewV);
 
+/* Round \p Offset to the nearest multiple of \p Alignment. \p Alignment must
+ * be a power of 2. */
+size_t lprofAlignTo(size_t Offset, size_t Alignment);
+
+/* Check if \p Offset is a multiple of \p Alignment. \p Alignment must be a
+ * power of 2. */
+bool lprofCheckIfAligned(size_t Offset, size_t Alignment);
+
 #endif  /* PROFILE_INSTRPROFILINGUTIL_H */
Index: lib/profile/InstrProfilingUtil.c
===================================================================
--- lib/profile/InstrProfilingUtil.c
+++ lib/profile/InstrProfilingUtil.c
@@ -63,4 +63,13 @@
 }
 #endif
 
+bool lprofCheckIfAligned(size_t Offset, size_t Alignment) {
+  return !(Offset & (Alignment - 1));
+}
+
+size_t lprofAlignTo(size_t Offset, size_t Alignment) {
+  if (lprofCheckIfAligned(Offset, Alignment))
+    return Offset;
 
+  return (Offset & ~(Alignment - 1)) + Alignment;
+}
Index: lib/profile/InstrProfilingWriter.c
===================================================================
--- lib/profile/InstrProfilingWriter.c
+++ lib/profile/InstrProfilingWriter.c
@@ -93,6 +93,7 @@
 
 COMPILER_RT_VISIBILITY int lprofWriteData(WriterCallback Writer,
                                           void *WriterCtx,
+                                          uint64_t CounterSectionAlignment,
                                           ValueProfData **ValueDataArray,
                                           const uint64_t ValueDataSize) {
   /* Match logic in __llvm_profile_write_buffer(). */
@@ -103,8 +104,9 @@
   const char *NamesBegin = __llvm_profile_begin_names();
   const char *NamesEnd = __llvm_profile_end_names();
   return lprofWriteDataImpl(Writer, WriterCtx, DataBegin, DataEnd,
-                            CountersBegin, CountersEnd, ValueDataArray,
-                            ValueDataSize, NamesBegin, NamesEnd);
+                            CountersBegin, CountersEnd, CounterSectionAlignment,
+                            ValueDataArray, ValueDataSize, NamesBegin,
+                            NamesEnd);
 }
 
 #define VP_BUFFER_SIZE 8 * 1024
@@ -136,11 +138,31 @@
   return 0;
 }
 
+static int writePadding(WriterCallback Writer, void *WriterCtx,
+                 uint64_t NumPaddingBytes) {
+  uint64_t BytesRemaining = NumPaddingBytes;
+
+  /* Enough zeroes for padding. */
+  const char Zeroes[256] = {0};
+
+  while (BytesRemaining > 0) {
+    uint64_t BytesToWrite =
+        (BytesRemaining < sizeof(Zeroes)) ? BytesRemaining : sizeof(Zeroes);
+    ProfDataIOVec PadIO[] = {{Zeroes, sizeof(uint8_t), BytesToWrite}};
+    if (Writer(PadIO, sizeof(PadIO) / sizeof(ProfDataIOVec), &WriterCtx))
+      return -1;
+    BytesRemaining -= BytesToWrite;
+  }
+
+  return 0;
+}
+
 COMPILER_RT_VISIBILITY int
 lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx,
                    const __llvm_profile_data *DataBegin,
                    const __llvm_profile_data *DataEnd,
                    const uint64_t *CountersBegin, const uint64_t *CountersEnd,
+                   uint64_t CounterSectionAlignment,
                    ValueProfData **ValueDataBegin, const uint64_t ValueDataSize,
                    const char *NamesBegin, const char *NamesEnd) {
 
@@ -150,9 +172,6 @@
   const uint64_t NamesSize = NamesEnd - NamesBegin;
   const uint64_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);
 
-  /* Enough zeroes for padding. */
-  const char Zeroes[sizeof(uint64_t)] = {0};
-
   /* Create the header. */
   __llvm_profile_header Header;
 
@@ -163,14 +182,34 @@
 #define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init;
 #include "InstrProfData.inc"
 
+  uint64_t DataEndOffset =
+      sizeof(__llvm_profile_header) + (DataSize * sizeof(__llvm_profile_data));
+  uint64_t PaddingBeforeCounters =
+      lprofAlignTo(DataEndOffset, CounterSectionAlignment) - DataEndOffset;
+  uint64_t CountersSizeInBytes = CountersSize * sizeof(uint64_t);
+  uint64_t PaddingAfterCounters =
+      lprofAlignTo(CountersSizeInBytes, CounterSectionAlignment) -
+      CountersSizeInBytes;
+  uint64_t PaddingAfterNames =
+      lprofAlignTo(NamesSize + Padding, CounterSectionAlignment) -
+      (NamesSize + Padding);
+
   /* Write the data. */
-  ProfDataIOVec IOVec[] = {{&Header, sizeof(__llvm_profile_header), 1},
-                           {DataBegin, sizeof(__llvm_profile_data), DataSize},
-                           {CountersBegin, sizeof(uint64_t), CountersSize},
-                           {NamesBegin, sizeof(uint8_t), NamesSize},
-                           {Zeroes, sizeof(uint8_t), Padding}};
-  if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx))
+  ProfDataIOVec IO1[] = {{&Header, sizeof(__llvm_profile_header), 1},
+                         {DataBegin, sizeof(__llvm_profile_data), DataSize}};
+  if (Writer(IO1, sizeof(IO1) / sizeof(ProfDataIOVec), &WriterCtx))
+    return -1;
+  if (writePadding(Writer, WriterCtx, PaddingBeforeCounters))
+    return -1;
+  ProfDataIOVec IO2[] = {{CountersBegin, sizeof(uint64_t), CountersSize}};
+  if (Writer(IO2, sizeof(IO2) / sizeof(ProfDataIOVec), &WriterCtx))
+    return -1;
+  if (writePadding(Writer, WriterCtx, PaddingAfterCounters))
+    return -1;
+  ProfDataIOVec IO3[] = {{NamesBegin, sizeof(uint8_t), NamesSize}};
+  if (Writer(IO3, sizeof(IO3) / sizeof(ProfDataIOVec), &WriterCtx))
+    return -1;
+  if (writePadding(Writer, WriterCtx, Padding + PaddingAfterNames))
     return -1;
-
   return writeValueProfData(Writer, WriterCtx, ValueDataBegin, DataSize);
 }
Index: test/lit.common.cfg
===================================================================
--- test/lit.common.cfg
+++ test/lit.common.cfg
@@ -17,6 +17,8 @@
 if execute_external:
   config.available_features.add('shell')
 
+config.available_features.add('OS=%s' % platform.system())
+
 # Setup clang binary.
 compiler_path = getattr(config, 'clang', None)
 if (not compiler_path) or (not os.path.exists(compiler_path)):
Index: test/profile/CMakeLists.txt
===================================================================
--- test/profile/CMakeLists.txt
+++ test/profile/CMakeLists.txt
@@ -12,21 +12,26 @@
   darwin_filter_host_archs(PROFILE_SUPPORTED_ARCH PROFILE_TEST_ARCH)
 endif()
 
+set(PROFILE_SUPPORTED_MMAP_OPTIONS "0;1")
+
 foreach(arch ${PROFILE_TEST_ARCH})
-  set(PROFILE_TEST_TARGET_ARCH ${arch})
-  if(${arch} MATCHES "arm|aarch64")
-    # This is only true if we're cross-compiling.
-    set(PROFILE_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
-  else()
-    get_target_flags_for_arch(${arch} PROFILE_TEST_TARGET_CFLAGS)
-    string(REPLACE ";" " " PROFILE_TEST_TARGET_CFLAGS "${PROFILE_TEST_TARGET_CFLAGS}")
-  endif()
-  set(CONFIG_NAME Profile-${arch})
-  configure_lit_site_cfg(
-    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
-    ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
-   )
-  list(APPEND PROFILE_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+  foreach(do_mmap ${PROFILE_SUPPORTED_MMAP_OPTIONS})
+    set(PROFILE_TEST_TARGET_ARCH ${arch})
+    set(PROFILE_DO_MMAP ${do_mmap})
+    if(${arch} MATCHES "arm|aarch64")
+      # This is only true if we're cross-compiling.
+      set(PROFILE_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
+    else()
+      get_target_flags_for_arch(${arch} PROFILE_TEST_TARGET_CFLAGS)
+      string(REPLACE ";" " " PROFILE_TEST_TARGET_CFLAGS "${PROFILE_TEST_TARGET_CFLAGS}")
+    endif()
+    set(CONFIG_NAME Profile-${arch}-mmap-${do_mmap})
+    configure_lit_site_cfg(
+      ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+      ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
+     )
+    list(APPEND PROFILE_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+  endforeach()
 endforeach()
 
 add_lit_testsuite(check-profile "Running the profile tests"
Index: test/profile/Linux/coverage_ctors.cpp
===================================================================
--- test/profile/Linux/coverage_ctors.cpp
+++ test/profile/Linux/coverage_ctors.cpp
@@ -1,5 +1,5 @@
 // RUN: %clangxx_profgen -std=c++11 -fuse-ld=gold -fcoverage-mapping -o %t %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: llvm-cov show %t -instr-profile %t.profdata -filename-equivalence 2>&1 | FileCheck %s
 
Index: test/profile/Linux/coverage_dtor.cpp
===================================================================
--- test/profile/Linux/coverage_dtor.cpp
+++ test/profile/Linux/coverage_dtor.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -x c++ -fno-exceptions  -std=c++11 -fuse-ld=gold -fcoverage-mapping -o %t %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: llvm-cov show %t -instr-profile %t.profdata -filename-equivalence 2>&1 | FileCheck %s
 
Index: test/profile/Linux/coverage_shared.test
===================================================================
--- test/profile/Linux/coverage_shared.test
+++ test/profile/Linux/coverage_shared.test
@@ -5,8 +5,8 @@
 
 RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t-static %t.d/a.shared.o %S/../Inputs/instrprof-dynamic-b.cpp %S/../Inputs/instrprof-dynamic-main.cpp
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw
Index: test/profile/Linux/coverage_test.cpp
===================================================================
--- test/profile/Linux/coverage_test.cpp
+++ test/profile/Linux/coverage_test.cpp
@@ -1,10 +1,10 @@
 // RUN: %clang_profgen -fuse-ld=gold -O2 -fdata-sections -ffunction-sections -fcoverage-mapping -Wl,--gc-sections -o %t %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: llvm-cov show %t -instr-profile %t.profdata -filename-equivalence 2>&1 | FileCheck %s
 // BFD linker older than 2.26 has a bug that per-func profile data will be wrongly garbage collected when GC is turned on. We only do end-to-end test here without GC:
 // RUN: %clang_profgen -O2  -fcoverage-mapping  -o %t.2 %s
-// RUN: env LLVM_PROFILE_FILE=%t.2.profraw %run %t.2
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.2.profraw %run %t.2
 // RUN: llvm-profdata merge -o %t.2.profdata %t.2.profraw
 // RUN: llvm-cov show %t.2 -instr-profile %t.2.profdata -filename-equivalence 2>&1 | FileCheck %s
 // Check covmap is not garbage collected when GC is turned on with BFD linker. Due to the bug mentioned above, we can only
@@ -13,7 +13,7 @@
 // RUN: llvm-objdump -h %t.3 | FileCheck --check-prefix COVMAP %s
 // Check PIE option
 // RUN: %clang_profgen -fuse-ld=gold -O2 -fdata-sections -ffunction-sections -fPIE -pie -fcoverage-mapping -Wl,--gc-sections -o %t.pie %s
-// RUN: env LLVM_PROFILE_FILE=%t.pie.profraw %run %t.pie
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.pie.profraw %run %t.pie
 // RUN: llvm-profdata merge -o %t.pie.profdata %t.pie.profraw
 // RUN: llvm-cov show %t.pie -instr-profile %t.pie.profdata -filename-equivalence 2>&1 | FileCheck %s
 
Index: test/profile/Linux/instrprof-basic.c
===================================================================
--- test/profile/Linux/instrprof-basic.c
+++ test/profile/Linux/instrprof-basic.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t -O3 %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
 
Index: test/profile/Linux/instrprof-dlopen.test
===================================================================
--- test/profile/Linux/instrprof-dlopen.test
+++ test/profile/Linux/instrprof-dlopen.test
@@ -7,9 +7,9 @@
 RUN: %clang -c -o %t.d/main.o %S/../Inputs/instrprof-dlopen-main.c
 RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections  -o %t-static %S/../Inputs/instrprof-dlopen-func.c %S/../Inputs/instrprof-dlopen-func2.c %t.d/main.o
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-local.profraw %run %t-local
-RUN: env LLVM_PROFILE_FILE=%t-global.profraw %run %t-global
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-local.profraw %run %t-local
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-global.profraw %run %t-global
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-local.profdata %t-local.profraw
Index: test/profile/Linux/instrprof-dynamic-one-shared.test
===================================================================
--- test/profile/Linux/instrprof-dynamic-one-shared.test
+++ test/profile/Linux/instrprof-dynamic-one-shared.test
@@ -4,8 +4,8 @@
 
 RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t-static %S/../Inputs/instrprof-dynamic-a.cpp %S/../Inputs/instrprof-dynamic-b.cpp %S/../Inputs/instrprof-dynamic-main.cpp
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw
Index: test/profile/Linux/instrprof-dynamic-two-shared.test
===================================================================
--- test/profile/Linux/instrprof-dynamic-two-shared.test
+++ test/profile/Linux/instrprof-dynamic-two-shared.test
@@ -5,8 +5,8 @@
 
 RUN: %clang_profgen -o %t-static %S/../Inputs/instrprof-dynamic-a.cpp %S/../Inputs/instrprof-dynamic-b.cpp %S/../Inputs/instrprof-dynamic-main.cpp
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw
Index: test/profile/gcc-flag-compatibility.test
===================================================================
--- test/profile/gcc-flag-compatibility.test
+++ test/profile/gcc-flag-compatibility.test
@@ -3,11 +3,11 @@
 RUN: %clang_profgen_gcc=%t.d/d1/d2 -o %t.d/code %S/Inputs/gcc-flag-compatibility.c
 
 # Test that the instrumented code writes to %t.d/d1/d2/default.profraw
-RUN: %run %t.d/code
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap %run %t.d/code
 RUN: llvm-profdata merge -o %t.profdata %t.d/d1/d2/default.profraw
 
 # Test that we can override the directory and file name with LLVM_PROFILE_FILE.
-RUN: env LLVM_PROFILE_FILE=%t.d/x1/prof.raw %run %t.d/code
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.d/x1/prof.raw %run %t.d/code
 RUN: llvm-profdata merge -o %t.profdata %t.d/x1/prof.raw
 
 # Test that we can specify a directory with -fprofile-use.
Index: test/profile/instrprof-basic.c
===================================================================
--- test/profile/instrprof-basic.c
+++ test/profile/instrprof-basic.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -o %t -O3 %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
 
Index: test/profile/instrprof-bufferio.c
===================================================================
--- test/profile/instrprof-bufferio.c
+++ test/profile/instrprof-bufferio.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -O3 -o %t %s
-// RUN: %run %t %t.out.1 %t.out.2 %t.out.3 %t.out.4
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap %run %t %t.out.1 %t.out.2 %t.out.3 %t.out.4
 // RUN: cat %t.out.1 | FileCheck %s
 // RUN: diff %t.out.1 %t.out.2
 // RUN: diff %t.out.2 %t.out.3
Index: test/profile/instrprof-dlopen.test
===================================================================
--- test/profile/instrprof-dlopen.test
+++ test/profile/instrprof-dlopen.test
@@ -1,15 +1,15 @@
 RUN: mkdir -p %t.d
-RUN: %clang_profgen -o %t.d/func.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func.c
-RUN: %clang_profgen -o %t.d/func2.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func2.c
-RUN: %clang -o %t-local -fPIC -DDLOPEN_FUNC_DIR=\"%t.d\" -DDLOPEN_FLAGS="RTLD_LAZY | RTLD_LOCAL" %S/Inputs/instrprof-dlopen-main.c
-RUN: %clang -o %t-global -fPIC -DDLOPEN_FUNC_DIR=\"%t.d\" -DDLOPEN_FLAGS="RTLD_LAZY | RTLD_GLOBAL" %S/Inputs/instrprof-dlopen-main.c
+RUN: %clang_profgen -g -o %t.d/func.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func.c
+RUN: %clang_profgen -g -o %t.d/func2.shared -fPIC -shared %S/Inputs/instrprof-dlopen-func2.c
+RUN: %clang -g -o %t-local -fPIC -DDLOPEN_FUNC_DIR=\"%t.d\" -DDLOPEN_FLAGS="RTLD_LAZY | RTLD_LOCAL" %S/Inputs/instrprof-dlopen-main.c
+RUN: %clang -g -o %t-global -fPIC -DDLOPEN_FUNC_DIR=\"%t.d\" -DDLOPEN_FLAGS="RTLD_LAZY | RTLD_GLOBAL" %S/Inputs/instrprof-dlopen-main.c
 
-RUN: %clang -c -o %t.d/main.o %S/Inputs/instrprof-dlopen-main.c
-RUN: %clang_profgen -o %t-static %S/Inputs/instrprof-dlopen-func.c %S/Inputs/instrprof-dlopen-func2.c %t.d/main.o
+RUN: %clang -g -c -o %t.d/main.o %S/Inputs/instrprof-dlopen-main.c
+RUN: %clang_profgen -g -o %t-static %S/Inputs/instrprof-dlopen-func.c %S/Inputs/instrprof-dlopen-func2.c %t.d/main.o
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-local.profraw %run %t-local
-RUN: env LLVM_PROFILE_FILE=%t-global.profraw %run %t-global
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-local.profraw %run %t-local
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-global.profraw %run %t-global
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-local.profdata %t-local.profraw
Index: test/profile/instrprof-dynamic-one-shared.test
===================================================================
--- test/profile/instrprof-dynamic-one-shared.test
+++ test/profile/instrprof-dynamic-one-shared.test
@@ -4,8 +4,8 @@
 
 RUN: %clang_profgen -o %t-static %S/Inputs/instrprof-dynamic-a.cpp %S/Inputs/instrprof-dynamic-b.cpp %S/Inputs/instrprof-dynamic-main.cpp
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw
Index: test/profile/instrprof-dynamic-two-shared.test
===================================================================
--- test/profile/instrprof-dynamic-two-shared.test
+++ test/profile/instrprof-dynamic-two-shared.test
@@ -5,8 +5,8 @@
 
 RUN: %clang_profgen -o %t-static %S/Inputs/instrprof-dynamic-a.cpp %S/Inputs/instrprof-dynamic-b.cpp %S/Inputs/instrprof-dynamic-main.cpp
 
-RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
-RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-static.profraw %run %t-static
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared
 
 RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw
 RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw
Index: test/profile/instrprof-error.c
===================================================================
--- test/profile/instrprof-error.c
+++ test/profile/instrprof-error.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -o %t -O3 %s
-// RUN: env LLVM_PROFILE_FILE=%t/ LLVM_PROFILE_VERBOSE_ERRORS=1 %run %t 1 2>&1 | FileCheck %s
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t/ LLVM_PROFILE_VERBOSE_ERRORS=1 %run %t 1 2>&1 | FileCheck %s
 
 int main(int argc, const char *argv[]) {
   if (argc < 2)
Index: test/profile/instrprof-hostname.c
===================================================================
--- test/profile/instrprof-hostname.c
+++ test/profile/instrprof-hostname.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -o %t -O3 %s
-// RUN: env LLVM_PROFILE_FILE=%h.%t-%h.profraw_%h %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%h.%t-%h.profraw_%h %run %t
 // RUN: llvm-profdata merge -o %t.profdata `uname -n`.%t-`uname -n`.profraw_`uname -n`
 // RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
 // REQUIRES: shell
Index: test/profile/instrprof-merge-match.test
===================================================================
--- test/profile/instrprof-merge-match.test
+++ test/profile/instrprof-merge-match.test
@@ -1,5 +1,5 @@
 // RUN: mkdir -p %t.d
 // RUN: %clang_profgen  -o %t.d/libt.so -fPIC -shared %S/Inputs/instrprof-merge-match-lib.c
 // RUN: %clang_profgen  -o %t -L %t.d -rpath %t.d  %S/Inputs/instrprof-merge-match.c -lt
-// RUN: %run %t
+// RUN: LLVM_PROFILE_ENABLE_MMAP=%do_mmap %run %t
 
Index: test/profile/instrprof-merge.c
===================================================================
--- test/profile/instrprof-merge.c
+++ test/profile/instrprof-merge.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -O2 -o %t %s
-// RUN: %run %t %t.profraw 1 1
+// RUN: LLVM_PROFILE_ENABLE_MMAP=%do_mmap %run %t %t.profraw 1 1
 // RUN: llvm-profdata show --all-functions --counts %t.profraw  | FileCheck %s
 
 #include <stdint.h>
Index: test/profile/instrprof-mmap-darwin.c
===================================================================
--- /dev/null
+++ test/profile/instrprof-mmap-darwin.c
@@ -0,0 +1,29 @@
+// Darwin-specific test for mmap'd counter sections.
+//
+// REQUIRES: OS=Darwin
+// RUN: %clang_profgen -g -o %t %s
+// RUN: %run %t %t.profraw.mmap %t.profraw.atexit
+// RUN: llvm-profdata show --function=foo %t.profraw.mmap | FileCheck %s
+// RUN: llvm-profdata show --function=foo %t.profraw.atexit | FileCheck %s
+
+extern void __llvm_profile_set_filename(const char *Name);
+extern int __llvm_profile_register_mmap(void);
+
+// CHECK: foo
+void foo() {}
+
+int main(int argc, char **argv) {
+  if (argc != 3)
+    return -1;
+
+  __llvm_profile_set_filename(argv[1]);
+
+  if (__llvm_profile_register_mmap())
+    return -1;
+
+  __llvm_profile_set_filename(argv[2]);
+
+  foo();
+
+  return 0;
+}
Index: test/profile/instrprof-reset-counters.c
===================================================================
--- test/profile/instrprof-reset-counters.c
+++ test/profile/instrprof-reset-counters.c
@@ -1,5 +1,5 @@
 // RUN: %clang_profgen -o %t -O3 %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
 
Index: test/profile/instrprof-shared.test
===================================================================
--- test/profile/instrprof-shared.test
+++ test/profile/instrprof-shared.test
@@ -30,15 +30,15 @@
 RUN: %clang -o %t-no-instr2-no-instr1 -L%t.d -rpath %t.d -lt-no-instr1  %t.d/instrprof-shared-main-no-instr2.o
 RUN: %clang -o %t-no-instr2-no-instr2 -L%t.d -rpath %t.d -lt-no-instr2  %t.d/instrprof-shared-main-no-instr2.o
 
-RUN: env LLVM_PROFILE_FILE=%t-instr-instr.profraw %run %t-instr-instr
-RUN: env LLVM_PROFILE_FILE=%t-instr-no-instr1.profraw %run %t-instr-no-instr1
-RUN: env LLVM_PROFILE_FILE=%t-instr-no-instr2.profraw %run %t-instr-no-instr2
-RUN: env LLVM_PROFILE_FILE=%t-no-instr1-instr.profraw %run %t-no-instr1-instr
-RUN: env LLVM_PROFILE_FILE=%t-no-instr2-instr.profraw %run %t-no-instr2-instr
-RUN: env LLVM_PROFILE_FILE=%t-no-instr1-no-instr1.profraw %run %t-no-instr1-no-instr1
-RUN: env LLVM_PROFILE_FILE=%t-no-instr1-no-instr2.profraw %run %t-no-instr1-no-instr2
-RUN: env LLVM_PROFILE_FILE=%t-no-instr2-no-instr1.profraw %run %t-no-instr2-no-instr1
-RUN: env LLVM_PROFILE_FILE=%t-no-instr2-no-instr2.profraw %run %t-no-instr2-no-instr2
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-instr-instr.profraw %run %t-instr-instr
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-instr-no-instr1.profraw %run %t-instr-no-instr1
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-instr-no-instr2.profraw %run %t-instr-no-instr2
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-no-instr1-instr.profraw %run %t-no-instr1-instr
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-no-instr2-instr.profraw %run %t-no-instr2-instr
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-no-instr1-no-instr1.profraw %run %t-no-instr1-no-instr1
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-no-instr1-no-instr2.profraw %run %t-no-instr1-no-instr2
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-no-instr2-no-instr1.profraw %run %t-no-instr2-no-instr1
+RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t-no-instr2-no-instr2.profraw %run %t-no-instr2-no-instr2
 
 RUN: llvm-profdata merge -o %t-instr-instr.profdata %t-instr-instr.profraw
 RUN: llvm-profdata merge -o %t-instr-no-instr1.profdata %t-instr-no-instr1.profraw
Index: test/profile/instrprof-visibility.cpp
===================================================================
--- test/profile/instrprof-visibility.cpp
+++ test/profile/instrprof-visibility.cpp
@@ -1,5 +1,5 @@
 // RUN: %clangxx_profgen -fcoverage-mapping %S/Inputs/instrprof-visibility-helper.cpp -o %t %s
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: env LLVM_PROFILE_ENABLE_MMAP=%do_mmap LLVM_PROFILE_FILE=%t.profraw %run %t
 // RUN: llvm-profdata merge %t.profraw -o %t.profdata
 // RUN: llvm-profdata show --all-functions %t.profraw | FileCheck %s --check-prefix=PROFILE
 // RUN: llvm-cov show %t -instr-profile=%t.profdata | FileCheck %s --check-prefix=COV
Index: test/profile/instrprof-without-libc.c
===================================================================
--- test/profile/instrprof-without-libc.c
+++ test/profile/instrprof-without-libc.c
@@ -1,7 +1,7 @@
 // RUN: %clang_profgen -DCHECK_SYMBOLS -O3 -o %t.symbols %s
 // RUN: llvm-nm %t.symbols | FileCheck %s --check-prefix=CHECK-SYMBOLS
 // RUN: %clang_profgen -O3 -o %t %s
-// RUN: %run %t %t.profraw
+// RUN: LLVM_PROFILE_ENABLE_MMAP=%do_mmap %run %t %t.profraw
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
 
Index: test/profile/lit.cfg
===================================================================
--- test/profile/lit.cfg
+++ test/profile/lit.cfg
@@ -12,7 +12,7 @@
   return attr_value
 
 # Setup config name.
-config.name = 'Profile-' + config.target_arch
+config.name = '-'.join(('Profile', config.target_arch, 'mmap', config.do_mmap))
 
 # Setup source root.
 config.test_source_root = os.path.dirname(__file__)
@@ -61,6 +61,7 @@
 config.substitutions.append( ("%clangxx_profuse=", build_invocation(clang_cxxflags) + " -fprofile-instr-use=") )
 config.substitutions.append( ("%clang_profgen_gcc=", build_invocation(clang_cflags) + " -fprofile-generate=") )
 config.substitutions.append( ("%clang_profuse_gcc=", build_invocation(clang_cflags) + " -fprofile-use=") )
+config.substitutions.append( ("%do_mmap", config.do_mmap) )
 
 if config.host_os not in ['Darwin', 'FreeBSD', 'Linux']:
   config.unsupported = True
Index: test/profile/lit.site.cfg.in
===================================================================
--- test/profile/lit.site.cfg.in
+++ test/profile/lit.site.cfg.in
@@ -4,6 +4,7 @@
 config.profile_lit_binary_dir = "@PROFILE_LIT_BINARY_DIR@"
 config.target_cflags = "@PROFILE_TEST_TARGET_CFLAGS@"
 config.target_arch = "@PROFILE_TEST_TARGET_ARCH@"
+config.do_mmap = "@PROFILE_DO_MMAP@"
 
 # Load common config for all compiler-rt lit tests.
 lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")