Skip to content

Commit 97a12b1

Browse files
committed
Merge branch 'main' of github.com:llvm/llvm-project into vloptimizer/dataflow-analysis
2 parents a31269c + 8704e55 commit 97a12b1

File tree

15 files changed

+296
-90
lines changed

15 files changed

+296
-90
lines changed

clang-tools-extra/clangd/ModulesBuilder.cpp

Lines changed: 105 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,13 @@ class FailedPrerequisiteModules : public PrerequisiteModules {
103103
}
104104
};
105105

106-
struct ModuleFile {
106+
/// Represents a reference to a module file (*.pcm).
107+
class ModuleFile {
108+
protected:
107109
ModuleFile(StringRef ModuleName, PathRef ModuleFilePath)
108110
: ModuleName(ModuleName.str()), ModuleFilePath(ModuleFilePath.str()) {}
109111

112+
public:
110113
ModuleFile() = delete;
111114

112115
ModuleFile(const ModuleFile &) = delete;
@@ -128,21 +131,58 @@ struct ModuleFile {
128131
new (this) ModuleFile(std::move(Other));
129132
return *this;
130133
}
131-
132-
~ModuleFile() {
133-
if (!ModuleFilePath.empty() && !DebugModulesBuilder)
134-
llvm::sys::fs::remove(ModuleFilePath);
135-
}
134+
virtual ~ModuleFile() = default;
136135

137136
StringRef getModuleName() const { return ModuleName; }
138137

139138
StringRef getModuleFilePath() const { return ModuleFilePath; }
140139

141-
private:
140+
protected:
142141
std::string ModuleName;
143142
std::string ModuleFilePath;
144143
};
145144

145+
/// Represents a prebuilt module file which is not owned by us.
146+
class PrebuiltModuleFile : public ModuleFile {
147+
private:
148+
// private class to make sure the class can only be constructed by member
149+
// functions.
150+
struct CtorTag {};
151+
152+
public:
153+
PrebuiltModuleFile(StringRef ModuleName, PathRef ModuleFilePath, CtorTag)
154+
: ModuleFile(ModuleName, ModuleFilePath) {}
155+
156+
static std::shared_ptr<PrebuiltModuleFile> make(StringRef ModuleName,
157+
PathRef ModuleFilePath) {
158+
return std::make_shared<PrebuiltModuleFile>(ModuleName, ModuleFilePath,
159+
CtorTag{});
160+
}
161+
};
162+
163+
/// Represents a module file built by us. We're responsible to remove it.
164+
class BuiltModuleFile : public ModuleFile {
165+
private:
166+
// private class to make sure the class can only be constructed by member
167+
// functions.
168+
struct CtorTag {};
169+
170+
public:
171+
BuiltModuleFile(StringRef ModuleName, PathRef ModuleFilePath, CtorTag)
172+
: ModuleFile(ModuleName, ModuleFilePath) {}
173+
174+
static std::shared_ptr<BuiltModuleFile> make(StringRef ModuleName,
175+
PathRef ModuleFilePath) {
176+
return std::make_shared<BuiltModuleFile>(ModuleName, ModuleFilePath,
177+
CtorTag{});
178+
}
179+
180+
virtual ~BuiltModuleFile() {
181+
if (!ModuleFilePath.empty() && !DebugModulesBuilder)
182+
llvm::sys::fs::remove(ModuleFilePath);
183+
}
184+
};
185+
146186
// ReusablePrerequisiteModules - stands for PrerequisiteModules for which all
147187
// the required modules are built successfully. All the module files
148188
// are owned by the modules builder.
@@ -171,9 +211,9 @@ class ReusablePrerequisiteModules : public PrerequisiteModules {
171211
std::string getAsString() const {
172212
std::string Result;
173213
llvm::raw_string_ostream OS(Result);
174-
for (const auto &ModuleFile : RequiredModules) {
175-
OS << "-fmodule-file=" << ModuleFile->getModuleName() << "="
176-
<< ModuleFile->getModuleFilePath() << " ";
214+
for (const auto &MF : RequiredModules) {
215+
OS << "-fmodule-file=" << MF->getModuleName() << "="
216+
<< MF->getModuleFilePath() << " ";
177217
}
178218
return Result;
179219
}
@@ -185,9 +225,9 @@ class ReusablePrerequisiteModules : public PrerequisiteModules {
185225
return BuiltModuleNames.contains(ModuleName);
186226
}
187227

188-
void addModuleFile(std::shared_ptr<const ModuleFile> ModuleFile) {
189-
BuiltModuleNames.insert(ModuleFile->getModuleName());
190-
RequiredModules.emplace_back(std::move(ModuleFile));
228+
void addModuleFile(std::shared_ptr<const ModuleFile> MF) {
229+
BuiltModuleNames.insert(MF->getModuleName());
230+
RequiredModules.emplace_back(std::move(MF));
191231
}
192232

193233
private:
@@ -265,7 +305,7 @@ bool IsModuleFilesUpToDate(
265305

266306
/// Build a module file for module with `ModuleName`. The information of built
267307
/// module file are stored in \param BuiltModuleFiles.
268-
llvm::Expected<ModuleFile>
308+
llvm::Expected<std::shared_ptr<BuiltModuleFile>>
269309
buildModuleFile(llvm::StringRef ModuleName, PathRef ModuleUnitFileName,
270310
const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS,
271311
const ReusablePrerequisiteModules &BuiltModuleFiles) {
@@ -340,7 +380,7 @@ buildModuleFile(llvm::StringRef ModuleName, PathRef ModuleUnitFileName,
340380
ModuleUnitFileName));
341381
}
342382

343-
return ModuleFile{ModuleName, Inputs.CompileCommand.Output};
383+
return BuiltModuleFile::make(ModuleName, Inputs.CompileCommand.Output);
344384
}
345385

346386
bool ReusablePrerequisiteModules::canReuse(
@@ -509,10 +549,51 @@ class ModulesBuilder::ModulesBuilderImpl {
509549
ReusablePrerequisiteModules &BuiltModuleFiles);
510550

511551
private:
552+
/// Try to get prebuilt module files from the compilation database.
553+
void getPrebuiltModuleFile(StringRef ModuleName, PathRef ModuleUnitFileName,
554+
const ThreadsafeFS &TFS,
555+
ReusablePrerequisiteModules &BuiltModuleFiles);
556+
512557
ModuleFileCache Cache;
513558
ModuleNameToSourceCache ProjectModulesCache;
514559
};
515560

561+
void ModulesBuilder::ModulesBuilderImpl::getPrebuiltModuleFile(
562+
StringRef ModuleName, PathRef ModuleUnitFileName, const ThreadsafeFS &TFS,
563+
ReusablePrerequisiteModules &BuiltModuleFiles) {
564+
auto Cmd = getCDB().getCompileCommand(ModuleUnitFileName);
565+
if (!Cmd)
566+
return;
567+
568+
ParseInputs Inputs;
569+
Inputs.TFS = &TFS;
570+
Inputs.CompileCommand = std::move(*Cmd);
571+
572+
IgnoreDiagnostics IgnoreDiags;
573+
auto CI = buildCompilerInvocation(Inputs, IgnoreDiags);
574+
if (!CI)
575+
return;
576+
577+
// We don't need to check if the module files are in ModuleCache or adding
578+
// them to the module cache. As even if the module files are in the module
579+
// cache, we still need to validate them. And it looks not helpful to add them
580+
// to the module cache, since we may always try to get the prebuilt module
581+
// files before building the module files by ourselves.
582+
for (auto &[ModuleName, ModuleFilePath] :
583+
CI->getHeaderSearchOpts().PrebuiltModuleFiles) {
584+
if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName))
585+
continue;
586+
587+
if (IsModuleFileUpToDate(ModuleFilePath, BuiltModuleFiles,
588+
TFS.view(std::nullopt))) {
589+
log("Reusing prebuilt module file {0} of module {1} for {2}",
590+
ModuleFilePath, ModuleName, ModuleUnitFileName);
591+
BuiltModuleFiles.addModuleFile(
592+
PrebuiltModuleFile::make(ModuleName, ModuleFilePath));
593+
}
594+
}
595+
}
596+
516597
llvm::Error ModulesBuilder::ModulesBuilderImpl::getOrBuildModuleFile(
517598
PathRef RequiredSource, StringRef ModuleName, const ThreadsafeFS &TFS,
518599
CachingProjectModules &MDB, ReusablePrerequisiteModules &BuiltModuleFiles) {
@@ -532,6 +613,11 @@ llvm::Error ModulesBuilder::ModulesBuilderImpl::getOrBuildModuleFile(
532613
return llvm::createStringError(
533614
llvm::formatv("Don't get the module unit for module {0}", ModuleName));
534615

616+
/// Try to get prebuilt module files from the compilation database first. This
617+
/// helps to avoid building the module files that are already built by the
618+
/// compiler.
619+
getPrebuiltModuleFile(ModuleName, ModuleUnitFileName, TFS, BuiltModuleFiles);
620+
535621
// Get Required modules in topological order.
536622
auto ReqModuleNames = getAllRequiredModules(RequiredSource, MDB, ModuleName);
537623
for (llvm::StringRef ReqModuleName : ReqModuleNames) {
@@ -551,15 +637,14 @@ llvm::Error ModulesBuilder::ModulesBuilderImpl::getOrBuildModuleFile(
551637

552638
std::string ReqFileName =
553639
MDB.getSourceForModuleName(ReqModuleName, RequiredSource);
554-
llvm::Expected<ModuleFile> MF = buildModuleFile(
640+
llvm::Expected<std::shared_ptr<BuiltModuleFile>> MF = buildModuleFile(
555641
ReqModuleName, ReqFileName, getCDB(), TFS, BuiltModuleFiles);
556642
if (llvm::Error Err = MF.takeError())
557643
return Err;
558644

559-
log("Built module {0} to {1}", ReqModuleName, MF->getModuleFilePath());
560-
auto BuiltModuleFile = std::make_shared<const ModuleFile>(std::move(*MF));
561-
Cache.add(ReqModuleName, BuiltModuleFile);
562-
BuiltModuleFiles.addModuleFile(std::move(BuiltModuleFile));
645+
log("Built module {0} to {1}", ReqModuleName, (*MF)->getModuleFilePath());
646+
Cache.add(ReqModuleName, *MF);
647+
BuiltModuleFiles.addModuleFile(std::move(*MF));
563648
}
564649

565650
return llvm::Error::success();

clang-tools-extra/clangd/unittests/PrerequisiteModulesTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,35 @@ import M;
644644
EXPECT_EQ(CDB.getGlobalScanningCount(), 1u);
645645
}
646646

647+
TEST_F(PrerequisiteModulesTests, PrebuiltModuleFileTest) {
648+
MockDirectoryCompilationDatabase CDB(TestDir, FS);
649+
650+
CDB.addFile("M.cppm", R"cpp(
651+
export module M;
652+
)cpp");
653+
654+
CDB.addFile("U.cpp", R"cpp(
655+
import M;
656+
)cpp");
657+
658+
// Use ModulesBuilder to produce the prebuilt module file.
659+
ModulesBuilder Builder(CDB);
660+
auto ModuleInfo =
661+
Builder.buildPrerequisiteModulesFor(getFullPath("U.cpp"), FS);
662+
HeaderSearchOptions HS(TestDir);
663+
ModuleInfo->adjustHeaderSearchOptions(HS);
664+
665+
CDB.ExtraClangFlags.push_back("-fmodule-file=M=" +
666+
HS.PrebuiltModuleFiles["M"]);
667+
ModulesBuilder Builder2(CDB);
668+
auto ModuleInfo2 =
669+
Builder2.buildPrerequisiteModulesFor(getFullPath("U.cpp"), FS);
670+
HeaderSearchOptions HS2(TestDir);
671+
ModuleInfo2->adjustHeaderSearchOptions(HS2);
672+
673+
EXPECT_EQ(HS.PrebuiltModuleFiles, HS2.PrebuiltModuleFiles);
674+
}
675+
647676
} // namespace
648677
} // namespace clang::clangd
649678

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ Windows Support
391391

392392
LoongArch Support
393393
^^^^^^^^^^^^^^^^^
394+
- Enable linker relaxation by default for loongarch64.
394395

395396
RISC-V Support
396397
^^^^^^^^^^^^^^

clang/lib/Driver/ToolChains/Arch/LoongArch.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,19 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
134134
(!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ)))
135135
Features.push_back("+lsx");
136136

137-
// FIXME: Now we must use -mrelax to enable relax, maybe -mrelax will be set
138-
// as default in the future.
139-
if (const Arg *A =
140-
Args.getLastArg(options::OPT_mrelax, options::OPT_mno_relax)) {
141-
if (A->getOption().matches(options::OPT_mrelax)) {
142-
Features.push_back("+relax");
143-
// -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing
144-
// into .debug_addr, which is currently not implemented.
145-
Arg *A;
146-
if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
147-
D.Diag(
148-
clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
149-
<< A->getAsString(Args);
150-
} else {
151-
Features.push_back("-relax");
152-
}
137+
// -mrelax is default, unless -mno-relax is specified.
138+
// FIXME: Only for loongarch64, loongarch32 has not been fully verified.
139+
if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax,
140+
Triple.isLoongArch64() ? true : false)) {
141+
Features.push_back("+relax");
142+
// -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing
143+
// into .debug_addr, which is currently not implemented.
144+
Arg *A;
145+
if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
146+
D.Diag(clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
147+
<< A->getAsString(Args);
148+
} else if (Args.getLastArg(options::OPT_mno_relax)) {
149+
Features.push_back("-relax");
153150
}
154151

155152
std::string ArchName;

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,8 @@ void ASTDeclMerger::MergeDefinitionData(
21072107
auto *Def = DD.Definition;
21082108
DD = std::move(MergeDD);
21092109
DD.Definition = Def;
2110+
while ((Def = Def->getPreviousDecl()))
2111+
cast<CXXRecordDecl>(Def)->DefinitionData = &DD;
21102112
return;
21112113
}
21122114

clang/test/Driver/loongarch-features.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64
33

44
// LA32: "target-features"="+32bit"
5-
// LA64: "target-features"="+64bit,+d,+f,+lsx,+ual"
5+
// LA64: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"
66

77
int foo(void) {
88
return 3;

clang/test/Driver/loongarch-march.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,39 @@
2121

2222
// CC1-LOONGARCH64: "-target-cpu" "loongarch64"
2323
// CC1-LOONGARCH64-NOT: "-target-feature"
24-
// CC1-LOONGARCH64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual"
24+
// CC1-LOONGARCH64: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual"
2525
// CC1-LOONGARCH64-NOT: "-target-feature"
2626
// CC1-LOONGARCH64: "-target-abi" "lp64d"
2727

2828
// CC1-LA464: "-target-cpu" "la464"
2929
// CC1-LA464-NOT: "-target-feature"
30-
// CC1-LA464: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual"
30+
// CC1-LA464: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual"
3131
// CC1-LA464-NOT: "-target-feature"
3232
// CC1-LA464: "-target-abi" "lp64d"
3333

3434
// CC1-LA64V1P0: "-target-cpu" "loongarch64"
3535
// CC1-LA64V1P0-NOT: "-target-feature"
36-
// CC1-LA64V1P0: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual"
36+
// CC1-LA64V1P0: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual"
3737
// CC1-LA64V1P0-NOT: "-target-feature"
3838
// CC1-LA64V1P0: "-target-abi" "lp64d"
3939

4040
// CC1-LA64V1P1: "-target-cpu" "loongarch64"
4141
// CC1-LA64V1P1-NOT: "-target-feature"
42-
// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+lamcas" "-target-feature" "+ld-seq-sa" "-target-feature" "+div32" "-target-feature" "+scq"
42+
// CC1-LA64V1P1: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+lamcas" "-target-feature" "+ld-seq-sa" "-target-feature" "+div32" "-target-feature" "+scq"
4343
// CC1-LA64V1P1-NOT: "-target-feature"
4444
// CC1-LA64V1P1: "-target-abi" "lp64d"
4545

4646
// CC1-LA664: "-target-cpu" "la664"
4747
// CC1-LA664-NOT: "-target-feature"
48-
// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+lamcas" "-target-feature" "+ld-seq-sa" "-target-feature" "+div32" "-target-feature" "+scq"
48+
// CC1-LA664: "-target-feature" "+relax" "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+lamcas" "-target-feature" "+ld-seq-sa" "-target-feature" "+div32" "-target-feature" "+scq"
4949
// CC1-LA664-NOT: "-target-feature"
5050
// CC1-LA664: "-target-abi" "lp64d"
5151

52-
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual"
53-
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
54-
// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+ual"
55-
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+div32,+frecipe,+lam-bh,+lamcas,+ld-seq-sa,+lsx,+scq,+ual"
56-
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+div32,+f,+frecipe,+lam-bh,+lamcas,+lasx,+ld-seq-sa,+lsx,+scq,+ual"
52+
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+relax,+ual"
53+
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+relax,+ual"
54+
// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+relax,+ual"
55+
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+div32,+frecipe,+lam-bh,+lamcas,+ld-seq-sa,+lsx,+relax,+scq,+ual"
56+
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+div32,+f,+frecipe,+lam-bh,+lamcas,+lasx,+ld-seq-sa,+lsx,+relax,+scq,+ual"
5757

5858
int foo(void) {
5959
return 3;

clang/test/Driver/loongarch-relax-features.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// RUN: not %clang -c --target=loongarch64 -mrelax -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
1818

1919
// LA32: "target-features"="+32bit"
20-
// LA64: "target-features"="+64bit,+d,+f,+lsx,+ual"
20+
// LA64: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"
2121

2222
// LA32-NORELAX: "target-features"="+32bit,-relax"
2323
// LA64-NORELAX: "target-features"="+64bit,+d,+f,+lsx,+ual,-relax"

0 commit comments

Comments
 (0)