Skip to content

Commit ccb4647

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merge llvm/main into amd-debug
2 parents 8fbff38 + dbf34e5 commit ccb4647

File tree

137 files changed

+1084
-1285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+1084
-1285
lines changed

clang/include/clang/Interpreter/Interpreter.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class ThreadSafeContext;
3737
namespace clang {
3838

3939
class CompilerInstance;
40-
class CodeGenerator;
4140
class CXXRecordDecl;
4241
class Decl;
4342
class IncrementalExecutor;
@@ -110,10 +109,6 @@ class Interpreter {
110109
// printing happens, it's in an invalid state.
111110
Value LastValue;
112111

113-
/// When CodeGen is created the first llvm::Module gets cached in many places
114-
/// and we must keep it alive.
115-
std::unique_ptr<llvm::Module> CachedInCodeGenModule;
116-
117112
/// Compiler instance performing the incremental compilation.
118113
std::unique_ptr<CompilerInstance> CI;
119114

@@ -175,15 +170,9 @@ class Interpreter {
175170
llvm::Expected<llvm::orc::ExecutorAddr>
176171
getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;
177172

178-
std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr);
179-
PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
180-
std::unique_ptr<llvm::Module> M = {},
181-
IncrementalAction *Action = nullptr);
182-
183173
private:
184174
size_t getEffectivePTUSize() const;
185175
void markUserCodeStart();
186-
llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E);
187176

188177
// A cache for the compiled destructors used to for de-allocation of managed
189178
// clang::Values.
@@ -206,11 +195,6 @@ class Interpreter {
206195
// This function forces emission of the needed dtor.
207196
llvm::Expected<llvm::orc::ExecutorAddr>
208197
CompileDtorCall(CXXRecordDecl *CXXRD) const;
209-
210-
/// @}
211-
/// @name Code generation
212-
/// @{
213-
CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const;
214198
};
215199
} // namespace clang
216200

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,12 +2505,8 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
25052505
}
25062506

25072507
// Check if we're currently running an initializer.
2508-
for (InterpFrame *Frame = S.Current; Frame; Frame = Frame->Caller) {
2509-
if (const Function *F = Frame->getFunction();
2510-
F && F->isConstructor() && Frame->getThis().block() == Ptr.block()) {
2511-
return Error(2);
2512-
}
2513-
}
2508+
if (llvm::is_contained(S.InitializingBlocks, Ptr.block()))
2509+
return Error(2);
25142510
if (S.EvaluatingDecl && Ptr.getDeclDesc()->asVarDecl() == S.EvaluatingDecl)
25152511
return Error(2);
25162512

clang/lib/Interpreter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ endif()
2222
add_clang_library(clangInterpreter
2323
DeviceOffload.cpp
2424
CodeCompletion.cpp
25+
IncrementalAction.cpp
2526
IncrementalExecutor.cpp
2627
IncrementalParser.cpp
2728
Interpreter.cpp

clang/lib/Interpreter/DeviceOffload.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ namespace clang {
2626

2727
IncrementalCUDADeviceParser::IncrementalCUDADeviceParser(
2828
CompilerInstance &DeviceInstance, CompilerInstance &HostInstance,
29+
IncrementalAction *DeviceAct,
2930
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS,
30-
llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs)
31-
: IncrementalParser(DeviceInstance, Err), PTUs(PTUs), VFS(FS),
31+
llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs)
32+
: IncrementalParser(DeviceInstance, DeviceAct, Err, PTUs), VFS(FS),
3233
CodeGenOpts(HostInstance.getCodeGenOpts()),
3334
TargetOpts(DeviceInstance.getTargetOpts()) {
3435
if (Err)

clang/lib/Interpreter/DeviceOffload.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ struct PartialTranslationUnit;
2222
class CompilerInstance;
2323
class CodeGenOptions;
2424
class TargetOptions;
25+
class IncrementalAction;
2526

2627
class IncrementalCUDADeviceParser : public IncrementalParser {
27-
const std::list<PartialTranslationUnit> &PTUs;
2828

2929
public:
3030
IncrementalCUDADeviceParser(
3131
CompilerInstance &DeviceInstance, CompilerInstance &HostInstance,
32+
IncrementalAction *DeviceAct,
3233
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS,
33-
llvm::Error &Err, const std::list<PartialTranslationUnit> &PTUs);
34+
llvm::Error &Err, std::list<PartialTranslationUnit> &PTUs);
3435

3536
// Generate PTX for the last PTU.
3637
llvm::Expected<llvm::StringRef> GeneratePTX();
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "IncrementalAction.h"
10+
11+
#include "clang/AST/ASTConsumer.h"
12+
#include "clang/CodeGen/CodeGenAction.h"
13+
#include "clang/CodeGen/ModuleBuilder.h"
14+
#include "clang/Frontend/CompilerInstance.h"
15+
#include "clang/Frontend/FrontendOptions.h"
16+
#include "clang/FrontendTool/Utils.h"
17+
#include "clang/Interpreter/Interpreter.h"
18+
#include "clang/Lex/PreprocessorOptions.h"
19+
#include "clang/Sema/Sema.h"
20+
#include "llvm/IR/Module.h"
21+
#include "llvm/Support/Error.h"
22+
#include "llvm/Support/ErrorHandling.h"
23+
24+
namespace clang {
25+
IncrementalAction::IncrementalAction(CompilerInstance &CI,
26+
llvm::LLVMContext &LLVMCtx,
27+
llvm::Error &Err, Interpreter &I,
28+
std::unique_ptr<ASTConsumer> Consumer)
29+
: WrapperFrontendAction([&]() {
30+
llvm::ErrorAsOutParameter EAO(&Err);
31+
std::unique_ptr<FrontendAction> Act;
32+
switch (CI.getFrontendOpts().ProgramAction) {
33+
default:
34+
Err = llvm::createStringError(
35+
std::errc::state_not_recoverable,
36+
"Driver initialization failed. "
37+
"Incremental mode for action %d is not supported",
38+
CI.getFrontendOpts().ProgramAction);
39+
return Act;
40+
case frontend::ASTDump:
41+
case frontend::ASTPrint:
42+
case frontend::ParseSyntaxOnly:
43+
Act = CreateFrontendAction(CI);
44+
break;
45+
case frontend::PluginAction:
46+
case frontend::EmitAssembly:
47+
case frontend::EmitBC:
48+
case frontend::EmitObj:
49+
case frontend::PrintPreprocessedInput:
50+
case frontend::EmitLLVMOnly:
51+
Act.reset(new EmitLLVMOnlyAction(&LLVMCtx));
52+
break;
53+
}
54+
return Act;
55+
}()),
56+
Interp(I), CI(CI), Consumer(std::move(Consumer)) {}
57+
58+
std::unique_ptr<ASTConsumer>
59+
IncrementalAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
60+
std::unique_ptr<ASTConsumer> C =
61+
WrapperFrontendAction::CreateASTConsumer(CI, InFile);
62+
63+
if (Consumer) {
64+
std::vector<std::unique_ptr<ASTConsumer>> Cs;
65+
Cs.push_back(std::move(Consumer));
66+
Cs.push_back(std::move(C));
67+
return std::make_unique<MultiplexConsumer>(std::move(Cs));
68+
}
69+
70+
return std::make_unique<InProcessPrintingASTConsumer>(std::move(C), Interp);
71+
}
72+
73+
void IncrementalAction::ExecuteAction() {
74+
WrapperFrontendAction::ExecuteAction();
75+
getCompilerInstance().getSema().CurContext = nullptr;
76+
}
77+
78+
void IncrementalAction::EndSourceFile() {
79+
if (IsTerminating && getWrapped())
80+
WrapperFrontendAction::EndSourceFile();
81+
}
82+
83+
void IncrementalAction::FinalizeAction() {
84+
assert(!IsTerminating && "Already finalized!");
85+
IsTerminating = true;
86+
EndSourceFile();
87+
}
88+
89+
void IncrementalAction::CacheCodeGenModule() {
90+
CachedInCodeGenModule = GenModule();
91+
}
92+
93+
llvm::Module *IncrementalAction::getCachedCodeGenModule() const {
94+
return CachedInCodeGenModule.get();
95+
}
96+
97+
std::unique_ptr<llvm::Module> IncrementalAction::GenModule() {
98+
static unsigned ID = 0;
99+
if (CodeGenerator *CG = getCodeGen()) {
100+
// Clang's CodeGen is designed to work with a single llvm::Module. In many
101+
// cases for convenience various CodeGen parts have a reference to the
102+
// llvm::Module (TheModule or Module) which does not change when a new
103+
// module is pushed. However, the execution engine wants to take ownership
104+
// of the module which does not map well to CodeGen's design. To work this
105+
// around we created an empty module to make CodeGen happy. We should make
106+
// sure it always stays empty.
107+
assert(((!CachedInCodeGenModule ||
108+
!CI.getPreprocessorOpts().Includes.empty()) ||
109+
(CachedInCodeGenModule->empty() &&
110+
CachedInCodeGenModule->global_empty() &&
111+
CachedInCodeGenModule->alias_empty() &&
112+
CachedInCodeGenModule->ifunc_empty())) &&
113+
"CodeGen wrote to a readonly module");
114+
std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
115+
CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
116+
return M;
117+
}
118+
return nullptr;
119+
}
120+
121+
CodeGenerator *IncrementalAction::getCodeGen() const {
122+
FrontendAction *WrappedAct = getWrapped();
123+
if (!WrappedAct || !WrappedAct->hasIRSupport())
124+
return nullptr;
125+
return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
126+
}
127+
128+
InProcessPrintingASTConsumer::InProcessPrintingASTConsumer(
129+
std::unique_ptr<ASTConsumer> C, Interpreter &I)
130+
: MultiplexConsumer(std::move(C)), Interp(I) {}
131+
132+
bool InProcessPrintingASTConsumer::HandleTopLevelDecl(DeclGroupRef DGR) {
133+
if (DGR.isNull())
134+
return true;
135+
136+
for (Decl *D : DGR)
137+
if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(D))
138+
if (TLSD && TLSD->isSemiMissing()) {
139+
auto ExprOrErr = Interp.convertExprToValue(cast<Expr>(TLSD->getStmt()));
140+
if (llvm::Error E = ExprOrErr.takeError()) {
141+
llvm::logAllUnhandledErrors(std::move(E), llvm::errs(),
142+
"Value printing failed: ");
143+
return false; // abort parsing
144+
}
145+
TLSD->setStmt(*ExprOrErr);
146+
}
147+
148+
return MultiplexConsumer::HandleTopLevelDecl(DGR);
149+
}
150+
151+
} // namespace clang
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
10+
#define LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H
11+
12+
#include "clang/Frontend/FrontendActions.h"
13+
#include "clang/Frontend/MultiplexConsumer.h"
14+
15+
namespace llvm {
16+
class Module;
17+
}
18+
19+
namespace clang {
20+
21+
class Interpreter;
22+
class CodeGenerator;
23+
24+
/// A custom action enabling the incremental processing functionality.
25+
///
26+
/// The usual \p FrontendAction expects one call to ExecuteAction and once it
27+
/// sees a call to \p EndSourceFile it deletes some of the important objects
28+
/// such as \p Preprocessor and \p Sema assuming no further input will come.
29+
///
30+
/// \p IncrementalAction ensures it keep its underlying action's objects alive
31+
/// as long as the \p IncrementalParser needs them.
32+
///
33+
class IncrementalAction : public WrapperFrontendAction {
34+
private:
35+
bool IsTerminating = false;
36+
Interpreter &Interp;
37+
CompilerInstance &CI;
38+
std::unique_ptr<ASTConsumer> Consumer;
39+
40+
/// When CodeGen is created the first llvm::Module gets cached in many places
41+
/// and we must keep it alive.
42+
std::unique_ptr<llvm::Module> CachedInCodeGenModule;
43+
44+
public:
45+
IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
46+
llvm::Error &Err, Interpreter &I,
47+
std::unique_ptr<ASTConsumer> Consumer = nullptr);
48+
49+
FrontendAction *getWrapped() const { return WrappedAction.get(); }
50+
51+
TranslationUnitKind getTranslationUnitKind() override {
52+
return TU_Incremental;
53+
}
54+
55+
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
56+
StringRef InFile) override;
57+
58+
void ExecuteAction() override;
59+
60+
// Do not terminate after processing the input. This allows us to keep various
61+
// clang objects alive and to incrementally grow the current TU.
62+
void EndSourceFile() override;
63+
64+
void FinalizeAction();
65+
66+
/// Cache the current CodeGen module to preserve internal references.
67+
void CacheCodeGenModule();
68+
69+
/// Access the cached CodeGen module.
70+
llvm::Module *getCachedCodeGenModule() const;
71+
72+
/// Access the current code generator.
73+
CodeGenerator *getCodeGen() const;
74+
75+
/// Generate an LLVM module for the most recent parsed input.
76+
std::unique_ptr<llvm::Module> GenModule();
77+
};
78+
79+
class InProcessPrintingASTConsumer final : public MultiplexConsumer {
80+
Interpreter &Interp;
81+
82+
public:
83+
InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I);
84+
85+
bool HandleTopLevelDecl(DeclGroupRef DGR) override;
86+
};
87+
88+
} // end namespace clang
89+
90+
#endif // LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H

0 commit comments

Comments
 (0)