Index: gcc/doc/plugins.texi
===================================================================
--- gcc/doc/plugins.texi	(revision 175201)
+++ gcc/doc/plugins.texi	(working copy)
@@ -23,10 +23,16 @@ plugins as key-value pairs. Multiple plugins can b
 specifying multiple @option{-fplugin} arguments.
 
 A plugin can be simply given by its short name (no dots or
-slashes). When simply passing @option{-fplugin=@var{name}}, the plugin is
-loaded from the @file{plugin} directory, so @option{-fplugin=@var{name}} is
-the same as @option{-fplugin=`gcc -print-file-name=plugin`/@var{name}.so},
-using backquote shell syntax to query the @file{plugin} directory.
+slashes). When simply passing @option{-fplugin=@var{name}}, the plugin
+is loaded from the @file{plugin} directory, or one of its front-end
+specific subdirectories, so @option{-fplugin=@var{name}} is the same
+as @option{-fplugin=`gcc
+-print-file-name=plugin`/@var{program}/@var{name}.so} or
+@option{-fplugin=`gcc -print-file-name=plugin`/@var{name}.so}, using
+backquote shell syntax to query the @file{plugin} directory, where
+@var{program} is one of @code{cc1}, @code{cc1plus}, @code{lto1} etc.
+Therefore, a plugin can be made available only to some front-ends,
+or can have language-specific variants.
 
 @section Plugin API
 
@@ -207,10 +213,11 @@ For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PL
 and PLUGIN_REGISTER_GGC_CACHES pseudo-events the @code{callback} should be
 null, and the @code{user_data} is specific.
 
-When the PLUGIN_PRAGMAS event is triggered (with a null
-pointer as data from GCC), plugins may register their own pragmas
-using functions like @code{c_register_pragma} or
-@code{c_register_pragma_with_expansion}.
+When the PLUGIN_PRAGMAS event is triggered (with a null pointer as
+data from GCC), plugins may register their own pragmas using functions
+like @code{c_register_pragma} or
+@code{c_register_pragma_with_expansion}. This is not possible in
+plugins run from @code{lto1}.
 
 @section Interacting with the pass manager
 
Index: gcc/plugin.c
===================================================================
--- gcc/plugin.c	(revision 175201)
+++ gcc/plugin.c	(working copy)
@@ -1,5 +1,5 @@
 /* Support for GCC plugin mechanism.
-   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -117,6 +117,12 @@ get_plugin_base_name (const char *full_name)
 }
 
 
+/* FIXME: the ".so" suffix is currently builtin, since plugins
+   only work on ELF host systems like e.g. Linux or Solaris.  
+   When plugins shall be available on non ELF systems such as
+   Windows or MacOS, this code has to be greatly improved.  */
+#define PLUGIN_FILE_SUFFIX ".so"
+
 /* Create a plugin_name_args object for the given plugin and insert it
    to the hash table. This function is called when
    -fplugin=/path/to/NAME.so or -fplugin=NAME option is processed.  */
@@ -140,17 +146,43 @@ add_new_plugin (const char* plugin_name)
 
   if (name_is_short)
     {
+      char *plugpath;
+      char* foundpath = NULL;
       base_name = CONST_CAST (char*, plugin_name);
-      /* FIXME: the ".so" suffix is currently builtin, since plugins
-	 only work on ELF host systems like e.g. Linux or Solaris.
-	 When plugins shall be available on non ELF systems such as
-	 Windows or MacOS, this code has to be greatly improved.  */
-      plugin_name = concat (default_plugin_dir_name (), "/",
-			    plugin_name, ".so", NULL);
-      if (access (plugin_name, R_OK))
-	fatal_error
-	  ("inacessible plugin file %s expanded from short plugin name %s: %m",
-	   plugin_name, base_name);
+
+      /* Look for PLUGINDIR/PROGNAME/NAME.so.  This is useful for
+	 front-end specific plugins.  */
+      if (!foundpath)
+	plugpath = concat (default_plugin_dir_name (), "/",
+			   progname, "/",
+			   plugin_name, PLUGIN_FILE_SUFFIX, NULL);
+      if (!access (plugpath, R_OK))
+	foundpath = plugpath;
+      else
+	free (plugpath);
+      
+      /* Look for PLUGINDIR/NAME.so.  This is useful for plugins
+	 common to all front-ends.  */
+      if (!foundpath)
+	plugpath = concat (default_plugin_dir_name (), "/",
+			   plugin_name, PLUGIN_FILE_SUFFIX, NULL);
+      if (!access (plugpath, R_OK))
+	foundpath = plugpath;
+      else
+	free (plugpath);
+      
+      if (!foundpath)
+	{
+	  inform (UNKNOWN_LOCATION,
+		  "short-named plugin searched in %s/%/ then in %s/",
+		  default_plugin_dir_name (), progname,
+		  default_plugin_dir_name ());
+	  fatal_error
+	    ("no plugin found under %s for %s from short plugin name %s",
+	     default_plugin_dir_name (), progname, base_name);
+	}
+ 
+      plugin_name = foundpath;
     }
   else
     base_name = get_plugin_base_name (plugin_name);
