diff mbox series

[2/2] Rework as a non-plugin

Message ID 20191208142818.10857-3-dmalcolm@redhat.com
State New
Headers show
Series v3 of analyzer patch kit (unsquashed) | expand

Commit Message

David Malcolm Dec. 8, 2019, 2:28 p.m. UTC
gcc/ChangeLog:
	* Makefile.in (lang_opt_files): Add analyzer.opt.
	(ANALYZER_OBJS): New.
	(OBJS): Add ANALYZER_OBJS.
	* analyzer/Make-plugin.in: Delete file.
	* analyzer/analysis-plan.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(analysis_plan::analysis_plan): Convert from auto_client_timevar
	to auto_timevar.
	* analyzer/analyzer-logging.cc: Guard with #if ENABLE_ANALYZER.
	* analyzer/analyzer-pass.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(pass_data_analyzer): Use TV_ANALYZER.
	(pass_analyzer::gate): New.
	(pass_analyzer::execute): Move the check for #if ENABLE_ANALYZER
	here.
	(make_pass_analyzer): Make non-static.
	(register_analyzer_pass): Delete.
	* analyzer/analyzer-plugin.cc: Delete file.
	* analyzer/analyzer-selftests.cc: Rework headers.
	(selftest::run_analyzer_selftests): Guard body with
	#if ENABLE_ANALYZER.
	* analyzer/analyzer-selftests.h: Fix comment.
	* analyzer/analyzer.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/analyzer.h: Include "function.h".
	* analyzer/call-string.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/checker-path.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/config-plugin.in: Delete file.
	* analyzer/constraint-manager.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/diagnostic-manager.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(diagnostic_manager::emit_saved_diagnostics): Convert from
	auto_client_timevar to auto_timevar.
	* analyzer/digraph.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/engine.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(strongly_connected_components::strongly_connected_components):
	Convert from auto_client_timevar to auto_timevar.
	(exploded_graph::process_worklist): Likewise.
	(exploded_graph::dump_exploded_nodes): Likewise.
	(dump_callgraph): Likewise.
	(impl_run_checkers): Likewise.
	(run_checkers): Drop top-level auto_client_timevar in favor of
	the tv_id of the pass as a whole.
	* analyzer/exploded-graph.h: Include "alloc-pool.h".
	* analyzer/graphviz.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/pending-diagnostic.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/program-point.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/program-state.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/region-model.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(dump_tree): New function.
	(region_model::dump_to_pp): Use dump_tree rather than %E.
	(dump_vec_of_tree): Likewise.
	(region_model::dump_summary_of_map): Likewise.
	* analyzer/region-model.h: Include "sbitmap.h".
	* analyzer/shortest-paths.h (shortest_paths::shortest_paths):
	Convert from auto_client_timevar to auto_timevar.
	* analyzer/sm-file.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/sm-malloc.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/sm-pattern-test.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/sm-sensitive.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/sm-signal.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/sm-taint.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/sm.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* analyzer/state-purge.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(state_purge_map::state_purge_map): Convert from
	auto_client_timevar to auto_timevar.
	* analyzer/supergraph.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	(supergraph::supergraph): Convert from auto_client_timevar to
	auto_timevar.
	* analyzer/supergraph.h: Include "options.h", "function.h",
	"cfg.h", and "basic-block.h".
	* analyzer/tristate.cc: Rework headers.  Guard with
	#if ENABLE_ANALYZER.
	* common.opt (fanalyzer): Convert from Driver to Common.  Add
	description.
	* configure.ac (--disable-analyzer, ENABLE_ANALYZER): New option.
	(gccdepdir): Also created depdir for "analyzer" subdir.
	* gcc.c (driver_handle_option): Drop case OPT_fanalyzer.
	(process_command): Drop handling of flag_analyzer; this is now
	done in the gate vfunc of the pass.
	* passes.def (pass_analyzer): Add before
	pass_ipa_whole_program_visibility.
	* selftest-run-tests.c: Include "analyzer/analyzer-selftests.h".
	(selftest::run_tests): Call selftest::run_analyzer_selftests.
	* timevar.def (TV_ANALYZER): New timevar.
	(TV_ANALYZER_SUPERGRAPH): Likewise.
	(TV_ANALYZER_STATE_PURGE): Likewise.
	(TV_ANALYZER_PLAN): Likewise.
	(TV_ANALYZER_SCC): Likewise.
	(TV_ANALYZER_WORKLIST): Likewise.
	(TV_ANALYZER_DUMP): Likewise.
	(TV_ANALYZER_DIAGNOSTICS): Likewise.
	(TV_ANALYZER_SHORTEST_PATHS): Likewise.
	* tree-pass.h (make_pass_analyzer): New decl.
---
 gcc/Makefile.in                           |  32 +++-
 gcc/analyzer/Make-plugin.in               | 182 ----------------------
 gcc/analyzer/analysis-plan.cc             |   8 +-
 gcc/analyzer/analyzer-logging.cc          |   4 +
 gcc/analyzer/analyzer-pass.cc             |  41 +++--
 gcc/analyzer/analyzer-plugin.cc           |  63 --------
 gcc/analyzer/analyzer-selftests.cc        |   3 +-
 gcc/analyzer/analyzer-selftests.h         |   2 +-
 gcc/analyzer/analyzer.cc                  |   7 +-
 gcc/analyzer/analyzer.h                   |   2 +
 gcc/analyzer/{plugin.opt => analyzer.opt} |   0
 gcc/analyzer/call-string.cc               |   6 +-
 gcc/analyzer/checker-path.cc              |   8 +-
 gcc/analyzer/config-plugin.in             |  34 ----
 gcc/analyzer/constraint-manager.cc        |  10 +-
 gcc/analyzer/diagnostic-manager.cc        |   7 +-
 gcc/analyzer/digraph.cc                   |   5 +-
 gcc/analyzer/engine.cc                    |  26 ++--
 gcc/analyzer/exploded-graph.h             |   1 +
 gcc/analyzer/graphviz.cc                  |   5 +-
 gcc/analyzer/pending-diagnostic.cc        |   5 +-
 gcc/analyzer/program-point.cc             |   5 +-
 gcc/analyzer/program-state.cc             |   5 +-
 gcc/analyzer/region-model.cc              |  66 ++++----
 gcc/analyzer/region-model.h               |   1 +
 gcc/analyzer/shortest-paths.h             |   2 +-
 gcc/analyzer/sm-file.cc                   |   8 +-
 gcc/analyzer/sm-malloc.cc                 |   9 +-
 gcc/analyzer/sm-pattern-test.cc           |   7 +-
 gcc/analyzer/sm-sensitive.cc              |   9 +-
 gcc/analyzer/sm-signal.cc                 |   7 +-
 gcc/analyzer/sm-taint.cc                  |   8 +-
 gcc/analyzer/sm.cc                        |   8 +-
 gcc/analyzer/state-purge.cc               |  10 +-
 gcc/analyzer/supergraph.cc                |   9 +-
 gcc/analyzer/supergraph.h                 |   4 +
 gcc/analyzer/tristate.cc                  |   5 +-
 gcc/common.opt                            |   3 +-
 gcc/configure                             |  25 ++-
 gcc/configure.ac                          |  14 +-
 gcc/gcc.c                                 |  12 --
 gcc/passes.def                            |   1 +
 gcc/selftest-run-tests.c                  |   4 +
 gcc/timevar.def                           |  11 ++
 gcc/tree-pass.h                           |   1 +
 45 files changed, 300 insertions(+), 385 deletions(-)
 delete mode 100644 gcc/analyzer/Make-plugin.in
 delete mode 100644 gcc/analyzer/analyzer-plugin.cc
 rename gcc/analyzer/{plugin.opt => analyzer.opt} (100%)
 delete mode 100644 gcc/analyzer/config-plugin.in
diff mbox series

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 77a12d5c7258..62ec973563b7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -567,7 +567,7 @@  xm_include_list=@xm_include_list@
 xm_defines=@xm_defines@
 lang_checks=
 lang_checks_parallelized=
-lang_opt_files=@lang_opt_files@ $(srcdir)/c-family/c.opt $(srcdir)/common.opt $(srcdir)/params.opt
+lang_opt_files=@lang_opt_files@ $(srcdir)/c-family/c.opt $(srcdir)/common.opt $(srcdir)/params.opt $(srcdir)/analyzer/analyzer.opt
 lang_specs_files=@lang_specs_files@
 lang_tree_files=@lang_tree_files@
 target_cpu_default=@target_cpu_default@
@@ -1214,6 +1214,35 @@  C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
   c-family/c-ubsan.o c-family/known-headers.o \
   c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o
 
+# Analyzer object files
+ANALYZER_OBJS = \
+	analyzer/analysis-plan.o \
+	analyzer/analyzer.o \
+	analyzer/analyzer-logging.o \
+	analyzer/analyzer-pass.o \
+	analyzer/analyzer-selftests.o \
+	analyzer/call-string.o \
+	analyzer/checker-path.o \
+	analyzer/constraint-manager.o \
+	analyzer/diagnostic-manager.o \
+	analyzer/digraph.o \
+	analyzer/graphviz.o \
+	analyzer/engine.o \
+	analyzer/pending-diagnostic.o \
+	analyzer/program-point.o \
+	analyzer/program-state.o \
+	analyzer/region-model.o \
+	analyzer/sm.o \
+	analyzer/sm-file.o \
+	analyzer/sm-malloc.o \
+	analyzer/sm-pattern-test.o \
+	analyzer/sm-sensitive.o \
+	analyzer/sm-signal.o \
+	analyzer/sm-taint.o \
+	analyzer/state-purge.o \
+	analyzer/supergraph.o \
+	analyzer/tristate.o
+
 # Language-independent object files.
 # We put the *-match.o and insn-*.o files first so that a parallel make
 # will build them sooner, because they are large and otherwise tend to be
@@ -1618,6 +1647,7 @@  OBJS = \
 	wide-int-print.o \
 	xcoffout.o \
 	$(out_object_file) \
+	$(ANALYZER_OBJS) \
 	$(EXTRA_OBJS) \
 	$(host_hook_obj)
 
diff --git a/gcc/analyzer/Make-plugin.in b/gcc/analyzer/Make-plugin.in
deleted file mode 100644
index f679686783fa..000000000000
--- a/gcc/analyzer/Make-plugin.in
+++ /dev/null
@@ -1,182 +0,0 @@ 
-# Top level -*- makefile -*- fragment for analyzer
-#   Copyright (C) 2013-2019 Free Software Foundation, Inc.
-
-#This file is part of GCC.
-
-#GCC is free software; you can redistribute it and/or modify
-#it under the terms of the GNU General Public License as published by
-#the Free Software Foundation; either version 3, or (at your option)
-#any later version.
-
-#GCC is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-# This file provides the plugin dependent support in the main Makefile.
-# Each plugin makefile fragment must provide the following targets:
-#
-# foo.all.cross, foo.start.encap, foo.rest.encap,
-# foo.install-common, foo.install-man, foo.install-info, foo.install-pdf,
-# foo.install-html, foo.info, foo.dvi, foo.pdf, foo.html, foo.uninstall,
-# foo.mostlyclean, foo.clean, foo.distclean,
-# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
-#
-# where `foo' is the name of the plugin.
-#
-# It should also provide rules for:
-#
-# - making any compiler driver (eg: g++)
-# - the plugin proper (eg: analyzer_plugin.so)
-# - define the names for selecting the plugin in PLUGINS.
-
-#
-# Define the names for selecting analyzer in PLUGINS.
-# Note that it would be nice to move the dependency on g++
-# into the analyzer rule, but that needs a little bit of work
-# to do the right thing within all.cross.
-
-plugin_builddir = plugin
-
-ANALYZER_PLUGIN_SO = $(plugin_builddir)/analyzer_plugin.so
-
-analyzer: \
-	$(FULL_DRIVER_NAME) \
-	$(ANALYZER_PLUGIN_SO)
-
-# Tell GNU make to ignore these if they exist.
-.PHONY: analyzer
-
-# Files that are linked into analyzer plugin
-
-analyzer_OBJS = \
-	analyzer/analysis-plan.o \
-	analyzer/analyzer.o \
-	analyzer/analyzer-logging.o \
-	analyzer/analyzer-pass.o \
-	analyzer/analyzer-plugin.o \
-	analyzer/analyzer-selftests.o \
-	analyzer/call-string.o \
-	analyzer/checker-path.o \
-	analyzer/constraint-manager.o \
-	analyzer/diagnostic-manager.o \
-	analyzer/digraph.o \
-	analyzer/graphviz.o \
-	analyzer/engine.o \
-	analyzer/pending-diagnostic.o \
-	analyzer/program-point.o \
-	analyzer/program-state.o \
-	analyzer/region-model.o \
-	analyzer/sm.o \
-	analyzer/sm-file.o \
-	analyzer/sm-malloc.o \
-	analyzer/sm-pattern-test.o \
-	analyzer/sm-sensitive.o \
-	analyzer/sm-signal.o \
-	analyzer/sm-taint.o \
-	analyzer/state-purge.o \
-	analyzer/supergraph.o \
-	analyzer/tristate.o \
-
-# Use strict warnings for this plugin.
-analyzer-warn = $(STRICT_WARN)
-
-#
-# Build hooks:
-
-analyzer.all.cross:
-analyzer.start.encap:
-analyzer.rest.encap:
-
-$(plugin_builddir):
-	mkdir $@
-
-$(ANALYZER_PLUGIN_SO): $(analyzer_OBJS) $(plugin_builddir)
-	$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) \
-	  -o $@ \
-	  -shared \
-	  $(analyzer_OBJS) \
-	-lpthread
-
-# If the analyzer is enabled, require the selftests to be run for it
-# at each stage of the build:
-selftest-analyzer: s-selftest-analyzer
-
-ANALYZER_SELFTEST_FLAGS = -xc $(SELFTEST_FLAGS) -fanalyzer
-ANALYZER_SELFTEST_DEPS = cc1$(exeext) $(SELFTEST_DEPS) $(ANALYZER_PLUGIN_SO)
-
-# Run the analyzer selftests:
-s-selftest-analyzer: $(ANALYZER_SELFTEST_DEPS)
-	$(GCC_FOR_TARGET) $(ANALYZER_SELFTEST_FLAGS)
-	$(STAMP) $@
-
-# Convenience methods for running analyzer selftests under gdb:
-.PHONY: selftest-analyzer-gdb
-selftest-analyzer-gdb: $(ANALYZER_SELFTEST_DEPS)
-	$(GCC_FOR_TARGET) $(ANALYZER_SELFTEST_FLAGS) \
-	  -wrapper gdb,--args
-
-# Convenience methods for running analyzer selftests under valgrind:
-.PHONY: selftest-analyzer-valgrind
-selftest-analyzer-valgrind: $(ANALYZER_SELFTEST_DEPS)
-	$(GCC_FOR_TARGET) $(ANALYZER_SELFTEST_FLAGS) \
-	  -wrapper valgrind,--leak-check=full
-
-# Documentation build hooks.
-analyzer.info:
-analyzer.dvi:
-analyzer.pdf:
-analyzer.html:
-analyzer.srcinfo:
-analyzer.man:
-analyzer.srcman:
-
-# Testing hooks:
-lang_checks += check-analyzer
-
-#
-# Install hooks:
-analyzer.install-common:
-analyzer.install-man:
-analyzer.install-info:
-analyzer.install-pdf:
-analyzer.install-html:
-
-analyzer.install-plugin: installdirs
-	$(INSTALL_DATA) $(ANALYZER_PLUGIN_SO) $(DESTDIR)/$(plugin_resourcesdir)/analyzer_plugin.so
-
-analyzer.uninstall:
-
-#
-# Clean hooks:
-# A lot of the ancillary files are deleted by the main makefile.
-# We just have to delete files specific to us.
-
-analyzer.mostlyclean:
-
-analyzer.clean:
-
-analyzer.distclean:
-
-analyzer.maintainer-clean:
-
-#
-# Stage hooks:
-# The main makefile has already created stage?/analyzer.
-
-analyzer.stage1: stage1-start
-	-mv analyzer/*$(objext) stage1/analyzer
-analyzer.stage2: stage2-start
-	-mv analyzer/*$(objext) stage2/analyzer
-analyzer.stage3: stage3-start
-	-mv analyzer/*$(objext) stage3/analyzer
-analyzer.stage4: stage4-start
-	-mv analyzer/*$(objext) stage4/analyzer
-analyzer.stageprofile: stageprofile-start
-	-mv analyzer/*$(objext) stageprofile/analyzer
-analyzer.stagefeedback: stagefeedback-start
-	-mv analyzer/*$(objext) stagefeedback/analyzer
diff --git a/gcc/analyzer/analysis-plan.cc b/gcc/analyzer/analysis-plan.cc
index 38123ffb13ba..ca9b01b32c96 100644
--- a/gcc/analyzer/analysis-plan.cc
+++ b/gcc/analyzer/analysis-plan.cc
@@ -19,10 +19,10 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "options.h"
 #include "cgraph.h"
 #include "timevar.h"
 #include "ipa-utils.h"
@@ -30,6 +30,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/analysis-plan.h"
 #include "analyzer/supergraph.h"
 
+#if ENABLE_ANALYZER
+
 /* class analysis_plan.  */
 
 /* analysis_plan's ctor.  */
@@ -41,7 +43,7 @@  analysis_plan::analysis_plan (const supergraph &sg, logger *logger)
   m_index_by_uid (symtab->cgraph_max_uid)
 {
   LOG_SCOPE (logger);
-  auto_client_timevar tv ("creating analysis plan");
+  auto_timevar time (TV_ANALYZER_PLAN);
 
   m_num_cgraph_nodes = ipa_reverse_postorder (m_cgraph_node_postorder);
   gcc_assert (m_num_cgraph_nodes == symtab->cgraph_count);
@@ -112,3 +114,5 @@  analysis_plan::use_summary_p (const cgraph_edge *edge) const
 
   return true;
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/analyzer-logging.cc b/gcc/analyzer/analyzer-logging.cc
index 575435cbceaa..2010cb78a176 100644
--- a/gcc/analyzer/analyzer-logging.cc
+++ b/gcc/analyzer/analyzer-logging.cc
@@ -28,6 +28,8 @@  along with GCC; see the file COPYING3.  If not see
 
 #include "analyzer/analyzer-logging.h"
 
+#if ENABLE_ANALYZER
+
 /* Implementation of class logger.  */
 
 /* ctor for logger.  */
@@ -218,3 +220,5 @@  log_user::set_logger (logger *logger)
     m_logger->decref ("log_user::set_logger");
   m_logger = logger;
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/analyzer-pass.cc b/gcc/analyzer/analyzer-pass.cc
index 54b8a5ca6db3..60535a944dc9 100644
--- a/gcc/analyzer/analyzer-pass.cc
+++ b/gcc/analyzer/analyzer-pass.cc
@@ -19,11 +19,12 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "context.h"
 #include "tree-pass.h"
+#include "diagnostic.h"
+#include "options.h"
 #include "analyzer/engine.h"
 
 namespace {
@@ -35,7 +36,7 @@  const pass_data pass_data_analyzer =
   IPA_PASS, /* type */
   "analyzer", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  TV_NONE, /* tv_id */
+  TV_ANALYZER, /* tv_id */
   PROP_ssa, /* properties_required */
   0, /* properties_provided */
   0, /* properties_destroyed */
@@ -62,15 +63,31 @@  public:
   {}
 
   /* opt_pass methods: */
+  bool gate (function *) FINAL OVERRIDE;
   unsigned int execute (function *) FINAL OVERRIDE;
 }; // class pass_analyzer
 
+/* Only run the analyzer if -fanalyzer.  */
+
+bool
+pass_analyzer::gate (function *)
+{
+  return flag_analyzer != 0;
+}
+
 /* Entrypoint for the analyzer pass.  */
 
 unsigned int
 pass_analyzer::execute (function *)
 {
+#if ENABLE_ANALYZER
   run_checkers ();
+#else
+  sorry ("%qs was not enabled in this build of GCC"
+	 " (missing configure-time option %qs)",
+	 "-fanalyzer", "--enable-analyzer");
+#endif
+
   return 0;
 }
 
@@ -78,26 +95,8 @@  pass_analyzer::execute (function *)
 
 /* Make an instance of the analyzer pass.  */
 
-static ipa_opt_pass_d *
+ipa_opt_pass_d *
 make_pass_analyzer (gcc::context *ctxt)
 {
   return new pass_analyzer (ctxt);
 }
-
-/* Register the analyzer pass with GCC's pass manager.
-   Called by plugin_init.  */
-
-void
-register_analyzer_pass ()
-{
-  static struct register_pass_info pass_info;
-
-  /* IPA-LTO pass.  */
-  pass_info.pass = make_pass_analyzer (g);
-  pass_info.reference_pass_name = "whole-program";
-  pass_info.ref_pass_instance_number = 1;
-  pass_info.pos_op = PASS_POS_INSERT_BEFORE;
-
-  register_callback ("analyzer", PLUGIN_PASS_MANAGER_SETUP, NULL,
-		     &pass_info);
-}
diff --git a/gcc/analyzer/analyzer-plugin.cc b/gcc/analyzer/analyzer-plugin.cc
deleted file mode 100644
index 1e7c56e50c56..000000000000
--- a/gcc/analyzer/analyzer-plugin.cc
+++ /dev/null
@@ -1,63 +0,0 @@ 
-/* Top-level interface to the analyzer, as a GCC plugin.
-   Copyright (C) 2019 Free Software Foundation, Inc.
-   Contributed by David Malcolm <dmalcolm@redhat.com>.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "gcc-plugin.h"
-#include "system.h"
-#include "coretypes.h"
-#include "analyzer/analyzer.h"
-#include "analyzer/analyzer-selftests.h"
-
-int plugin_is_GPL_compatible;
-
-#if CHECKING_P
-
-namespace selftest {
-
-/* Callback for running the analyzer's selftests.  */
-
-static void
-analyzer_selftests_cb (void */*gcc_data*/, void */*user_data*/)
-{
-  run_analyzer_selftests ();
-}
-
-} /* end of namespace selftest.  */
-
-#endif /* #if CHECKING_P */
-
-/* Entrypoint to the pass.  */
-
-int
-plugin_init (struct plugin_name_args *plugin_info ATTRIBUTE_UNUSED,
-	     struct plugin_gcc_version */*version*/)
-{
-  /* Register our selftests.  */
-#if CHECKING_P
-  register_callback (plugin_info->base_name,
-		     PLUGIN_RUN_SELFTESTS,
-		     selftest::analyzer_selftests_cb, NULL);
-#endif /* #if CHECKING_P */
-
-  /* Register our pass.  */
-  register_analyzer_pass ();
-
-  return 0;
-}
diff --git a/gcc/analyzer/analyzer-selftests.cc b/gcc/analyzer/analyzer-selftests.cc
index 5696af5762df..487cd81fe211 100644
--- a/gcc/analyzer/analyzer-selftests.cc
+++ b/gcc/analyzer/analyzer-selftests.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
@@ -48,12 +47,14 @@  build_global_decl (const char *name, tree type)
 void
 run_analyzer_selftests ()
 {
+#if ENABLE_ANALYZER
   analyzer_constraint_manager_cc_tests ();
   analyzer_digraph_cc_tests ();
   analyzer_program_point_cc_tests ();
   analyzer_program_state_cc_tests ();
   analyzer_region_model_cc_tests ();
   analyzer_tristate_cc_tests ();
+#endif /* #if ENABLE_ANALYZER */
 }
 
 } /* end of namespace selftest.  */
diff --git a/gcc/analyzer/analyzer-selftests.h b/gcc/analyzer/analyzer-selftests.h
index 1c26f25616a3..0724ce74c9c2 100644
--- a/gcc/analyzer/analyzer-selftests.h
+++ b/gcc/analyzer/analyzer-selftests.h
@@ -30,7 +30,7 @@  extern tree build_global_decl (const char *name, tree type);
 extern void run_analyzer_selftests ();
 
 /* Declarations for specific families of tests (by source file), in
-   alphabetical order, for the checker plugin.  */
+   alphabetical order.  */
 extern void analyzer_checker_script_cc_tests ();
 extern void analyzer_constraint_manager_cc_tests ();
 extern void analyzer_digraph_cc_tests ();
diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
index 5405facf5e86..3f073371f936 100644
--- a/gcc/analyzer/analyzer.cc
+++ b/gcc/analyzer/analyzer.cc
@@ -19,15 +19,18 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "diagnostic.h"
 #include "intl.h"
 #include "analyzer/analyzer.h"
 
+#if ENABLE_ANALYZER
+
 /* Helper function for checkers.  Is the CALL to the given function name,
    and with the given number of arguments?
 
@@ -143,3 +146,5 @@  make_label_text (bool can_colorize, const char *fmt, ...)
   delete pp;
   return result;
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 353285c35c36..0595822dee6f 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -21,6 +21,8 @@  along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ANALYZER_ANALYZER_H
 #define GCC_ANALYZER_ANALYZER_H
 
+#include "function.h"
+
 /* Forward decls of common types, with indentation to show inheritance.  */
 
 class graphviz_out;
diff --git a/gcc/analyzer/plugin.opt b/gcc/analyzer/analyzer.opt
similarity index 100%
rename from gcc/analyzer/plugin.opt
rename to gcc/analyzer/analyzer.opt
diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc
index a9a9ce51ea52..a9ff9cbfca44 100644
--- a/gcc/analyzer/call-string.cc
+++ b/gcc/analyzer/call-string.cc
@@ -19,14 +19,16 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "pretty-print.h"
 #include "tree.h"
+#include "options.h"
 #include "analyzer/call-string.h"
 #include "analyzer/supergraph.h"
 
+#if ENABLE_ANALYZER
+
 /* class call_string.  */
 
 /* call_string's copy ctor.  */
@@ -218,3 +220,5 @@  call_string::validate () const
       gcc_assert (e->get_caller_function ()
 		  == m_return_edges[i - 1]->get_callee_function ());
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 554a20f31bec..6eb3dff62c6e 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -19,18 +19,22 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "gimple-pretty-print.h"
+#include "fold-const.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/checker-path.h"
 #include "analyzer/supergraph.h"
 #include "analyzer/diagnostic-manager.h"
 #include "analyzer/exploded-graph.h"
 
+#if ENABLE_ANALYZER
+
 ////////////////////////////////////////////////////////////////////////////
 
 /* Get a string for EK.  */
@@ -944,3 +948,5 @@  checker_path::add_final_event (const state_machine *sm,
 			 sm, var, state);
   add_event (end_of_path);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/config-plugin.in b/gcc/analyzer/config-plugin.in
deleted file mode 100644
index 283e8e93e498..000000000000
--- a/gcc/analyzer/config-plugin.in
+++ /dev/null
@@ -1,34 +0,0 @@ 
-# Top level configure fragment for static analyzer
-#   Copyright (C) 2013-2015 Free Software Foundation, Inc.
-
-#This file is part of GCC.
-
-#GCC is free software; you can redistribute it and/or modify
-#it under the terms of the GNU General Public License as published by
-#the Free Software Foundation; either version 3, or (at your option)
-#any later version.
-
-#GCC is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-# Configure looks for the existence of this file to auto-config each plugin.
-# We define several parameters used by configure:
-#
-# plugin	- name of plugin as it would appear in $(PLUGINS)
-# compilers	- value to add to $(COMPILERS)
-
-plugin="analyzer"
-
-compilers=""
-
-target_libs=""
-
-gtfiles=""
-
-build_by_default="no"
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 12846f2c18b6..8a9bb5df0c9b 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -19,19 +19,23 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "gimple-iterator.h"
-#include "graphviz.h"
+#include "fold-const.h"
 #include "selftest.h"
 #include "analyzer/analyzer.h"
+#include "analyzer/graphviz.h"
 #include "analyzer/supergraph.h"
 #include "analyzer/constraint-manager.h"
 #include "analyzer/analyzer-selftests.h"
 
+#if ENABLE_ANALYZER
+
 /* One of the end-points of a range.  */
 
 struct bound
@@ -2261,3 +2265,5 @@  analyzer_constraint_manager_cc_tests ()
 } // namespace selftest
 
 #endif /* CHECKING_P */
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index cbbba4e8de40..258d3187acc8 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
@@ -31,6 +30,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/exploded-graph.h"
 #include "analyzer/checker-path.h"
 
+#if ENABLE_ANALYZER
+
 /* class saved_diagnostic.  */
 
 /* saved_diagnostic's ctor.
@@ -370,7 +371,7 @@  void
 diagnostic_manager::emit_saved_diagnostics (const exploded_graph &eg)
 {
   LOG_SCOPE (get_logger ());
-  auto_client_timevar tv ("emit saved diagnostics");
+  auto_timevar tv (TV_ANALYZER_DIAGNOSTICS);
   log ("# saved diagnostics: %i", m_saved_diagnostics.length ());
 
   if (m_saved_diagnostics.length () == 0)
@@ -1185,3 +1186,5 @@  diagnostic_manager::prune_path (checker_path *path,
 
   path->maybe_log (get_logger (), "pruned");
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/digraph.cc b/gcc/analyzer/digraph.cc
index c1fa46ee0c3a..04a4249f0119 100644
--- a/gcc/analyzer/digraph.cc
+++ b/gcc/analyzer/digraph.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "diagnostic.h"
@@ -28,6 +27,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/shortest-paths.h"
 #include "selftest.h"
 
+#if ENABLE_ANALYZER
+
 #if CHECKING_P
 
 namespace selftest {
@@ -187,3 +188,5 @@  analyzer_digraph_cc_tests ()
 } // namespace selftest
 
 #endif /* #if CHECKING_P */
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index f739af779ef3..66f6a39739fd 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -19,10 +19,10 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "fold-const.h"
 #include "gcc-rich-location.h"
 #include "analyzer/exploded-graph.h"
 #include "analyzer/analysis-plan.h"
@@ -31,6 +31,8 @@  along with GCC; see the file COPYING3.  If not see
 
 /* For an overview, see gcc/doc/analyzer.texi.  */
 
+#if ENABLE_ANALYZER
+
 static int readability_comparator (const void *p1, const void *p2);
 
 ////////////////////////////////////////////////////////////////////////////
@@ -1470,7 +1472,7 @@  strongly_connected_components (const supergraph &sg, logger *logger)
 : m_sg (sg), m_per_node (m_sg.num_nodes ())
 {
   LOG_SCOPE (logger);
-  auto_client_timevar tv ("computing scc");
+  auto_timevar tv (TV_ANALYZER_SCC);
 
   for (int i = 0; i < m_sg.num_nodes (); i++)
     m_per_node.quick_push (per_node_data ());
@@ -2082,7 +2084,7 @@  void
 exploded_graph::process_worklist ()
 {
   LOG_SCOPE (get_logger ());
-  auto_client_timevar tv ("exploded_graph::process_worklist");
+  auto_timevar tv (TV_ANALYZER_WORKLIST);
 
   while (m_worklist.length () > 0)
     {
@@ -3048,7 +3050,7 @@  exploded_graph::dump_exploded_nodes () const
 
   if (flag_dump_analyzer_exploded_nodes)
     {
-      auto_client_timevar tv ("-fdump-analyzer-exploded-nodes");
+      auto_timevar tv (TV_ANALYZER_DUMP);
       gcc_rich_location richloc (UNKNOWN_LOCATION);
       unsigned i;
       exploded_node *enode;
@@ -3079,7 +3081,7 @@  exploded_graph::dump_exploded_nodes () const
   /* Dump the egraph in textual form to a dump file.  */
   if (flag_dump_analyzer_exploded_nodes_2)
     {
-      auto_client_timevar tv ("-fdump-analyzer-exploded-nodes-2");
+      auto_timevar tv (TV_ANALYZER_DUMP);
       char *filename
 	= concat (dump_base_name, ".eg.txt", NULL);
       FILE *outf = fopen (filename, "w");
@@ -3109,7 +3111,7 @@  exploded_graph::dump_exploded_nodes () const
   /* Dump the egraph in textual form to multiple dump files, one per enode.  */
   if (flag_dump_analyzer_exploded_nodes_3)
     {
-      auto_client_timevar tv ("-fdump-analyzer-exploded-nodes-3");
+      auto_timevar tv (TV_ANALYZER_DUMP);
 
       unsigned i;
       exploded_node *enode;
@@ -3458,7 +3460,7 @@  dump_callgraph (const supergraph &sg, const char *filename,
 static void
 dump_callgraph (const supergraph &sg, const exploded_graph *eg)
 {
-  auto_client_timevar tv ("writing .callgraph.dot");
+  auto_timevar tv (TV_ANALYZER_DUMP);
   char *filename = concat (dump_base_name, ".callgraph.dot", NULL);
   dump_callgraph (sg, filename, eg);
   free (filename);
@@ -3488,7 +3490,7 @@  impl_run_checkers (logger *logger)
 
   if (flag_dump_analyzer_supergraph)
     {
-      auto_client_timevar tv ("writing .supergraph.dot");
+      auto_timevar tv (TV_ANALYZER_DUMP);
       char *filename = concat (dump_base_name, ".supergraph.dot", NULL);
       supergraph::dump_args_t args ((enum supergraph_dot_flags)0, NULL);
       sg.dump_dot (filename, args);
@@ -3497,7 +3499,7 @@  impl_run_checkers (logger *logger)
 
   if (flag_dump_analyzer_state_purge)
     {
-      auto_client_timevar tv ("writing .state-purge.dot");
+      auto_timevar tv (TV_ANALYZER_DUMP);
       state_purge_annotator a (purge_map);
       char *filename = concat (dump_base_name, ".state-purge.dot", NULL);
       supergraph::dump_args_t args ((enum supergraph_dot_flags)0, &a);
@@ -3533,7 +3535,7 @@  impl_run_checkers (logger *logger)
 
   if (flag_dump_analyzer_exploded_graph)
     {
-      auto_client_timevar tv ("writing .eg.dot");
+      auto_timevar tv (TV_ANALYZER_DUMP);
       char *filename
 	= concat (dump_base_name, ".eg.dot", NULL);
       exploded_graph::dump_args_t args (eg);
@@ -3561,8 +3563,6 @@  impl_run_checkers (logger *logger)
 void
 run_checkers ()
 {
-  auto_client_timevar tv ("run_checkers");
-
   /* Handle -fdump-analyzer and -fdump-analyzer-stderr.  */
   FILE *dump_fout = NULL;
   /* Track if we're responsible for closing dump_fout.  */
@@ -3594,3 +3594,5 @@  run_checkers ()
   if (owns_dump_fout)
     fclose (dump_fout);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index c8784acd8d91..95c7b985eca8 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -21,6 +21,7 @@  along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ANALYZER_EXPLODED_GRAPH_H
 #define GCC_ANALYZER_EXPLODED_GRAPH_H
 
+#include "alloc-pool.h"
 #include "fibonacci_heap.h"
 #include "analyzer/analyzer-logging.h"
 #include "analyzer/constraint-manager.h"
diff --git a/gcc/analyzer/graphviz.cc b/gcc/analyzer/graphviz.cc
index 4ba9330cd8c8..54b8a036ae41 100644
--- a/gcc/analyzer/graphviz.cc
+++ b/gcc/analyzer/graphviz.cc
@@ -19,11 +19,12 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "analyzer/graphviz.h"
 
+#if ENABLE_ANALYZER
+
 /* graphviz_out's ctor, wrapping PP.  */
 
 graphviz_out::graphviz_out (pretty_printer *pp)
@@ -99,3 +100,5 @@  graphviz_out::end_tr ()
   pp_string (m_pp, "</TD></TR>");
   pp_write_text_to_stream (m_pp);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/pending-diagnostic.cc b/gcc/analyzer/pending-diagnostic.cc
index 96ab82403978..ae61b47bef66 100644
--- a/gcc/analyzer/pending-diagnostic.cc
+++ b/gcc/analyzer/pending-diagnostic.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
@@ -28,6 +27,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/analyzer.h"
 #include "analyzer/pending-diagnostic.h"
 
+#if ENABLE_ANALYZER
+
 /* Generate a label_text by printing FMT.
 
    Use a clone of the global_dc for formatting callbacks.
@@ -59,3 +60,5 @@  evdesc::event_desc::formatted_print (const char *fmt, ...) const
   delete pp;
   return result;
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index c46aa51eb43b..4ccb79a95128 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
@@ -29,6 +28,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/exploded-graph.h"
 #include "analyzer/analysis-plan.h"
 
+#if ENABLE_ANALYZER
+
 /* Get a string for PK.  */
 
 const char *
@@ -517,3 +518,5 @@  analyzer_program_point_cc_tests ()
 } // namespace selftest
 
 #endif /* CHECKING_P */
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 6313174e99ad..bd2309c4b627 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
@@ -31,6 +30,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/state-purge.h"
 #include "analyzer/analyzer-selftests.h"
 
+#if ENABLE_ANALYZER
+
 ////////////////////////////////////////////////////////////////////////////
 
 /* class sm_state_map.  */
@@ -1316,3 +1317,5 @@  analyzer_program_state_cc_tests ()
 } // namespace selftest
 
 #endif /* CHECKING_P */
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index dccd4eec37c7..56e45f20b637 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -19,21 +19,25 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "graphviz.h"
+#include "options.h"
 #include "cgraph.h"
 #include "tree-dfa.h"
 #include "stringpool.h"
 #include "convert.h"
 #include "target.h"
-#include "selftest.h"
+#include "fold-const.h"
+#include "tree-pretty-print.h"
 #include "diagnostic-color.h"
 #include "diagnostic-metadata.h"
+#include "selftest.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/analyzer-logging.h"
 #include "analyzer/tristate.h"
@@ -43,8 +47,19 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/analyzer-selftests.h"
 
+#if ENABLE_ANALYZER
+
 ////////////////////////////////////////////////////////////////////////////
 
+/* Dump T to PP in language-independent form, for debugging/logging/dumping
+   purposes.  */
+
+static void
+dump_tree (pretty_printer *pp, tree t)
+{
+  dump_generic_node (pp, t, 0, TDF_SLIM, 0);
+}
+
 /* Dump this path_var to PP (which must support %E for trees).
 
    Express the stack depth using an "@DEPTH" suffix, so e.g. given
@@ -3456,9 +3471,9 @@  region_model::dump_to_pp (pretty_printer *pp, bool summarize) const
 			   && CONSTANT_CLASS_P (rhs_tree)))
 		    {
 		      dump_separator (pp, &is_first);
-		      PUSH_IGNORE_WFORMAT
-			pp_printf (pp, "%E == %E", lhs_tree, rhs_tree);
-		      POP_IGNORE_WFORMAT
+		      dump_tree (pp, lhs_tree);
+		      pp_string (pp, " == ");
+		      dump_tree (pp, rhs_tree);
 		    }
 		}
 	    }
@@ -3477,10 +3492,9 @@  region_model::dump_to_pp (pretty_printer *pp, bool summarize) const
 	      && !(CONSTANT_CLASS_P (lhs_tree) && CONSTANT_CLASS_P (rhs_tree)))
 	    {
 	      dump_separator (pp, &is_first);
-	      PUSH_IGNORE_WFORMAT
-		pp_printf (pp, "%E %s %E",
-			   lhs_tree, constraint_op_code (c->m_op), rhs_tree);
-	      POP_IGNORE_WFORMAT
+	      dump_tree (pp, lhs_tree);
+	      pp_printf (pp, " %s ", constraint_op_code (c->m_op));
+	      dump_tree (pp, rhs_tree);
 	   }
 	}
 
@@ -3554,10 +3568,7 @@  dump_vec_of_tree (pretty_printer *pp,
     {
       if (i > 0)
 	pp_string (pp, ", ");
-
-      PUSH_IGNORE_WFORMAT
-	pp_printf (pp, "%E", key);
-      POP_IGNORE_WFORMAT
+      dump_tree (pp, key);
     }
   pp_printf (pp, "}: %s", label);
 }
@@ -3610,20 +3621,22 @@  region_model::dump_summary_of_map (pretty_printer *pp,
 	    region_id pointee_rid = region_sval->get_pointee ();
 	    tree pointee = get_representative_path_var (pointee_rid).m_tree;
 	    dump_separator (pp, is_first);
-	    PUSH_IGNORE_WFORMAT
-	      if (pointee)
-		pp_printf (pp, "%E: &%E", key, pointee);
-	      else
-		pp_printf (pp, "%E: NULL", key);
-	    POP_IGNORE_WFORMAT
+	    dump_tree (pp, key);
+	    pp_string (pp, ": ");
+	    if (pointee)
+	      {
+		pp_character (pp, '&');
+		dump_tree (pp, pointee);
+	      }
+	    else
+	      pp_string (pp, "NULL");
 	  }
 	  break;
 	case SK_CONSTANT:
 	  dump_separator (pp, is_first);
-	  PUSH_IGNORE_WFORMAT
-	    pp_printf (pp, "%E: %E", key,
-		       sval->dyn_cast_constant_svalue ()->get_constant ());
-	  POP_IGNORE_WFORMAT
+	  dump_tree (pp, key);
+	  pp_string (pp, ": ");
+	  dump_tree (pp, sval->dyn_cast_constant_svalue ()->get_constant ());
 	  break;
 	case SK_UNKNOWN:
 	  unknown_keys.safe_push (key);
@@ -3637,9 +3650,8 @@  region_model::dump_summary_of_map (pretty_printer *pp,
 	    else
 	      {
 		dump_separator (pp, is_first);
-		PUSH_IGNORE_WFORMAT
-		  pp_printf (pp, "%E: %s", key, poison_kind_to_str (pkind));
-		POP_IGNORE_WFORMAT
+		dump_tree (pp, key);
+		pp_printf (pp, ": %s", poison_kind_to_str (pkind));
 	      }
 	  }
 	  break;
@@ -7787,3 +7799,5 @@  analyzer_region_model_cc_tests ()
 } // namespace selftest
 
 #endif /* CHECKING_P */
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 5cb3a9a15ab3..cf41cd88b6a9 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -21,6 +21,7 @@  along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ANALYZER_REGION_MODEL_H
 #define GCC_ANALYZER_REGION_MODEL_H
 
+#include "sbitmap.h"
 #include "ordered-hash-map.h"
 #include "pretty-print.h"
 #include "selftest.h"
diff --git a/gcc/analyzer/shortest-paths.h b/gcc/analyzer/shortest-paths.h
index 4738f182b854..4dd48367afd3 100644
--- a/gcc/analyzer/shortest-paths.h
+++ b/gcc/analyzer/shortest-paths.h
@@ -69,7 +69,7 @@  shortest_paths<GraphTraits, Path_t>::shortest_paths (const graph_t &graph,
   m_dist (graph.m_nodes.length ()),
   m_prev (graph.m_nodes.length ())
 {
-  auto_client_timevar tv ("shortest_paths");
+  auto_timevar tv (TV_ANALYZER_SHORTEST_PATHS);
 
   auto_vec<int> queue (graph.m_nodes.length ());
 
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index a96971464af7..f7f065429386 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -19,17 +19,21 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
+#include "options.h"
 #include "diagnostic-path.h"
 #include "diagnostic-metadata.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 namespace {
 
 /* A state machine for detecting misuses of <stdio.h>'s FILE * API.  */
@@ -326,3 +330,5 @@  make_fileptr_state_machine (logger *logger)
 {
   return new fileptr_state_machine (logger);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 4253d2b42535..5b3ae1d2d7e4 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -19,17 +19,22 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
+#include "options.h"
+#include "bitmap.h"
 #include "diagnostic-path.h"
 #include "diagnostic-metadata.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 namespace {
 
 ////////////////////////////////////////////////////////////////////////////
@@ -788,3 +793,5 @@  make_malloc_state_machine (logger *logger)
 {
   return new malloc_state_machine (logger);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc
index 746f2fa64d41..b8863120cfe9 100644
--- a/gcc/analyzer/sm-pattern-test.cc
+++ b/gcc/analyzer/sm-pattern-test.cc
@@ -21,10 +21,11 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "tree-pretty-print.h"
 #include "diagnostic-path.h"
@@ -33,6 +34,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 namespace {
 
 /* A state machine for use in DejaGnu tests, to check that
@@ -146,3 +149,5 @@  make_pattern_test_state_machine (logger *logger)
 {
   return new pattern_test_state_machine (logger);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc
index 08b1b32b7933..dfb6a05ef5f0 100644
--- a/gcc/analyzer/sm-sensitive.cc
+++ b/gcc/analyzer/sm-sensitive.cc
@@ -20,17 +20,22 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
+#include "options.h"
 #include "diagnostic-path.h"
 #include "diagnostic-metadata.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 namespace {
 
 /* An experimental state machine, for tracking exposure of sensitive
@@ -192,3 +197,5 @@  make_sensitive_state_machine (logger *logger)
 {
   return new sensitive_state_machine (logger);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index 6b7b5f7b5327..73448db08405 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -21,10 +21,11 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "diagnostic-path.h"
 #include "diagnostic-metadata.h"
@@ -34,6 +35,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 namespace {
 
 /* An experimental state machine, for tracking calls to async-signal-unsafe
@@ -303,3 +306,5 @@  make_signal_state_machine (logger *logger)
 {
   return new signal_state_machine (logger);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index 1c110119b2d6..e4e701213d6e 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -21,17 +21,21 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
+#include "options.h"
 #include "diagnostic-path.h"
 #include "diagnostic-metadata.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/pending-diagnostic.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 namespace {
 
 /* An experimental state machine, for tracking "taint": unsanitized uses
@@ -321,3 +325,5 @@  make_taint_state_machine (logger *logger)
 {
   return new taint_state_machine (logger);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc
index 39360c03f6cc..9822eedc43f2 100644
--- a/gcc/analyzer/sm.cc
+++ b/gcc/analyzer/sm.cc
@@ -19,14 +19,18 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
+#include "options.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/sm.h"
 
+#if ENABLE_ANALYZER
+
 ////////////////////////////////////////////////////////////////////////////
 
 /* If STMT is an assignment to zero, return the LHS.  */
@@ -134,3 +138,5 @@  make_checkers (auto_delete_vec <state_machine> &out, logger *logger)
 					  (*sm)->get_name ()));
     }
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc
index 79eb5549197c..75b8548e4c5d 100644
--- a/gcc/analyzer/state-purge.cc
+++ b/gcc/analyzer/state-purge.cc
@@ -19,23 +19,27 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
 #include "timevar.h"
 #include "tree-ssa-alias.h"
+#include "function.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "stringpool.h"
 #include "tree-vrp.h"
 #include "gimple-ssa.h"
 #include "tree-ssanames.h"
 #include "tree-phinodes.h"
+#include "options.h"
 #include "ssa-iterators.h"
 #include "gimple-pretty-print.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/state-purge.h"
 
+#if ENABLE_ANALYZER
+
 /* state_purge_map's ctor.  Walk all SSA names in all functions, building
    a state_purge_per_ssa_name instance for each.  */
 
@@ -45,7 +49,7 @@  state_purge_map::state_purge_map (const supergraph &sg,
 {
   LOG_FUNC (logger);
 
-  auto_client_timevar tv ("state_purge_map ctor");
+  auto_timevar tv (TV_ANALYZER_STATE_PURGE);
 
   cgraph_node *node;
   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
@@ -519,3 +523,5 @@  state_purge_annotator::add_stmt_annotations (graphviz_out *gv,
   print_vec_of_names (gv, "needed here", needed);
   print_vec_of_names (gv, "not needed here", not_needed);
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index 17cfe5d5f2d7..59c9264d5a08 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -19,7 +19,6 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
@@ -29,6 +28,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "vec.h"
 #include "ggc.h"
 #include "basic-block.h"
+#include "function.h"
 #include "gimple-fold.h"
 #include "tree-eh.h"
 #include "gimple-expr.h"
@@ -41,10 +41,13 @@  along with GCC; see the file COPYING3.  If not see
 #include "graphviz.h"
 #include "cgraph.h"
 #include "tree-dfa.h"
+#include "cfganal.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/supergraph.h"
 #include "analyzer/analyzer-logging.h"
 
+#if ENABLE_ANALYZER
+
 /* Get the cgraph_edge, but only if there's an underlying function body.  */
 
 cgraph_edge *
@@ -70,7 +73,7 @@  supergraph_call_edge (function *fun, gimple *stmt)
 
 supergraph::supergraph (logger *logger)
 {
-  auto_client_timevar tv ("building supergraph");
+  auto_timevar tv (TV_ANALYZER_SUPERGRAPH);
 
   LOG_FUNC (logger);
 
@@ -948,3 +951,5 @@  callgraph_superedge::map_expr_from_callee_to_caller (tree callee_expr,
 
   return NULL_TREE;
 }
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/supergraph.h b/gcc/analyzer/supergraph.h
index a13d6730b3ca..bc7b8d681a56 100644
--- a/gcc/analyzer/supergraph.h
+++ b/gcc/analyzer/supergraph.h
@@ -22,7 +22,11 @@  along with GCC; see the file COPYING3.  If not see
 #define GCC_ANALYZER_SUPERGRAPH_H
 
 #include "ordered-hash-map.h"
+#include "options.h"
 #include "cgraph.h"
+#include "function.h"
+#include "cfg.h"
+#include "basic-block.h"
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "analyzer/digraph.h"
diff --git a/gcc/analyzer/tristate.cc b/gcc/analyzer/tristate.cc
index ac161292f1c4..1875a674eb3f 100644
--- a/gcc/analyzer/tristate.cc
+++ b/gcc/analyzer/tristate.cc
@@ -19,12 +19,13 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
-#include "gcc-plugin.h"
 #include "system.h"
 #include "coretypes.h"
 #include "analyzer/tristate.h"
 #include "selftest.h"
 
+#if ENABLE_ANALYZER
+
 const char *
 tristate::as_string () const
 {
@@ -220,3 +221,5 @@  analyzer_tristate_cc_tests ()
 } // namespace selftest
 
 #endif /* CHECKING_P */
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/common.opt b/gcc/common.opt
index c6512e6ead2e..2e055c5969fc 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -990,7 +990,8 @@  Common Report Var(flag_store_data_races) Optimization
 Allow the compiler to introduce new data races on stores.
 
 fanalyzer
-Driver Var(flag_analyzer)
+Common Var(flag_analyzer)
+Enable static analysis pass.
 
 fargument-alias
 Common Ignore
diff --git a/gcc/configure b/gcc/configure
index 24d27d3e3cba..d5c015e5867c 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -958,6 +958,7 @@  enable_fixed_point
 enable_threads
 enable_tls
 enable_vtable_verify
+enable_analyzer
 enable_objc_gc
 with_dwarf2
 enable_shared
@@ -1685,6 +1686,7 @@  Optional Features:
   --enable-tls            enable or disable generation of tls code overriding
                           the assembler check for tls support
   --enable-vtable-verify  enable vtable verification feature
+  --enable-analyzer       enable -fanalyzer static analyzer
   --enable-objc-gc        enable the use of Boehm's garbage collector with the
                           GNU Objective-C runtime
   --disable-shared        don't provide a shared libgcc
@@ -7703,6 +7705,23 @@  cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# Check whether --enable-analyzer was given.
+if test "${enable_analyzer+set}" = set; then :
+  enableval=$enable_analyzer; if test x$enable_analyzer = xno; then
+	analyzer=0
+else
+	analyzer=1
+fi
+else
+  analyzer=0
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define ENABLE_ANALYZER $analyzer
+_ACEOF
+
+
 # Check whether --enable-objc-gc was given.
 if test "${enable_objc_gc+set}" = set; then :
   enableval=$enable_objc_gc; if test x$enable_objc_gc = xno; then
@@ -18938,7 +18957,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18941 "configure"
+#line 18960 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19044,7 +19063,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 19047 "configure"
+#line 19066 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -31960,7 +31979,7 @@  $as_echo "$as_me: executing $ac_file commands" >&6;}
     "depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;;
     "gccdepdir":C)
   ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR
-  for lang in $subdirs c-family common
+  for lang in $subdirs c-family common analyzer
   do
       ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
   done ;;
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 954c1496fb1c..dcd5e8dd38cc 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -909,6 +909,18 @@  vtable_verify=`if test x$enable_vtable_verify = xyes; then echo 1; else echo 0;
 AC_DEFINE_UNQUOTED(ENABLE_VTABLE_VERIFY, $vtable_verify,
 [Define 0/1 if vtable verification feature is enabled.])
 
+AC_ARG_ENABLE(analyzer,
+[AS_HELP_STRING([--disable-analyzer],
+		[disable -fanalyzer static analyzer])],
+if test x$enable_analyzer = xno; then
+	analyzer=0
+else
+	analyzer=1
+fi,
+analyzer=1)
+AC_DEFINE_UNQUOTED(ENABLE_ANALYZER, $analyzer,
+[Define 0/1 if static analyzer feature is enabled.])
+
 AC_ARG_ENABLE(objc-gc,
 [AS_HELP_STRING([--enable-objc-gc],
 		[enable the use of Boehm's garbage collector with
@@ -1214,7 +1226,7 @@  AC_CHECK_HEADERS(ext/hash_map)
 ZW_CREATE_DEPDIR
 AC_CONFIG_COMMANDS([gccdepdir],[
   ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR
-  for lang in $subdirs c-family common
+  for lang in $subdirs c-family common analyzer
   do
       ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR
   done], [subdirs="$subdirs" ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR])
diff --git a/gcc/gcc.c b/gcc/gcc.c
index d96e568a0b5a..4428d50c3906 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3965,7 +3965,6 @@  driver_handle_option (struct gcc_options *opts,
       add_linker_option ("--target-help", 13);
       break;
 
-    case OPT_fanalyzer:
     case OPT__no_sysroot_suffix:
     case OPT_pass_exit_codes:
     case OPT_print_search_dirs:
@@ -4611,17 +4610,6 @@  process_command (unsigned int decoded_options_count,
 			   CL_DRIVER, &handlers, global_dc);
     }
 
-  if (flag_analyzer)
-    {
-#ifdef ENABLE_ANALYZER
-      save_switch ("-fplugin=analyzer_plugin", 0, NULL, true, true);
-#else
-      sorry ("%qs was not enabled in this build of GCC"
-	     " (missing configure-time option %qs)",
-	     "-fanalyzer", "--enable-plugins=analyzer");
-#endif
-    }
-
   /* If the user didn't specify any, default to all configured offload
      targets.  */
   if (ENABLE_OFFLOADING && offload_targets == NULL)
diff --git a/gcc/passes.def b/gcc/passes.def
index 798a391bd351..0ee8b621016c 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -142,6 +142,7 @@  along with GCC; see the file COPYING3.  If not see
   TERMINATE_PASS_LIST (all_small_ipa_passes)
 
   INSERT_PASSES_AFTER (all_regular_ipa_passes)
+  NEXT_PASS (pass_analyzer);
   NEXT_PASS (pass_ipa_whole_program_visibility);
   NEXT_PASS (pass_ipa_profile);
   NEXT_PASS (pass_ipa_icf);
diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c
index 156575a6695c..883fb104c101 100644
--- a/gcc/selftest-run-tests.c
+++ b/gcc/selftest-run-tests.c
@@ -27,6 +27,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "options.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "analyzer/analyzer-selftests.h"
 
 /* This function needed to be split out from selftest.c as it references
    tests from the whole source tree, and so is within
@@ -115,6 +116,9 @@  selftest::run_tests ()
   /* Run any lang-specific selftests.  */
   lang_hooks.run_lang_selftests ();
 
+  /* Run the analyzer selftests (if enabled).  */
+  run_analyzer_selftests ();
+
   /* Force a GC at the end of the selftests, to shake out GC-related
      issues.  For example, if any GC-managed items have buggy (or missing)
      finalizers, this last collection will ensure that things that were
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 357fcfd65c59..7fca9286d748 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -322,3 +322,14 @@  DEFTIMEVAR (TV_LINK		     , "link JIT code")
 DEFTIMEVAR (TV_LOAD		     , "load JIT result")
 DEFTIMEVAR (TV_JIT_ACQUIRING_MUTEX   , "acquiring JIT mutex")
 DEFTIMEVAR (TV_JIT_CLIENT_CODE   , "JIT client code")
+
+/* Analyzer timevars.  */
+DEFTIMEVAR (TV_ANALYZER              , "analyzer")
+DEFTIMEVAR (TV_ANALYZER_SUPERGRAPH   , "analyzer: supergraph")
+DEFTIMEVAR (TV_ANALYZER_STATE_PURGE  , "analyzer: state purge")
+DEFTIMEVAR (TV_ANALYZER_PLAN         , "analyzer: planning")
+DEFTIMEVAR (TV_ANALYZER_SCC          , "analyzer: scc")
+DEFTIMEVAR (TV_ANALYZER_WORKLIST     , "analyzer: processing worklist")
+DEFTIMEVAR (TV_ANALYZER_DUMP         , "analyzer: dump")
+DEFTIMEVAR (TV_ANALYZER_DIAGNOSTICS  , "analyzer: emitting diagnostics")
+DEFTIMEVAR (TV_ANALYZER_SHORTEST_PATHS, "analyzer: shortest paths")
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index a987661530ea..59a5fa6ad4a5 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -490,6 +490,7 @@  extern simple_ipa_opt_pass *make_pass_build_ssa_passes (gcc::context *ctxt);
 extern simple_ipa_opt_pass *make_pass_local_optimization_passes (gcc::context *ctxt);
 extern simple_ipa_opt_pass *make_pass_ipa_remove_symbols (gcc::context *ctxt);
 
+extern ipa_opt_pass_d *make_pass_analyzer (gcc::context *ctxt);
 extern ipa_opt_pass_d *make_pass_ipa_whole_program_visibility (gcc::context
 							       *ctxt);
 extern simple_ipa_opt_pass *make_pass_ipa_increase_alignment (gcc::context