This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Make decision forest model optional
AbandonedPublic

Authored by mgorny on Nov 22 2022, 1:37 PM.

Details

Summary

Make it possible to disable building the decision forest ranking
model for clangd. This was suggested on D136283 as an alternative
to splitting the huge generated file in order to fix building on PPC32.

Bug: https://bugs.gentoo.org/829602

Diff Detail

Event Timeline

mgorny created this revision.Nov 22 2022, 1:37 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 22 2022, 1:37 PM
mgorny requested review of this revision.Nov 22 2022, 1:37 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 22 2022, 1:37 PM

@thesamesam, could you test it on PPC32, please?

Works on PPC.

Arfrever added a subscriber: Arfrever.EditedNov 25 2022, 7:42 PM

In clang-tools-extra/clangd/unittests/CMakeLists.txt, usage of CompletionModel.cmake probably also should be dependent on CLANGD_DECISION_FOREST.

In clang-tools-extra/clangd/CMakeLists.txt and clang-tools-extra/clangd/unittests/CMakeLists.txt, calls to target_include_directories() for directories with generated Completion Model headers can be also made dependent on CLANGD_DECISION_FOREST.

--- clang-tools-extra/clangd/CMakeLists.txt
+++ clang-tools-extra/clangd/CMakeLists.txt
@@ -146,10 +146,12 @@
   omp_gen
   )
 
-# Include generated CompletionModel headers.
-target_include_directories(clangDaemon PUBLIC
-  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-)
+if(CLANGD_DECISION_FOREST)
+  # Include generated Completion Model header.
+  target_include_directories(clangDaemon PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+  )
+endif()
 
 clang_target_link_libraries(clangDaemon
   PRIVATE
--- clang-tools-extra/clangd/unittests/CMakeLists.txt
+++ clang-tools-extra/clangd/unittests/CMakeLists.txt
@@ -19,8 +19,12 @@
   set(REMOTE_TEST_SOURCES remote/MarshallingTests.cpp)
 endif()
 
-include(${CMAKE_CURRENT_SOURCE_DIR}/../quality/CompletionModel.cmake)
-gen_decision_forest(${CMAKE_CURRENT_SOURCE_DIR}/decision_forest_model DecisionForestRuntimeTest ::ns1::ns2::test::Example)
+set(DECISIONFORESTRUNTIMETEST_SOURCES)
+if(CLANGD_DECISION_FOREST)
+  include(${CMAKE_CURRENT_SOURCE_DIR}/../quality/CompletionModel.cmake)
+  gen_decision_forest(${CMAKE_CURRENT_SOURCE_DIR}/decision_forest_model DecisionForestRuntimeTest ::ns1::ns2::test::Example)
+  list(APPEND DECISIONFORESTRUNTIMETEST_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/DecisionForestRuntimeTest.cpp)
+endif()
 
 add_custom_target(ClangdUnitTests)
 add_unittest(ClangdUnitTests ClangdTests
@@ -95,7 +99,7 @@
   TypeHierarchyTests.cpp
   URITests.cpp
   XRefsTests.cpp
-  ${CMAKE_CURRENT_BINARY_DIR}/DecisionForestRuntimeTest.cpp
+  ${DECISIONFORESTRUNTIMETEST_SOURCES}
 
   support/CancellationTests.cpp
   support/ContextTests.cpp
@@ -134,10 +138,12 @@
   $<TARGET_OBJECTS:obj.clangDaemonTweaks>
   )
 
-# Include generated ComletionModel headers.
-target_include_directories(ClangdTests PUBLIC
-  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-)
+if(CLANGD_DECISION_FOREST)
+  # Include generated Completion Model header.
+  target_include_directories(ClangdTests PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+  )
+endif()
 
 clang_target_link_libraries(ClangdTests
   PRIVATE

(Above patch also fixes typo in Comletion and fixes grammatical number of headers to singular header, since there is only 1 generated Completion Model header in each of those directories.)

nridge added a subscriber: nridge.Nov 26 2022, 10:50 PM

Thanks for doing this!

clang-tools-extra/clangd/CMakeLists.txt
52

Rather than add_definitions, could you instead add a line to clangd/Features.inc.in, and #include Features.h where needed?

There are probably tradeoffs between these approaches, but that's the one we're using for other optional features.

We also use #if rather than #if defined() which ensures we're not forgetting to include a definition and getting some default behavior.

clang-tools-extra/clangd/CodeComplete.h
129

this approach feels a bit heavy on the preprocessor, especially for a header.
It makes the decision-forest-less version seem "complete" but at the cost of having to understand two variants of the code.

what about:

  • keeping all the existing APIs
  • using #if to change the default value of RankingModel, but otherwise leaving this struct unchanged
  • providing an alternate definition of evaluateDecisionForest that just calls std::abort()
  • having ClangdMain exit with an error if DecisionForest is selected and not enabled (or simply ignoring the flag)
mgorny added inline comments.Nov 28 2022, 5:38 AM
clang-tools-extra/clangd/CodeComplete.h
129

This is what I originally wanted to do. However, it doesn't seem that this code path is covered by the test suite and I have no clue how to use clangd (or at least the test suite didn't see it crash when I added fatal asserts to the decision forest paths), so I've decided that ensure compile-time failures is the safer approach.

sammccall added inline comments.
clang-tools-extra/clangd/CodeComplete.h
129

When I add std::abort() to evaluateDecisionForest then I see lots of failed tests:

********************
Failed Tests (69):
  Clangd :: completion-auto-trigger.test
  Clangd :: completion-snippets.test
  Clangd :: completion.test
  Clangd :: protocol.test
  Clangd Unit Tests :: ./ClangdTests/0/73
...
  Clangd Unit Tests :: ./ClangdTests/9/73


Testing Time: 4.22s
  Unsupported:   7
  Passed     : 193
  Failed     :  69

The compile-time failures may be safer in some ways, but I think this use of preprocessor is more intrusive than we'd like to to maintain to work around toolchain limitations on a platform where (AFAIK) we don't have any actual users.
(i.e. even if the runtime behavior were untested, that is probably still preferable)

mgorny abandoned this revision.Dec 1 2022, 6:28 AM

Closing in favor of D139107.