Bug 1542746 - remove code for frontend-based PGO instrumentation; r=dmajor
authorNathan Froyd <froydnj@mozilla.com>
Fri, 24 May 2019 20:00:38 +0000
changeset 475465 085342ba416f464742b068edd32f20fae8e18e87
parent 475464 bd7bac95cd92ff936212b0243c993f920720771e
child 475466 f41fab78af2f06d2ad86d49e7308ced2a39e1891
push id36062
push useraciure@mozilla.com
push dateSat, 25 May 2019 09:39:13 +0000
treeherdermozilla-central@af54b2de7028 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmajor
bugs1542746
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1542746 - remove code for frontend-based PGO instrumentation; r=dmajor We're moving to IR-level PGO instrumentation for clang-cl. We've also moved to using static linker ordering files, which was the primary application of the previous style of PGO instrumentation. We therefore we no longer need this code. Differential Revision: https://phabricator.services.mozilla.com/D31134
build/pgo/profileserver.py
config/config.mk
config/rules.mk
mozglue/build/cygprofile.cpp
mozglue/build/moz.build
python/mozbuild/mozbuild/backend/common.py
python/mozbuild/mozbuild/backend/recursivemake.py
python/mozbuild/mozbuild/backend/tup.py
python/mozbuild/mozbuild/frontend/context.py
python/mozbuild/mozbuild/frontend/data.py
python/mozbuild/mozbuild/frontend/emitter.py
--- a/build/pgo/profileserver.py
+++ b/build/pgo/profileserver.py
@@ -91,19 +91,16 @@ if __name__ == '__main__':
                 if e not in env:
                     continue
 
                 vcdir = os.path.abspath(os.path.join(env[e], '../../VC/bin'))
                 if os.path.exists(vcdir):
                     env['PATH'] = '%s;%s' % (vcdir, env['PATH'])
                     break
 
-        # Add MOZ_OBJDIR to the env so that cygprofile.cpp can use it.
-        env["MOZ_OBJDIR"] = build.topobjdir
-
         # Write to an output file if we're running in automation
         process_args = {}
         if 'UPLOAD_PATH' in env:
             process_args['logfile'] = os.path.join(env['UPLOAD_PATH'], 'profile-run-1.log')
 
         # Run Firefox a first time to initialize its profile
         runner = FirefoxRunner(profile=profile,
                                binary=binary,
--- a/config/config.mk
+++ b/config/config.mk
@@ -128,17 +128,17 @@ endif
 # No sense in profiling unit tests
 ifdef CPP_UNIT_TESTS
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 endif
 
 # Enable profile-based feedback
 ifneq (1,$(NO_PROFILE_GUIDED_OPTIMIZE))
 ifdef MOZ_PROFILE_GENERATE
-PGO_CFLAGS += $(if $(filter $(notdir $<),$(notdir $(NO_PROFILE_GUIDED_OPTIMIZE))),,$(PROFILE_GEN_CFLAGS) $(COMPUTED_PROFILE_GEN_DYN_CFLAGS))
+PGO_CFLAGS += $(if $(filter $(notdir $<),$(notdir $(NO_PROFILE_GUIDED_OPTIMIZE))),,$(PROFILE_GEN_CFLAGS))
 PGO_LDFLAGS += $(PROFILE_GEN_LDFLAGS)
 ifeq (WINNT,$(OS_ARCH))
 AR_FLAGS += -LTCG
 endif
 endif # MOZ_PROFILE_GENERATE
 
 ifdef MOZ_PROFILE_USE
 PGO_CFLAGS += $(if $(filter $(notdir $<),$(notdir $(NO_PROFILE_GUIDED_OPTIMIZE))),,$(PROFILE_USE_CFLAGS))
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -187,20 +187,16 @@ ifdef MOZ_PROFILE_GENERATE
 SIMPLE_PROGRAMS :=
 endif
 
 ifdef COMPILE_ENVIRONMENT
 ifndef TARGETS
 TARGETS			= $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(HOST_SHARED_LIBRARY)
 endif
 
-ifdef MOZ_PROFILE_GENERATE
-CPPSRCS := $(CPPSRCS) $(PGO_GEN_ONLY_CPPSRCS)
-endif
-
 COBJS = $(notdir $(CSRCS:.c=.$(OBJ_SUFFIX)))
 SOBJS = $(notdir $(SSRCS:.S=.$(OBJ_SUFFIX)))
 # CPPSRCS can have different extensions (eg: .cpp, .cc)
 CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS))))
 CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX)))
 CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
 # ASFILES can have different extensions (.s, .asm)
 ASOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(ASFILES))))
deleted file mode 100644
--- a/mozglue/build/cygprofile.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Copied from Chromium's /src/tools/cygprofile_win/cygprofile.cc.
-
-#include <stdio.h>
-#include <atomic>
-#include <string>
-#include <unordered_set>
-
-#include <windows.h>  // Needs to be included before the others.
-
-#include <dbghelp.h>
-#include <process.h>
-
-#include "mozilla/Sprintf.h"
-#include "mozilla/Types.h"
-
-namespace {
-
-// The main purpose of the order file is to optimize startup time,
-// so capturing the first N function calls is enough.
-static constexpr int kSamplesCapacity = 25 * 1024 * 1024;
-
-void* samples[kSamplesCapacity];
-std::atomic_int num_samples;
-std::atomic_int done;
-
-// Symbolize the samples and write them to disk.
-void dump(void*) {
-  HMODULE dbghelp = LoadLibraryA("dbghelp.dll");
-  auto sym_from_addr = reinterpret_cast<decltype(::SymFromAddr)*>(
-      ::GetProcAddress(dbghelp, "SymFromAddr"));
-  auto sym_initialize = reinterpret_cast<decltype(::SymInitialize)*>(
-      ::GetProcAddress(dbghelp, "SymInitialize"));
-  auto sym_set_options = reinterpret_cast<decltype(::SymSetOptions)*>(
-      ::GetProcAddress(dbghelp, "SymSetOptions"));
-
-  // Path to the dump file. %s will be substituted by objdir path.
-  static const char kDumpFile[] = "%s/cygprofile.txt";
-
-  char filename[MAX_PATH];
-  const char* objdir = ::getenv("MOZ_OBJDIR");
-
-  if (!objdir) {
-    fprintf(stderr, "ERROR: cannot determine objdir\n");
-    return;
-  }
-
-  SprintfLiteral(filename, kDumpFile, objdir);
-
-  FILE* f = fopen(filename, "w");
-  if (!f) {
-    fprintf(stderr, "ERROR: Cannot open %s\n", filename);
-    return;
-  }
-
-  sym_initialize(::GetCurrentProcess(), NULL, TRUE);
-  sym_set_options(SYMOPT_DEFERRED_LOADS | SYMOPT_PUBLICS_ONLY);
-  char sym_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
-
-  std::unordered_set<void*> seen;
-  std::unordered_set<std::string> seen_names;
-
-  for (void* sample : samples) {
-    // Only print the first call of a function.
-    if (seen.count(sample)) continue;
-    seen.insert(sample);
-
-    SYMBOL_INFO* symbol = reinterpret_cast<SYMBOL_INFO*>(sym_buf);
-    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
-    symbol->MaxNameLen = MAX_SYM_NAME;
-    DWORD64 offset = 0;
-
-    if (sym_from_addr(::GetCurrentProcess(), reinterpret_cast<DWORD64>(sample),
-                      &offset, symbol)) {
-      const char* name = symbol->Name;
-      if (name[0] == '_') name++;
-      if (seen_names.count(name)) continue;
-      seen_names.insert(name);
-
-      fprintf(f, "%s\n", name);
-    }
-  }
-
-  fclose(f);
-}
-
-}  // namespace
-
-extern "C" {
-
-MOZ_EXPORT void __cyg_profile_func_enter(void* this_fn,
-                                         void* call_site_unused) {
-  if (done) return;
-
-  // Get our index for the samples array atomically.
-  int n = num_samples++;
-
-  if (n < kSamplesCapacity) {
-    samples[n] = this_fn;
-
-    if (n + 1 == kSamplesCapacity) {
-      // This is the final sample; start dumping the samples to a file (on a
-      // separate thread so as not to disturb the main program).
-      done = 1;
-      _beginthread(dump, 0, nullptr);
-    }
-  }
-}
-
-MOZ_EXPORT void __cyg_profile_func_exit(void* this_fn, void* call_site) {}
-
-}  // extern "C"
--- a/mozglue/build/moz.build
+++ b/mozglue/build/moz.build
@@ -33,20 +33,16 @@ if CONFIG['MOZ_UBSAN']:
 if CONFIG['OS_TARGET'] == 'WINNT':
     DEFFILE = '!mozglue.def'
     # We'll break the DLL blocklist if we immediately load user32.dll
     DELAYLOAD_DLLS += [
         'user32.dll',
     ]
     RCINCLUDE = 'mozglue.rc'
 
-    if CONFIG['MOZ_PGO'] and CONFIG['CC_TYPE'] == 'clang-cl':
-        SOURCES += ['cygprofile.cpp']
-        SOURCES['cygprofile.cpp'].pgo_generate_only = True
-
 if CONFIG['MOZ_WIDGET_TOOLKIT']:
 
     if CONFIG['MOZ_MEMORY'] and FORCE_SHARED_LIB:
         pass
         # TODO: SHARED_LIBRARY_LIBS go here
     else:
         # Temporary, until bug 662814 lands
         NoVisibilityFlags()
--- a/python/mozbuild/mozbuild/backend/common.py
+++ b/python/mozbuild/mozbuild/backend/common.py
@@ -227,30 +227,23 @@ class CommonBackend(BuildBackend):
     def _expand_libs(self, input_bin):
         os_libs = []
         shared_libs = []
         static_libs = []
         objs = []
         no_pgo_objs = []
 
         seen_objs = set()
-        seen_pgo_gen_only_objs = set()
         seen_libs = set()
 
         def add_objs(lib):
-            seen_pgo_gen_only_objs.update(lib.pgo_gen_only_objs)
-
             for o in lib.objs:
                 if o in seen_objs:
                     continue
 
-                # The front end should keep pgo generate-only objects and
-                # normal objects separate.
-                assert o not in seen_pgo_gen_only_objs
-
                 seen_objs.add(o)
                 objs.append(o)
                 # This is slightly odd, but for consistency with the
                 # recursivemake backend we don't replace OBJ_SUFFIX if any
                 # object in a library has `no_pgo` set.
                 if lib.no_pgo_objs or lib.no_pgo:
                     no_pgo_objs.append(o)
 
@@ -289,18 +282,17 @@ class CommonBackend(BuildBackend):
                     seen_libs.add(lib)
                     shared_libs.append(lib)
 
         for lib in input_bin.linked_system_libs:
             if lib not in seen_libs:
                 seen_libs.add(lib)
                 os_libs.append(lib)
 
-        return (objs, sorted(seen_pgo_gen_only_objs), no_pgo_objs, \
-                shared_libs, os_libs, static_libs)
+        return (objs, no_pgo_objs, shared_libs, os_libs, static_libs)
 
     def _make_list_file(self, kind, objdir, objs, name):
         if not objs:
             return None
         if kind == 'target':
             list_style = self.environment.substs.get('EXPAND_LIBS_LIST_STYLE')
         else:
             # The host compiler is not necessarily the same kind as the target
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -474,20 +474,16 @@ class RecursiveMakeBackend(CommonBackend
                 variables.append('GARBAGE')
                 base = backend_file.objdir
             else:
                 base = backend_file.srcdir
             for f in sorted(obj.files):
                 f = mozpath.relpath(f, base)
                 for var in variables:
                     backend_file.write('%s += %s\n' % (var, f))
-        elif isinstance(obj, PgoGenerateOnlySources):
-            assert obj.canonical_suffix == '.cpp'
-            for f in sorted(obj.files):
-                backend_file.write('PGO_GEN_ONLY_CPPSRCS += %s\n' % f)
         elif isinstance(obj, (HostSources, HostGeneratedSources)):
             suffix_map = {
                 '.c': 'HOST_CSRCS',
                 '.mm': 'HOST_CMMSRCS',
                 '.cpp': 'HOST_CPPSRCS',
             }
             variables = [suffix_map[obj.canonical_suffix]]
             if isinstance(obj, GeneratedSources):
@@ -1365,17 +1361,17 @@ class RecursiveMakeBackend(CommonBackend
             return os.path.normpath(mozpath.join(mozpath.relpath(lib.objdir, obj.objdir),
                                                  name))
 
         topobjdir = mozpath.normsep(obj.topobjdir)
         # This will create the node even if there aren't any linked libraries.
         build_target = self._build_target_for_obj(obj)
         self._compile_graph[build_target]
 
-        objs, pgo_gen_objs, no_pgo_objs, shared_libs, os_libs, static_libs = self._expand_libs(obj)
+        objs, no_pgo_objs, shared_libs, os_libs, static_libs = self._expand_libs(obj)
 
         obj_target = obj.name
         if isinstance(obj, Program):
             obj_target = self._pretty_path(obj.output_path, backend_file)
 
         profile_gen_objs = []
 
         if obj.KIND == 'target':
@@ -1387,18 +1383,16 @@ class RecursiveMakeBackend(CommonBackend
             if doing_pgo and obj_suffix_change_needed:
                 # We use a different OBJ_SUFFIX for the profile generate phase on
                 # systems where the pgo generate phase requires instrumentation
                 # that can only be removed by recompiling objects. These get
                 # picked up via OBJS_VAR_SUFFIX in config.mk.
                 if not is_unit_test and not isinstance(obj, SimpleProgram):
                     profile_gen_objs = [o if o in no_pgo_objs else '%s.%s' %
                                         (mozpath.splitext(o)[0], 'i_o') for o in objs]
-                    profile_gen_objs += ['%s.%s' % (mozpath.splitext(o)[0], 'i_o')
-                                         for o in pgo_gen_objs]
 
         def write_obj_deps(target, objs_ref, pgo_objs_ref):
             if pgo_objs_ref:
                 backend_file.write('ifdef MOZ_PROFILE_GENERATE\n')
                 backend_file.write('%s: %s\n' % (target, pgo_objs_ref))
                 backend_file.write('else\n')
                 backend_file.write('%s: %s\n' % (target, objs_ref))
                 backend_file.write('endif\n')
--- a/python/mozbuild/mozbuild/backend/tup.py
+++ b/python/mozbuild/mozbuild/backend/tup.py
@@ -405,17 +405,17 @@ class TupBackend(CommonBackend):
 
         mkshlib += (
             backend_file.environment.substs['DSO_PIC_CFLAGS'] +
             [backend_file.environment.substs['DSO_LDOPTS']] +
             ['-Wl,-h,%s' % shlib.soname] +
             ['-o', shlib.lib_name]
         )
 
-        objs, _, _, shared_libs, os_libs, static_libs = self._expand_libs(shlib)
+        objs, _, shared_libs, os_libs, static_libs = self._expand_libs(shlib)
         static_libs = self._lib_paths(backend_file.objdir, static_libs)
         shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
 
         list_file_name = '%s.list' % shlib.name.replace('.', '_')
         list_file = self._make_list_file(shlib.KIND, backend_file.objdir, objs, list_file_name)
 
         rust_linked = [l for l in backend_file.shared_lib.linked_libraries
                        if isinstance(l, RustLibrary)]
@@ -459,17 +459,17 @@ class TupBackend(CommonBackend):
                                   output_group=output_group)
 
     def _gen_programs(self, backend_file):
         for p in backend_file.programs:
             self._gen_program(backend_file, p)
 
     def _gen_program(self, backend_file, prog):
         cc_or_cxx = 'CXX' if prog.cxx_link else 'CC'
-        objs, _, _, shared_libs, os_libs, static_libs = self._expand_libs(prog)
+        objs, _, shared_libs, os_libs, static_libs = self._expand_libs(prog)
 
         static_libs = self._lib_paths(backend_file.objdir, static_libs)
         shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
 
         # Linking some programs will access libraries installed to dist/bin,
         # so depend on the installed libraries here. This can be made more
         # accurate once we start building libraries in their final locations.
         inputs = objs + static_libs + shared_libs + [self._shlibs]
@@ -514,17 +514,17 @@ class TupBackend(CommonBackend):
 
 
     def _gen_host_programs(self, backend_file):
         for p in backend_file.host_programs:
             self._gen_host_program(backend_file, p)
 
 
     def _gen_host_program(self, backend_file, prog):
-        _, _, _, _, extra_libs, _ = self._expand_libs(prog)
+        _, _, _, extra_libs, _ = self._expand_libs(prog)
         objs = prog.objs
 
         if isinstance(prog, HostSimpleProgram):
             outputs = [prog.name]
         else:
             outputs = [mozpath.relpath(prog.output_path.full_path,
                                        backend_file.objdir)]
         host_libs = self._lib_paths(backend_file.objdir,
@@ -560,17 +560,17 @@ class TupBackend(CommonBackend):
 
 
     def _gen_static_library(self, backend_file):
         ar = [
             backend_file.environment.substs['AR'],
             backend_file.environment.substs['AR_FLAGS'].replace('$@', '%o')
         ]
 
-        objs, _, _, shared_libs, _, static_libs = self._expand_libs(backend_file.static_lib)
+        objs, _, shared_libs, _, static_libs = self._expand_libs(backend_file.static_lib)
         static_libs = self._lib_paths(backend_file.objdir, static_libs)
         shared_libs = self._lib_paths(backend_file.objdir, shared_libs)
 
         inputs = objs + static_libs
 
         cmd = (
             ar +
             inputs
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -441,17 +441,16 @@ class CompileFlags(BaseCompileFlags):
                 'NSPR_CFLAGS', 'NSS_CFLAGS', 'MOZ_JPEG_CFLAGS', 'MOZ_PNG_CFLAGS',
                 'MOZ_ZLIB_CFLAGS', 'MOZ_PIXMAN_CFLAGS')))),
              ('CXXFLAGS', 'CFLAGS')),
             ('DSO', context.config.substs.get('DSO_CFLAGS'),
              ('CXXFLAGS', 'CFLAGS')),
             ('DSO_PIC', context.config.substs.get('DSO_PIC_CFLAGS'),
              ('CXXFLAGS', 'CFLAGS')),
             ('RTL', None, ('CXXFLAGS', 'CFLAGS')),
-            ('PROFILE_GEN_DYN_CFLAGS', None, ('PROFILE_GEN_DYN_CFLAGS',)),
             ('OS_COMPILE_CFLAGS', context.config.substs.get('OS_COMPILE_CFLAGS'),
              ('CFLAGS',)),
             ('OS_COMPILE_CXXFLAGS', context.config.substs.get('OS_COMPILE_CXXFLAGS'),
              ('CXXFLAGS',)),
             ('OS_CPPFLAGS', context.config.substs.get('OS_CPPFLAGS'),
              ('CXXFLAGS', 'CFLAGS', 'CXX_LDFLAGS', 'C_LDFLAGS')),
             ('OS_CFLAGS', context.config.substs.get('OS_CFLAGS'),
              ('CFLAGS', 'C_LDFLAGS')),
@@ -1184,17 +1183,17 @@ SUBCONTEXTS = {cls.__name__: cls for cls
 
 # This defines the set of mutable global variables.
 #
 # Each variable is a tuple of:
 #
 #   (storage_type, input_types, docs)
 
 VARIABLES = {
-    'SOURCES': (ContextDerivedTypedListWithItems(Path, StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': List, 'pgo_generate_only': bool})), list,
+    'SOURCES': (ContextDerivedTypedListWithItems(Path, StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': List})), list,
         """Source code files.
 
         This variable contains a list of source code files to compile.
         Accepts assembler, C, C++, Objective C/C++.
         """),
 
     'FILES_PER_UNIFIED_FILE': (int, int,
         """The number of source files to compile into each unified source file.
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -398,30 +398,28 @@ class LinkageMultipleRustLibrariesError(
 class Linkable(ContextDerived):
     """Generic context derived container object for programs and libraries"""
     __slots__ = (
         'cxx_link',
         'lib_defines',
         'linked_libraries',
         'linked_system_libs',
         'no_pgo_sources',
-        'pgo_gen_only_sources',
         'no_pgo',
         'sources',
     )
 
     def __init__(self, context):
         ContextDerived.__init__(self, context)
         self.cxx_link = False
         self.linked_libraries = []
         self.linked_system_libs = []
         self.lib_defines = Defines(context, {})
         self.sources = defaultdict(list)
         self.no_pgo_sources = []
-        self.pgo_gen_only_sources = set()
         self.no_pgo = False
 
     def link_library(self, obj):
         assert isinstance(obj, BaseLibrary)
         if obj.KIND != self.KIND:
             raise LinkageWrongKindError('%s != %s' % (obj.KIND, self.KIND))
         # Linking multiple Rust libraries into an object would result in
         # multiple copies of the Rust standard library, as well as linking
@@ -472,20 +470,16 @@ class Linkable(ContextDerived):
     @property
     def no_pgo_objs(self):
         return self._get_objs(self.no_pgo_sources)
 
     @property
     def objs(self):
         return self._get_objs(self.source_files())
 
-    @property
-    def pgo_gen_only_objs(self):
-        return self._get_objs(self.pgo_gen_only_sources)
-
 
 class BaseProgram(Linkable):
     """Context derived container object for programs, which is a unicode
     string.
 
     This class handles automatically appending a binary suffix to the program
     name.
     If the suffix is not defined, the program name is unchanged.
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -834,17 +834,16 @@ class TreeMetadataEmitter(LoggingMixin):
             # TODO: objdirs with only host things in them shouldn't need target
             # flags, but there's at least one Makefile.in (in
             # build/unix/elfhack) that relies on the value of LDFLAGS being
             # passed to one-off rules.
             self._compile_dirs.add(context.objdir)
 
         sources = defaultdict(list)
         gen_sources = defaultdict(list)
-        pgo_generate_only = set()
         all_flags = {}
         for symbol in ('SOURCES', 'HOST_SOURCES', 'UNIFIED_SOURCES'):
             srcs = sources[symbol]
             gen_srcs = gen_sources[symbol]
             context_srcs = context.get(symbol, [])
             seen_sources = set()
             for f in context_srcs:
                 if f in seen_sources:
@@ -856,43 +855,28 @@ class TreeMetadataEmitter(LoggingMixin):
                     srcs.append(full_path)
                 else:
                     assert isinstance(f, Path)
                     gen_srcs.append(full_path)
                 if symbol == 'SOURCES':
                     flags = context_srcs[f]
                     if flags:
                         all_flags[full_path] = flags
-                    # Files for the generation phase of PGO are unusual, so
-                    # it's not unreasonable to require them to be special.
-                    if flags.pgo_generate_only:
-                        if not isinstance(f, Path):
-                            raise SandboxValidationError('pgo_generate_only file'
-                                'must not be a generated file: %s' % f, context)
-                        if mozpath.splitext(f)[1] != '.cpp':
-                            raise SandboxValidationError('pgo_generate_only file'
-                                'must be a .cpp file: %s' % f, context)
-                        if flags.no_pgo:
-                            raise SandboxValidationError('pgo_generate_only files'
-                                'cannot be marked no_pgo: %s' % f, context)
-                        pgo_generate_only.add(f)
 
                 if isinstance(f, SourcePath) and not os.path.exists(full_path):
                     raise SandboxValidationError('File listed in %s does not '
                         'exist: \'%s\'' % (symbol, full_path), context)
 
         # UNIFIED_SOURCES only take SourcePaths, so there should be no
         # generated source in here
         assert not gen_sources['UNIFIED_SOURCES']
 
         no_pgo = context.get('NO_PGO')
         no_pgo_sources = [f for f, flags in all_flags.iteritems()
                           if flags.no_pgo]
-        pgo_gen_only_sources = set(f for f, flags in all_flags.iteritems()
-                                   if flags.pgo_generate_only)
         if no_pgo:
             if no_pgo_sources:
                 raise SandboxValidationError('NO_PGO and SOURCES[...].no_pgo '
                     'cannot be set at the same time', context)
             passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo
         if no_pgo_sources:
             passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo_sources
 
@@ -945,18 +929,16 @@ class TreeMetadataEmitter(LoggingMixin):
             for f in itertools.chain(sources[variable], gen_sources[variable]):
                 ext = mozpath.splitext(f)[1]
                 if ext not in allowed_suffixes:
                     raise SandboxValidationError(
                         '%s has an unknown file type.' % f, context)
 
             for srcs, cls in ((sources[variable], klass),
                               (gen_sources[variable], gen_klass)):
-                if variable == 'SOURCES' and pgo_gen_only_sources:
-                    srcs = [s for s in srcs if s not in pgo_gen_only_sources]
                 # Now sort the files to let groupby work.
                 sorted_files = sorted(srcs, key=canonical_suffix_for_file)
                 for canonical_suffix, files in itertools.groupby(
                         sorted_files, canonical_suffix_for_file):
                     if canonical_suffix in ('.cpp', '.mm'):
                         cxx_sources[variable] = True
                     elif canonical_suffix in ('.s', '.S'):
                         self._asm_compile_dirs.add(context.objdir)
@@ -970,34 +952,29 @@ class TreeMetadataEmitter(LoggingMixin):
                     ctxt_sources[variable][canonical_suffix] += sorted(srcs)
                     yield obj
 
         if ctxt_sources:
             for linkable in linkables:
                 for target_var in ('SOURCES', 'UNIFIED_SOURCES'):
                     for suffix, srcs in ctxt_sources[target_var].items():
                         linkable.sources[suffix] += srcs
-                if pgo_gen_only_sources:
-                    linkable.pgo_gen_only_sources = pgo_gen_only_sources
                 if no_pgo_sources:
                     linkable.no_pgo_sources = no_pgo_sources
                 elif no_pgo:
                     linkable.no_pgo = True
             for host_linkable in host_linkables:
                 for suffix, srcs in ctxt_sources['HOST_SOURCES'].items():
                     host_linkable.sources[suffix] += srcs
 
         for f, flags in all_flags.iteritems():
             if flags.flags:
                 ext = mozpath.splitext(f)[1]
                 yield PerSourceFlag(context, f, flags.flags)
 
-        if pgo_generate_only:
-            yield PgoGenerateOnlySources(context, pgo_generate_only)
-
         # If there are any C++ sources, set all the linkables defined here
         # to require the C++ linker.
         for vars, linkable_items in ((('SOURCES', 'UNIFIED_SOURCES'), linkables),
                                      (('HOST_SOURCES',), host_linkables)):
             for var in vars:
                 if cxx_sources[var]:
                     for l in linkable_items:
                         l.cxx_link = True
@@ -1107,28 +1084,16 @@ class TreeMetadataEmitter(LoggingMixin):
                 not context.config.substs.get('GNU_CC')):
             use_static_lib = (context.get('USE_STATIC_LIBS') and
                               not context.config.substs.get('MOZ_ASAN'))
             rtl_flag = '-MT' if use_static_lib else '-MD'
             if (context.config.substs.get('MOZ_DEBUG') and
                     not context.config.substs.get('MOZ_NO_DEBUG_RTL')):
                 rtl_flag += 'd'
             computed_flags.resolve_flags('RTL', [rtl_flag])
-            # For PGO clang-cl builds, we generate order files in the
-            # profile generate phase that are subsequently used to link the
-            # final library.  We need to provide flags to the compiler to
-            # have it instrument functions for generating the data for the
-            # order file.  We'd normally put flags like these in
-            # PROFILE_GEN_CFLAGS or the like, but we need to only use the
-            # flags in contexts where we're compiling code for xul.
-            code_for_xul = context.get('FINAL_LIBRARY', 'notxul') == 'xul'
-            if context.config.substs.get('CLANG_CL') and code_for_xul:
-                computed_flags.resolve_flags('PROFILE_GEN_DYN_CFLAGS',
-                                             ['-Xclang',
-                                              '-finstrument-functions-after-inlining'])
             if not context.config.substs.get('CROSS_COMPILE'):
                 computed_host_flags.resolve_flags('RTL', [rtl_flag])
 
         generated_files = set()
         localized_generated_files = set()
         for obj in self._process_generated_files(context):
             for f in obj.outputs:
                 generated_files.add(f)