[clang] Revert "[Clang][Driver] Final phase also determined by input (#218802)" (PR #225416)
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 22 07:49:35 PDT 2026
https://github.com/nico created https://github.com/llvm/llvm-project/pull/225416
This reverts commit 7987830e776411a0de84c0c75e9f1059acadceb5.
It makes the driver O(n^2) in number of inputs, slowing down some links a lot:
https://github.com/llvm/llvm-project/pull/218802#pullrequestreview-5258702203
>From 8fc4bc5fba5cd1af004a66bd9f49cdc7a1ef1111 Mon Sep 17 00:00:00 2001
From: Nico Weber <thakis at chromium.org>
Date: Sat, 19 Sep 2026 21:10:41 -0400
Subject: [PATCH] Revert "[Clang][Driver] Final phase also determined by input
(#218802)"
This reverts commit 7987830e776411a0de84c0c75e9f1059acadceb5.
---
clang/include/clang/Driver/Driver.h | 1 -
clang/include/clang/Driver/Types.h | 6 ++--
clang/lib/Driver/Driver.cpp | 51 +++++++----------------------
clang/lib/Driver/Types.cpp | 5 ++-
clang/test/Driver/Inputs/object0.o | 0
clang/test/Driver/aix-ld.c | 2 +-
clang/test/Driver/pch-inputs.h | 48 ---------------------------
7 files changed, 18 insertions(+), 95 deletions(-)
delete mode 100644 clang/test/Driver/Inputs/object0.o
delete mode 100644 clang/test/Driver/pch-inputs.h
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index e653d8e3a2dbe..15b6fdcb8a574 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -339,7 +339,6 @@ class Driver {
// modes. Fold this functionality into Types::getCompilationPhases and
// handleArguments.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
- llvm::ArrayRef<InputTy>,
llvm::opt::Arg **FinalPhaseArg = nullptr) const;
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h
index 9ec456773716d..9dd89e1904a4f 100644
--- a/clang/include/clang/Driver/Types.h
+++ b/clang/include/clang/Driver/Types.h
@@ -115,9 +115,9 @@ namespace types {
/// done for type 'Id' up until including LastPhase.
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>
getCompilationPhases(ID Id, phases::ID LastPhase = phases::IfsMerge);
- llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> getCompilationPhases(
- const clang::driver::Driver &Driver, llvm::opt::DerivedArgList &DAL,
- llvm::ArrayRef<std::pair<ID, const llvm::opt::Arg *>> Inputs, ID Id);
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>
+ getCompilationPhases(const clang::driver::Driver &Driver,
+ llvm::opt::DerivedArgList &DAL, ID Id);
/// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
/// C type (used for clang++ emulation of g++ behaviour)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 7a742e404bf5c..de5cb3faa69bb 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -352,10 +352,8 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
// Determine which compilation mode we are in. We look for options which
// affect the phase, starting with the earliest phases, and record which
-// option we used to determine the final phase. In absence of any explicit
-// action command line option, derive the compilation mode from the inputs.
+// option we used to determine the final phase.
phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
- llvm::ArrayRef<InputTy> Inputs,
Arg **FinalPhaseArg) const {
Arg *PhaseArg = nullptr;
phases::ID FinalPhase;
@@ -403,33 +401,9 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
} else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
FinalPhase = phases::IfsMerge;
- // Otherwise autodetect from last phase triggered by input file.
- } else {
- FinalPhase = phases::Preprocess;
- bool AnyPhase = false;
- for (auto &I : Inputs) {
- types::ID InputType = I.first;
- const Arg *InputArg = I.second;
-
- // Linker options should not trigger more phases.
- if (InputArg->getOption().hasFlag(options::LinkerInput))
- continue;
-
- // Relies on the compilation phases being ordered.
- auto PL = types::getCompilationPhases(InputType);
- if (PL.empty())
- continue;
-
- phases::ID LastPL = PL.back();
- if (LastPL > FinalPhase)
- FinalPhase = LastPL;
- AnyPhase = true;
- }
-
- // Fall back to "do everything" when consistency check fails.
- if (!AnyPhase || FinalPhase > phases::Link)
- FinalPhase = phases::Link;
- }
+ // Otherwise do everything.
+ } else
+ FinalPhase = phases::Link;
if (FinalPhaseArg)
*FinalPhaseArg = PhaseArg;
@@ -1875,8 +1849,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs);
if (HasConfigFileTail && Inputs.size()) {
Arg *FinalPhaseArg;
- if (getFinalPhase(*TranslatedArgs, Inputs, &FinalPhaseArg) ==
- phases::Link) {
+ if (getFinalPhase(*TranslatedArgs, &FinalPhaseArg) == phases::Link) {
DerivedArgList TranslatedLinkerIns(*CfgOptionsTail);
for (Arg *A : *CfgOptionsTail)
TranslatedLinkerIns.append(A);
@@ -3461,7 +3434,7 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
}
Arg *FinalPhaseArg;
- phases::ID FinalPhase = getFinalPhase(Args, Inputs, &FinalPhaseArg);
+ phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
if (FinalPhase == phases::Link) {
if (Args.hasArgNoClaim(options::OPT_hipstdpar)) {
@@ -3558,8 +3531,8 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
else
Diag(clang::diag::warn_drv_input_file_unused)
<< InputArg->getAsString(Args) << getPhaseName(InitialPhase)
- << !FinalPhaseArg
- << (FinalPhaseArg ? FinalPhaseArg->getSpelling() : "");
+ << !!FinalPhaseArg
+ << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
continue;
}
@@ -3640,7 +3613,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
C.isOffloadingHostKind(Action::OFK_HIP) && offloadDeviceOnly() &&
Args.hasArg(options::OPT_hip_link) &&
Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false) &&
- getFinalPhase(Args, Inputs) == phases::Link &&
+ getFinalPhase(Args) == phases::Link &&
!Args.hasArg(options::OPT_emit_llvm) &&
Args.hasFlag(options::OPT_gpu_bundle_output,
options::OPT_no_gpu_bundle_output, true);
@@ -3654,7 +3627,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
types::ID InputType = I.first;
const Arg *InputArg = I.second;
- auto PL = types::getCompilationPhases(*this, Args, Inputs, InputType);
+ auto PL = types::getCompilationPhases(*this, Args, InputType);
if (PL.empty())
continue;
@@ -4152,7 +4125,7 @@ Driver::BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args,
// Don't build offloading actions if we do not have a compile action. If
// preprocessing only ignore embedding.
if (!(isa<CompileJobAction>(HostAction) ||
- getFinalPhase(Args, {Input}) == phases::Preprocess))
+ getFinalPhase(Args) == phases::Preprocess))
return HostAction;
bool UsesLLVMOffloading = Args.hasArg(
@@ -4205,7 +4178,7 @@ Driver::BuildOffloadingActions(Compilation &C, llvm::opt::DerivedArgList &Args,
.isOSDarwin())
HostAction->setCannotBeCollapsedWithNextDependentAction();
- auto PL = types::getCompilationPhases(*this, Args, {Input}, InputType);
+ auto PL = types::getCompilationPhases(*this, Args, InputType);
for (phases::ID Phase : PL) {
if (Phase == phases::Link) {
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 618fb402af728..4cca8acd515d7 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -429,9 +429,8 @@ types::getCompilationPhases(ID Id, phases::ID LastPhase) {
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>
types::getCompilationPhases(const clang::driver::Driver &Driver,
- llvm::opt::DerivedArgList &DAL,
- llvm::ArrayRef<InputTy> Inputs, ID Id) {
- return types::getCompilationPhases(Id, Driver.getFinalPhase(DAL, Inputs));
+ llvm::opt::DerivedArgList &DAL, ID Id) {
+ return types::getCompilationPhases(Id, Driver.getFinalPhase(DAL));
}
ID types::lookupCXXTypeForCType(ID Id) {
diff --git a/clang/test/Driver/Inputs/object0.o b/clang/test/Driver/Inputs/object0.o
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/clang/test/Driver/aix-ld.c b/clang/test/Driver/aix-ld.c
index 641908afc8d98..bedd224eeca9c 100644
--- a/clang/test/Driver/aix-ld.c
+++ b/clang/test/Driver/aix-ld.c
@@ -1171,4 +1171,4 @@
// RUN: -K \
// RUN: -c \
// RUN: | FileCheck --check-prefixes=CHECK-K-UNUSED %s
-// CHECK-K-UNUSED: clang: warning: -K: 'linker' input unused when '-c' is present [-Wunused-command-line-argument]
+// CHECK-K-UNUSED: clang: warning: -K: 'linker' input unused [-Wunused-command-line-argument]
diff --git a/clang/test/Driver/pch-inputs.h b/clang/test/Driver/pch-inputs.h
deleted file mode 100644
index fa6f94f996915..0000000000000
--- a/clang/test/Driver/pch-inputs.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir %t
-
-// Warn about linker options being ignored when not linking
-// RUN: %clang %s -lfoo -o %t/tmp1.pch -### 2>&1 | FileCheck %s --check-prefix=UNUSED-L,SINGLEHEADER
-// RUN: %clang %s -x c++-header -lfoo -o %t/tmp1.pch -### 2>&1 | FileCheck %s --check-prefix=UNUSED-L,SINGLEHEADER
-// UNUSED-L: clang: warning: -lfoo: 'linker' input unused [-Wunused-command-line-argument]
-
-// RUN: %clang %s -Wl,--whole-archive -o %t/tmp1.pch -### 2>&1 | FileCheck %s --check-prefix=UNUSED-WL,SINGLEHEADER
-// UNUSED-WL: clang: warning: -Wl,--whole-archive: 'linker' input unused [-Wunused-command-line-argument]
-
-// RUN: %clang %S/Inputs/header1.h %S/Inputs/header2.h -lfoo -### 2>&1 | FileCheck %s --check-prefix=UNUSED-L,MULTIHEADER
-
-
-// Error with single -o when there are multiple output files
-// RUN: not %clang %S/Inputs/header1.h %S/Inputs/header2.h -lfoo -o %t/tmp2.pch -### 2>&1 | FileCheck %s --check-prefix=UNUSED-L,MULTIOUTPUT
-// MULTIOUTPUT: clang: error: cannot specify -o when generating multiple output files
-
-// An actual linker input file (object0.o) triggers an error, not a warning
-// RUN: not %clang %s %S/Inputs/object0.o -o %t/tmp3.pch -### 2>&1 | FileCheck %s --check-prefix=MULTIOUTPUT
-
-// Other input types that do not link
-// RUN: %clang -x cl-header %s -Xlinker -somelinkerflag -### 2>&1 | FileCheck %s --check-prefix=UNUSED-XLINKER
-// RUN: %clang -x objective-c++-header %s -Xlinker -somelinkerflag -### 2>&1 | FileCheck %s --check-prefix=UNUSED-XLINKER
-// RUN: %clang -x hlsl %s -Xlinker -somelinkerflag -### 2>&1 | FileCheck %s --check-prefix=UNUSED-XLINKER
-// UNUSED-XLINKER: clang: warning: -Xlinker -somelinkerflag: 'linker' input unused [-Wunused-command-line-argument]
-
-
-// Normal case: Single header file input compiles to .pch even without --precompile
-// RUN: %clang %s -o %t/tmp1.pch -### 2>&1 | FileCheck %s --check-prefix=SINGLEHEADER
-// SINGLEHEADER: "-cc1"
-// SINGLEHEADER: "-emit-pch"
-// SINGLEHEADER: "-o"
-// SINGLEHEADER: tmp1.pch"
-
-
-// Multiple header files input compiles to one .pch each even without --precompile
-// RUN: %clang %S/Inputs/header1.h %S/Inputs/header2.h -### 2>&1 | FileCheck %s --check-prefix=MULTIHEADER
-// MULTIHEADER: "-cc1"
-// MULTIHEADER: "-emit-pch"
-// MULTIHEADER: "-o"
-// MULTIHEADER: header1.h.pch"
-// MULTIHEADER: "-cc1"
-// MULTIHEADER: "-emit-pch"
-// MULTIHEADER: "-o"
-// MULTIHEADER: header2.h.pch"
-
-
More information about the cfe-commits
mailing list