diff --git a/src/implicit.c b/src/implicit.c
index 3c7fba7..8106546 100644
--- a/src/implicit.c
+++ b/src/implicit.c
@@ -54,6 +54,9 @@ try_implicit_rule (struct file *file, unsigned int depth)
            _("Looking for archive-member implicit rule for '%s'.\n"));
       if (pattern_search (file, 1, depth, 0))
         return 1;
+      DBS (DB_IMPLICIT,
+           (_("No archive-member implicit rule found for '%s'.\n"),
+            file->name));
     }
 #endif
 
@@ -309,7 +312,9 @@ pattern_search (struct file *file, int archive,
          don't use it here.  */
       if (rule->in_use)
         {
-          DBS (DB_IMPLICIT, (_("Avoiding implicit rule recursion.\n")));
+          DBS (DB_IMPLICIT,
+               (_("Avoiding implicit rule recursion for rule '%s'.\n"),
+                rule->name));
           continue;
         }
 
@@ -432,6 +437,8 @@ pattern_search (struct file *file, int archive,
   for (intermed_ok = 0; intermed_ok < 2; ++intermed_ok)
     {
       pat = deplist;
+      if (intermed_ok)
+        DBS (DB_IMPLICIT, (_("Trying harder.\n")));
 
       /* Try each pattern rule till we find one that applies.  If it does,
          expand its dependencies (as substituted) and chain them in DEPS.  */
@@ -480,6 +487,10 @@ pattern_search (struct file *file, int archive,
                 }
             }
 
+          DBS (DB_IMPLICIT,
+               (_("Trying pattern rule '%s' with stem '%.*s'.\n"),
+                rule->name, (int) stemlen, stem));
+
           if (stemlen + (check_lastslash ? pathlen : 0) > GET_PATH_MAX)
             {
               DBS (DB_IMPLICIT, (_("Stem too long: '%s%.*s'.\n"),
@@ -488,9 +499,6 @@ pattern_search (struct file *file, int archive,
               continue;
             }
 
-          DBS (DB_IMPLICIT, (_("Trying pattern rule with stem '%.*s'.\n"),
-                             (int) stemlen, stem));
-
           if (!check_lastslash)
             {
               memcpy (stem_str, stem, stemlen);
@@ -722,9 +730,9 @@ pattern_search (struct file *file, int archive,
                          then the rule fails.  Don't bother trying it on the
                          second pass either since we know that will fail.  */
                       DBS (DB_IMPLICIT,
-                           (is_rule
-                            ? _("Rejecting impossible rule prerequisite '%s'.\n")
-                            : _("Rejecting impossible implicit prerequisite '%s'.\n"),
+                           (_("Rejecting rule '%s' due to impossible '%s' "
+                                                       "prerequisite '%s'.\n"),
+                            rule->name, is_rule ? "rule" : "implicit",
                             d->name));
                       tryrules[ri].rule = 0;
 
@@ -745,15 +753,9 @@ pattern_search (struct file *file, int archive,
                   /* If this prereq is also explicitly mentioned for FILE,
                      skip all tests below since it must be built no matter
                      which implicit rule we choose. */
-
                   for (expl_d = file->deps; expl_d != 0; expl_d = expl_d->next)
                     if (streq (dep_name (expl_d), d->name))
                       break;
-                  if (expl_d != 0)
-                    {
-                      (pat++)->name = d->name;
-                      continue;
-                    }
 
                   /* f->is_explicit is set when this file is mentioned
                     explicitly on some other rule.  d->is_explicit is set when
@@ -762,20 +764,33 @@ pattern_search (struct file *file, int archive,
                   if (f && !f->is_explicit && !d->is_explicit)
                     f->intermediate = 1;
 
+                  /* @@ dep->changed check is disabled. */
+                  if (expl_d != 0 || f)
+                    {
+                      (pat++)->name = d->name;
+                      DBS (DB_IMPLICIT, (_("'%s' ought to exist.\n"), d->name));
+                      continue;
+                    }
+                  if (file_exists_p (d->name))
+                    {
+                      (pat++)->name = d->name;
+                      DBS (DB_IMPLICIT, (_("Found '%s'.\n"), d->name));
+                      continue;
+                    }
+
                   /* The DEP->changed flag says that this dependency resides
                      in a nonexistent directory.  So we normally can skip
                      looking for the file.  However, if CHECK_LASTSLASH is
                      set, then the dependency file we are actually looking for
                      is in a different directory (the one gotten by prepending
                      FILENAME's directory), so it might actually exist.  */
-
-                  /* @@ dep->changed check is disabled. */
-                  if (f /* || ((!dep->changed || check_lastslash) */
-                      || file_exists_p (d->name))
+                  /*
+                  if (!dep->changed || check_lastslash)
                     {
                       (pat++)->name = d->name;
                       continue;
                     }
+                  */
 
                   /* This code, given FILENAME = "lib/foo.o", dependency name
                      "lib/foo.c", and VPATH=src, searches for
@@ -785,7 +800,7 @@ pattern_search (struct file *file, int archive,
                     if (vname)
                       {
                         DBS (DB_IMPLICIT,
-                             (_("Found prerequisite '%s' as VPATH '%s'\n"),
+                             (_("Found prerequisite '%s' as VPATH '%s'.\n"),
                               d->name, vname));
                         (pat++)->name = d->name;
                         continue;
@@ -833,6 +848,14 @@ pattern_search (struct file *file, int archive,
 
                   /* A dependency of this rule does not exist. Therefore, this
                      rule fails.  */
+                  if (intermed_ok)
+                    DBS (DB_IMPLICIT,
+                         (_("Rejecting rule '%s' "
+                                     "due to impossible prerequisite '%s'.\n"),
+                          rule->name, d->name));
+                  else
+                    DBS (DB_IMPLICIT, (_("Not found '%s'.\n"), d->name));
+
                   failed = 1;
                   break;
                 }
@@ -1042,5 +1065,11 @@ pattern_search (struct file *file, int archive,
   free (tryrules);
   free (deplist);
 
+  if (rule)
+    DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
+                       rule->name, filename));
+  else
+    DBS (DB_IMPLICIT, (_("No implicit rule found for '%s'.\n"), filename));
+
   return rule != 0;
 }
diff --git a/src/job.c b/src/job.c
index ee59b95..d6e28d3 100644
--- a/src/job.c
+++ b/src/job.c
@@ -2391,7 +2391,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
           }
       }
 
-    cmd = (char *)find_in_given_path (argv[0], p, NULL, 0);
+    cmd = (char *)find_in_given_path (argv[0], p, 0);
   }
 
   if (!cmd)
diff --git a/src/remake.c b/src/remake.c
index 9b71ce6..bd6d8e5 100644
--- a/src/remake.c
+++ b/src/remake.c
@@ -509,10 +509,7 @@ update_file_1 (struct file *file, unsigned int depth)
 
   if (!file->phony && file->cmds == 0 && !file->tried_implicit)
     {
-      if (try_implicit_rule (file, depth))
-        DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
-      else
-        DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
+      try_implicit_rule (file, depth);
       file->tried_implicit = 1;
     }
   if (file->cmds == 0 && !file->is_target
@@ -1045,10 +1042,7 @@ check_dep (struct file *file, unsigned int depth,
 
       if (!file->phony && file->cmds == 0 && !file->tried_implicit)
         {
-          if (try_implicit_rule (file, depth))
-            DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
-          else
-            DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
+          try_implicit_rule (file, depth);
           file->tried_implicit = 1;
         }
       if (file->cmds == 0 && !file->is_target
diff --git a/src/rule.c b/src/rule.c
index 7efca58..6aed6f0 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -59,6 +59,61 @@ struct file *suffix_file;
 /* Maximum length of a suffix.  */
 
 static size_t maxsuffix;
+
+/* Copy N bytes from SRC to DST. Return DST + N.  */
+
+static
+void *mymempcpy (void *dst, const void *src, size_t n)
+{
+    memcpy (dst, src, n);
+    return (char *) dst + n;
+}
+
+/* Init rule name with space separated rule targets, followed by either a colon
+ * or two colons in the case of a terminal rule, followed by space separated
+ * rule prerequisites, followed by a pipe, followed by order-only
+ * prerequisites, if present.  */
+
+static
+void init_rule_name (struct rule *r)
+{
+  unsigned int k;
+  ptrdiff_t len = 8; // Reserve for ":: ", " | " and the null terminator.
+  char *p;
+  const char *sep = "";
+  const struct dep *dep, *ood = 0;
+
+  for (k = 0; k < r->num; ++k)
+    len += r->lens[k] + 1; // Add one for a space.
+
+  for (dep = r->deps; dep; dep = dep->next)
+    len += strlen (dep_name (dep)) + 1; // Add one for a space.
+
+  p = r->name = xmalloc (len);
+  for (k = 0; k < r->num; ++k, sep = " ")
+    p = mymempcpy (mymempcpy (p, sep, strlen (sep)),
+                   r->targets[k], r->lens[k]);
+  *p++ = ':';
+  if (r->terminal)
+    *p++ = ':';
+
+  /* Copy all normal dependencies; note any order-only deps.  */
+  for (dep = r->deps; dep; dep = dep->next)
+    if (dep->ignore_mtime == 0)
+      p = mymempcpy (mymempcpy (p, " ", 1),
+                     dep_name (dep), strlen (dep_name (dep)));
+    else if (ood == 0)
+      ood = dep;
+
+  /* Copy order-only deps, if we have any.  */
+  for (sep = " | "; ood; ood = ood->next, sep = " ")
+    if (ood->ignore_mtime)
+      p = mymempcpy (mymempcpy (p, sep, strlen (sep)),
+                     dep_name (ood), strlen (dep_name (ood)));
+  *p = '\0';
+  assert (p - r->name < len);
+}
+
 
 /* Compute the maximum dependency length and maximum number of dependencies of
    all implicit rules.  Also sets the subdir flag for a rule when appropriate,
@@ -160,6 +215,9 @@ snap_implicit_rules (void)
 
   free (name);
   free_dep_chain (prereqs);
+
+  for (rule = pattern_rules; rule; rule = rule->next)
+    init_rule_name (rule);
 }
 
 /* Create a pattern rule from a suffix rule.
@@ -398,6 +456,7 @@ install_pattern_rule (struct pspec *p, int terminal)
   r->targets = xmalloc (sizeof (const char *));
   r->suffixes = xmalloc (sizeof (const char *));
   r->lens = xmalloc (sizeof (unsigned int));
+  r->name = 0;
 
   r->lens[0] = (unsigned int) strlen (p->target);
   r->targets[0] = p->target;
@@ -439,6 +498,7 @@ freerule (struct rule *rule, struct rule *lastrule)
   free ((void *)rule->targets);
   free ((void *)rule->suffixes);
   free (rule->lens);
+  free ((void *) rule->name);
 
   /* We can't free the storage for the commands because there
      are ways that they could be in more than one place:
@@ -488,6 +548,7 @@ create_pattern_rule (const char **targets, const char **target_percents,
   r->targets = targets;
   r->suffixes = target_percents;
   r->lens = xmalloc (n * sizeof (unsigned int));
+  r->name = 0;
 
   for (i = 0; i < n; ++i)
     {
@@ -505,18 +566,7 @@ create_pattern_rule (const char **targets, const char **target_percents,
 static void                     /* Useful to call from gdb.  */
 print_rule (struct rule *r)
 {
-  unsigned int i;
-
-  for (i = 0; i < r->num; ++i)
-    {
-      fputs (r->targets[i], stdout);
-      putchar ((i + 1 == r->num) ? ':' : ' ');
-    }
-  if (r->terminal)
-    putchar (':');
-
-  print_prereqs (r->deps);
-
+  printf("%s\n", r->name);
   if (r->cmds != 0)
     print_commands (r->cmds);
 }
diff --git a/src/rule.h b/src/rule.h
index 120a682..019c746 100644
--- a/src/rule.h
+++ b/src/rule.h
@@ -25,6 +25,7 @@ struct rule
     const char **suffixes;      /* Suffixes (after '%') of each target.  */
     struct dep *deps;           /* Dependencies of the rule.  */
     struct commands *cmds;      /* Commands to execute.  */
+    char *name;                 /* Name of the rule. */
     unsigned short num;         /* Number of targets.  */
     char terminal;              /* If terminal (double-colon).  */
     char in_use;                /* If in use by a parent pattern_search.  */
