-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[clang-repl] Delegate CodeGen related operations for PTU to IncrementalParser #137458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
1d773de
Delegate CodeGen related operations for PTU to IncrementalParser
anutosh491 44cd370
move codegen related operations to incrementalaction clas
anutosh491 a646940
Merge branch 'main' into cuda2
anutosh491 046549f
Fix CI
anutosh491 16aa6ef
formatting
anutosh491 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "IncrementalAction.h" | ||
|
||
#include "clang/AST/ASTConsumer.h" | ||
#include "clang/CodeGen/CodeGenAction.h" | ||
#include "clang/CodeGen/ModuleBuilder.h" | ||
#include "clang/Frontend/CompilerInstance.h" | ||
#include "clang/Frontend/FrontendOptions.h" | ||
#include "clang/FrontendTool/Utils.h" | ||
#include "clang/Interpreter/Interpreter.h" | ||
#include "clang/Lex/PreprocessorOptions.h" | ||
#include "clang/Sema/Sema.h" | ||
#include "llvm/IR/Module.h" | ||
#include "llvm/Support/Error.h" | ||
#include "llvm/Support/ErrorHandling.h" | ||
|
||
namespace clang { | ||
IncrementalAction::IncrementalAction(CompilerInstance &CI, | ||
llvm::LLVMContext &LLVMCtx, | ||
llvm::Error &Err, Interpreter &I, | ||
std::unique_ptr<ASTConsumer> Consumer) | ||
: WrapperFrontendAction([&]() { | ||
llvm::ErrorAsOutParameter EAO(&Err); | ||
std::unique_ptr<FrontendAction> Act; | ||
switch (CI.getFrontendOpts().ProgramAction) { | ||
default: | ||
Err = llvm::createStringError( | ||
std::errc::state_not_recoverable, | ||
"Driver initialization failed. " | ||
"Incremental mode for action %d is not supported", | ||
CI.getFrontendOpts().ProgramAction); | ||
return Act; | ||
case frontend::ASTDump: | ||
case frontend::ASTPrint: | ||
case frontend::ParseSyntaxOnly: | ||
Act = CreateFrontendAction(CI); | ||
break; | ||
case frontend::PluginAction: | ||
case frontend::EmitAssembly: | ||
case frontend::EmitBC: | ||
case frontend::EmitObj: | ||
case frontend::PrintPreprocessedInput: | ||
case frontend::EmitLLVMOnly: | ||
Act.reset(new EmitLLVMOnlyAction(&LLVMCtx)); | ||
break; | ||
} | ||
return Act; | ||
}()), | ||
Interp(I), CI(CI), Consumer(std::move(Consumer)) {} | ||
|
||
std::unique_ptr<ASTConsumer> | ||
IncrementalAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { | ||
std::unique_ptr<ASTConsumer> C = | ||
WrapperFrontendAction::CreateASTConsumer(CI, InFile); | ||
|
||
if (Consumer) { | ||
std::vector<std::unique_ptr<ASTConsumer>> Cs; | ||
Cs.push_back(std::move(Consumer)); | ||
Cs.push_back(std::move(C)); | ||
return std::make_unique<MultiplexConsumer>(std::move(Cs)); | ||
} | ||
|
||
return std::make_unique<InProcessPrintingASTConsumer>(std::move(C), Interp); | ||
} | ||
|
||
void IncrementalAction::ExecuteAction() { | ||
WrapperFrontendAction::ExecuteAction(); | ||
getCompilerInstance().getSema().CurContext = nullptr; | ||
} | ||
|
||
void IncrementalAction::EndSourceFile() { | ||
if (IsTerminating && getWrapped()) | ||
WrapperFrontendAction::EndSourceFile(); | ||
} | ||
|
||
void IncrementalAction::FinalizeAction() { | ||
assert(!IsTerminating && "Already finalized!"); | ||
IsTerminating = true; | ||
EndSourceFile(); | ||
} | ||
|
||
void IncrementalAction::CacheCodeGenModule() { | ||
CachedInCodeGenModule = GenModule(); | ||
} | ||
|
||
llvm::Module *IncrementalAction::getCachedCodeGenModule() const { | ||
return CachedInCodeGenModule.get(); | ||
} | ||
|
||
std::unique_ptr<llvm::Module> IncrementalAction::GenModule() { | ||
static unsigned ID = 0; | ||
if (CodeGenerator *CG = getCodeGen()) { | ||
// Clang's CodeGen is designed to work with a single llvm::Module. In many | ||
// cases for convenience various CodeGen parts have a reference to the | ||
// llvm::Module (TheModule or Module) which does not change when a new | ||
// module is pushed. However, the execution engine wants to take ownership | ||
// of the module which does not map well to CodeGen's design. To work this | ||
// around we created an empty module to make CodeGen happy. We should make | ||
// sure it always stays empty. | ||
assert(((!CachedInCodeGenModule || | ||
!CI.getPreprocessorOpts().Includes.empty()) || | ||
(CachedInCodeGenModule->empty() && | ||
CachedInCodeGenModule->global_empty() && | ||
CachedInCodeGenModule->alias_empty() && | ||
CachedInCodeGenModule->ifunc_empty())) && | ||
"CodeGen wrote to a readonly module"); | ||
std::unique_ptr<llvm::Module> M(CG->ReleaseModule()); | ||
CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext()); | ||
return M; | ||
} | ||
return nullptr; | ||
} | ||
|
||
CodeGenerator *IncrementalAction::getCodeGen() const { | ||
FrontendAction *WrappedAct = getWrapped(); | ||
if (!WrappedAct || !WrappedAct->hasIRSupport()) | ||
return nullptr; | ||
return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator(); | ||
} | ||
|
||
InProcessPrintingASTConsumer::InProcessPrintingASTConsumer( | ||
std::unique_ptr<ASTConsumer> C, Interpreter &I) | ||
: MultiplexConsumer(std::move(C)), Interp(I) {} | ||
|
||
bool InProcessPrintingASTConsumer::HandleTopLevelDecl(DeclGroupRef DGR) { | ||
if (DGR.isNull()) | ||
return true; | ||
|
||
for (Decl *D : DGR) | ||
if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(D)) | ||
if (TLSD && TLSD->isSemiMissing()) { | ||
auto ExprOrErr = Interp.convertExprToValue(cast<Expr>(TLSD->getStmt())); | ||
if (llvm::Error E = ExprOrErr.takeError()) { | ||
llvm::logAllUnhandledErrors(std::move(E), llvm::errs(), | ||
"Value printing failed: "); | ||
return false; // abort parsing | ||
} | ||
TLSD->setStmt(*ExprOrErr); | ||
} | ||
|
||
return MultiplexConsumer::HandleTopLevelDecl(DGR); | ||
} | ||
|
||
} // namespace clang |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
//===--- IncrementalAction.h - Incremental Frontend Action -*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H | ||
#define LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H | ||
|
||
#include "clang/Frontend/FrontendActions.h" | ||
#include "clang/Frontend/MultiplexConsumer.h" | ||
|
||
namespace llvm { | ||
class Module; | ||
} | ||
|
||
namespace clang { | ||
|
||
class Interpreter; | ||
class CodeGenerator; | ||
|
||
/// A custom action enabling the incremental processing functionality. | ||
/// | ||
/// The usual \p FrontendAction expects one call to ExecuteAction and once it | ||
/// sees a call to \p EndSourceFile it deletes some of the important objects | ||
/// such as \p Preprocessor and \p Sema assuming no further input will come. | ||
/// | ||
/// \p IncrementalAction ensures it keep its underlying action's objects alive | ||
/// as long as the \p IncrementalParser needs them. | ||
/// | ||
class IncrementalAction : public WrapperFrontendAction { | ||
private: | ||
bool IsTerminating = false; | ||
Interpreter &Interp; | ||
CompilerInstance &CI; | ||
std::unique_ptr<ASTConsumer> Consumer; | ||
|
||
/// When CodeGen is created the first llvm::Module gets cached in many places | ||
/// and we must keep it alive. | ||
std::unique_ptr<llvm::Module> CachedInCodeGenModule; | ||
|
||
public: | ||
IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx, | ||
llvm::Error &Err, Interpreter &I, | ||
std::unique_ptr<ASTConsumer> Consumer = nullptr); | ||
|
||
FrontendAction *getWrapped() const { return WrappedAction.get(); } | ||
|
||
TranslationUnitKind getTranslationUnitKind() override { | ||
return TU_Incremental; | ||
} | ||
|
||
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, | ||
StringRef InFile) override; | ||
|
||
void ExecuteAction() override; | ||
|
||
// Do not terminate after processing the input. This allows us to keep various | ||
// clang objects alive and to incrementally grow the current TU. | ||
void EndSourceFile() override; | ||
|
||
void FinalizeAction(); | ||
|
||
/// Cache the current CodeGen module to preserve internal references. | ||
void CacheCodeGenModule(); | ||
|
||
/// Access the cached CodeGen module. | ||
llvm::Module *getCachedCodeGenModule() const; | ||
|
||
/// Access the current code generator. | ||
CodeGenerator *getCodeGen() const; | ||
|
||
/// Generate an LLVM module for the most recent parsed input. | ||
std::unique_ptr<llvm::Module> GenModule(); | ||
}; | ||
|
||
class InProcessPrintingASTConsumer final : public MultiplexConsumer { | ||
Interpreter &Interp; | ||
|
||
public: | ||
InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I); | ||
|
||
bool HandleTopLevelDecl(DeclGroupRef DGR) override; | ||
}; | ||
|
||
} // end namespace clang | ||
|
||
#endif // LLVM_CLANG_INTERPRETER_INCREMENTALACTION_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.