Fix 'comp--func-unique-in-cu-p' to match docstring

* lisp/emacs-lisp/comp.el (comp--func-unique-in-cu-p): Check
only the callee name instead of requiring global uniqueness.
* test/src/comp-resources/comp-test-direct-call.el: New file.
* test/src/comp-resources/comp-test-direct-call-dup.el: New file.
* test/src/comp-tests.el (comp-tests-has-direct-call-p)
(comp-tests-direct-call-with-lambdas)
(comp-tests-direct-call-with-duplicate-names): New tests.
This commit is contained in:
Julian Scheid
2026-03-12 09:07:08 +01:00
committed by Andrea Corallo
parent d019b5ec71
commit f15ad18a14
4 changed files with 132 additions and 6 deletions

View File

@@ -606,12 +606,9 @@ In use by the back-end."
(defun comp--func-unique-in-cu-p (func)
"Return t if FUNC is known to be unique in the current compilation unit."
(if (symbolp func)
(cl-loop with h = (make-hash-table :test #'eq)
for f being the hash-value in (comp-ctxt-funcs-h comp-ctxt)
for name = (comp-func-name f)
when (gethash name h)
return nil
do (puthash name t h)
(cl-loop for f being the hash-value in (comp-ctxt-funcs-h comp-ctxt)
count (eq func (comp-func-name f)) into n
when (> n 1) return nil
finally return t)
t))

View File

@@ -0,0 +1,41 @@
;;; comp-test-direct-call-dup.el --- test direct calls with duplicate names -*- lexical-binding: t; -*-
;; Copyright (C) 2026 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs 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 of the License, or
;; (at your option) any later version.
;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Test that a duplicated function name only suppresses direct calls
;; to that name, not to other unique functions in the same CU.
;; See `comp--func-unique-in-cu-p'.
;;; Code:
;; Duplicate name -- calls to this should NOT be direct.
(defun comp-tests-dup-f (x) (1+ x))
(defun comp-tests-dup-f (x) (+ x 2))
;; Unique callee.
(defun comp-tests-unique-f (x) (* x 2))
;; Call to unique callee -- should be a direct call.
(defun comp-tests-calls-unique-f (x) (comp-tests-unique-f x))
;; Call to ambiguous callee -- should NOT be a direct call.
(defun comp-tests-calls-dup-f (x) (comp-tests-dup-f x))
;;; comp-test-direct-call-dup.el ends here

View File

@@ -0,0 +1,42 @@
;;; comp-test-direct-call.el --- compilation unit tested by comp-tests.el -*- lexical-binding: t; -*-
;; Copyright (C) 2026 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
;; GNU Emacs 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 of the License, or
;; (at your option) any later version.
;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Test that anonymous lambdas in a compilation unit don't prevent
;; direct calls between named functions at speed 3.
;; See `comp--func-unique-in-cu-p'.
;;; Code:
(defun comp-tests-direct-call-callee-f (x)
(1+ x))
(defun comp-tests-direct-call-caller-f (x)
(comp-tests-direct-call-callee-f x))
;; Two anonymous lambdas -- these must not prevent direct calls
;; between the named functions above.
(defvar comp-tests-direct-call-list1
(mapcar (lambda (x) (1+ x)) '(1 2 3)))
(defvar comp-tests-direct-call-list2
(mapcar (lambda (x) (1- x)) '(1 2 3)))
;;; comp-test-direct-call.el ends here

View File

@@ -1612,4 +1612,50 @@ folded."
t)
(native-compile #'comp-tests-type-branch-optim-1-f)))
(defun comp-tests-has-direct-call-p (func-name)
"Return non-nil if FUNC-NAME contains a direct call instruction."
(cl-some
#'identity
(comp-tests-map-checker
func-name
(lambda (insn)
(or (comp-tests-mentioned-p 'direct-call insn)
(comp-tests-mentioned-p 'direct-callref insn))))))
(comp-deftest direct-call-with-lambdas ()
"Check that anonymous lambdas don't prevent direct calls at speed 3.
See `comp--func-unique-in-cu-p'."
(let ((native-comp-speed 3)
(comp-post-pass-hooks
'((comp--final
(lambda (_)
(should (comp-tests-has-direct-call-p
'comp-tests-direct-call-caller-f)))))))
(load (native-compile
(ert-resource-file "comp-test-direct-call.el")))
(declare-function comp-tests-direct-call-caller-f nil)
(should (native-comp-function-p
(symbol-function 'comp-tests-direct-call-caller-f)))
(should (= (comp-tests-direct-call-caller-f 3) 4))))
(comp-deftest direct-call-with-duplicate-names ()
"Check that duplicate names only block their own direct calls.
See `comp--func-unique-in-cu-p'."
(let ((native-comp-speed 3)
(comp-post-pass-hooks
'((comp--final
(lambda (_)
;; Call to unique callee: SHOULD use direct call.
(should (comp-tests-has-direct-call-p
'comp-tests-calls-unique-f))
;; Call to ambiguous callee: should NOT.
(should-not (comp-tests-has-direct-call-p
'comp-tests-calls-dup-f)))))))
(load (native-compile
(ert-resource-file "comp-test-direct-call-dup.el")))
(declare-function comp-tests-calls-unique-f nil)
(should (native-comp-function-p
(symbol-function 'comp-tests-calls-unique-f)))
(should (= (comp-tests-calls-unique-f 3) 6))))
;;; comp-tests.el ends here