The CUDA compiler can handle variable declarations from the prompt.

Now, it is possible to declare variables on the prompt, which are visible for other statements.

The problems was, that cling wrapped all statements in a function, to get valid input. So, every variable is just visible inside in its own wrapper function. To solve the problem, cling change the local variable declaration to a global declaration.

The implementation for the CUDA compiler checks, if the unwrapping is happened. If it happened, the c++ code of the unwrapped variable declaration (AST-printer) instead the raw input will be written to the .cu-file.
This commit is contained in:
Simeon Ehrig 2018-03-27 17:19:50 +02:00 committed by sftnight
parent c18f074cbd
commit eb5cfc5f3f
3 changed files with 38 additions and 6 deletions

View File

@ -10,10 +10,13 @@
#include "IncrementalCUDADeviceCompiler.h"
#include "cling/Interpreter/InvocationOptions.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/Paths.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/Decl.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
@ -163,7 +166,8 @@ namespace cling {
}
}
bool IncrementalCUDADeviceCompiler::generateFatbinary(llvm::StringRef input){
bool IncrementalCUDADeviceCompiler::generateFatbinary(llvm::StringRef input,
cling::Transaction * T){
if(!m_Init){
llvm::errs() << "Error: Initializiation of CUDA Device Code Compiler failed\n";
return false;
@ -177,7 +181,33 @@ namespace cling {
llvm::errs() << "Could not open file: " << EC.message();
return false;
}
cuFile << input;
// This variable prevent, that the input and the code from the transaction
// will be written to the .cu-file.
bool foundVarDecl = false;
// Search after variable declarations. The conditions are, that the
// source code comes from the prompt (getWrapperFD()) and has a variable
// declaration.
if(T != nullptr && T->getWrapperFD()){
for(auto iDCI = T->decls_begin(), eDCI = T->decls_end();
iDCI != eDCI; ++iDCI){
for (clang::DeclGroupRef::const_iterator iDecl = iDCI->m_DGR.begin(),
eDecl = iDCI->m_DGR.end();
iDecl != eDecl; ++iDecl) {
if(clang::VarDecl * v = llvm::dyn_cast<clang::VarDecl>(*iDecl)){
foundVarDecl = true;
v->print(cuFile);
// The c++ code has no whitespace and semicolon at the end.
cuFile << ";\n";
}
}
}
}
if(!foundVarDecl){
cuFile << input;
}
cuFile.close();
if(!generatePCH()){

View File

@ -18,6 +18,7 @@
namespace cling{
class InvocationOptions;
class Transaction;
}
namespace clang {
@ -181,10 +182,11 @@ namespace cling {
///
///\param [in] input - New source code. The function can select, if code
/// is relevant for the device side. Have to be valid CUDA C++ code.
///\param [in] T - Source of c++ code for variable declaration.
///
///\returns True, if all stages of generating fatbin runs right and a new
/// fatbin file is written.
bool generateFatbinary(llvm::StringRef input);
bool generateFatbinary(llvm::StringRef input, cling::Transaction * T);
///\brief Print some information of the IncrementalCUDADeviceCompiler to
/// llvm::outs(). For Example the paths of the files and tools.

View File

@ -737,9 +737,6 @@ namespace cling {
DiagnosticErrorTrap Trap(Diags);
Sema::SavePendingInstantiationsRAII SavedPendingInstantiations(S);
if(m_CI->getLangOpts().CUDA )
m_Interpreter->getCUDADeviceCompiler().generateFatbinary(input);
Parser::DeclGroupPtrTy ADecl;
while (!m_Parser->ParseTopLevelDecl(ADecl)) {
// If we got a null return and something *was* parsed, ignore it. This
@ -796,6 +793,9 @@ namespace cling {
else if (Diags.getNumWarnings())
return kSuccessWithWarnings;
if(m_CI->getLangOpts().CUDA )
m_Interpreter->getCUDADeviceCompiler().generateFatbinary(input, m_Consumer->getTransaction());
return kSuccess;
}