[HIPIFY][#1435] Add HIP_SYMBOL wrapper to the templated Device Symbol argument of the following functions:

cudaMemcpyToSymbol, cudaMemcpyToSymbolAsync, cudaGetSymbolSize, cudaGetSymbolAddress, cudaMemcpyFromSymbol, cudaMemcpyFromSymbolAsync

+ Add a corresponding cudaSymbolFuncCall matcher.
+ Add device_symbols.cu test for the above 6 functions, update existed.
+ Fix dim3() type cast issue, update affected tests.

TODO: Do the same in hipify-perl


[ROCm/hip commit: 3722d5b4b9]
This commit is contained in:
Evgeny Mankov
2019-09-19 19:33:42 +03:00
parent 8f1d12360d
commit 0504e85f02
5 changed files with 241 additions and 5 deletions
+85 -2
View File
@@ -20,6 +20,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <algorithm>
#include <set>
#include "HipifyAction.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Frontend/CompilerInstance.h"
@@ -34,6 +36,25 @@ THE SOFTWARE.
namespace ct = clang::tooling;
namespace mat = clang::ast_matchers;
const std::string sCudaMemcpyToSymbol = "cudaMemcpyToSymbol";
const std::string sCudaMemcpyToSymbolAsync = "cudaMemcpyToSymbolAsync";
const std::string sCudaGetSymbolSize = "cudaGetSymbolSize";
const std::string sCudaGetSymbolAddress = "cudaGetSymbolAddress";
const std::string sCudaMemcpyFromSymbol = "cudaMemcpyFromSymbol";
const std::string sCudaMemcpyFromSymbolAsync = "cudaMemcpyFromSymbolAsync";
const std::set<std::string> DeviceSymbolFunctions0 {
{sCudaMemcpyToSymbol},
{sCudaMemcpyToSymbolAsync}
};
const std::set<std::string> DeviceSymbolFunctions1 {
{sCudaGetSymbolSize},
{sCudaGetSymbolAddress},
{sCudaMemcpyFromSymbol},
{sCudaMemcpyFromSymbolAsync}
};
void HipifyAction::RewriteString(StringRef s, clang::SourceLocation start) {
clang::SourceManager& SM = getCompilerInstance().getSourceManager();
size_t begin = 0;
@@ -316,8 +337,12 @@ bool HipifyAction::cudaLaunchKernel(const clang::ast_matchers::MatchFinder::Matc
// Next up are the four kernel configuration parameters, the last two of which are optional and default to zero.
// Copy the two dimensional arguments verbatim.
OS << "dim3(" << readSourceText(*SM, config->getArg(0)->getSourceRange()) << "), ";
OS << "dim3(" << readSourceText(*SM, config->getArg(1)->getSourceRange()) << "), ";
std::string sDim3 = "dim3(";
for (unsigned int i = 0; i < 2; ++i) {
const std::string sArg = readSourceText(*SM, config->getArg(i)->getSourceRange()).str();
bool bDim3 = std::equal(sDim3.begin(), sDim3.end(), sArg.c_str());
OS << (bDim3 ? "" : sDim3) << sArg << (bDim3 ? "" : ")") << ", ";
}
// The stream/memory arguments default to zero if omitted.
OS << stringifyZeroDefaultedArg(*SM, config->getArg(2)) << ", ";
OS << stringifyZeroDefaultedArg(*SM, config->getArg(3));
@@ -395,11 +420,50 @@ bool HipifyAction::cudaSharedIncompleteArrayVar(const clang::ast_matchers::Match
bool HipifyAction::cudaDeviceFuncCall(const clang::ast_matchers::MatchFinder::MatchResult& Result) {
if (const clang::CallExpr *call = Result.Nodes.getNodeAs<clang::CallExpr>("cudaDeviceFuncCall")) {
const clang::FunctionDecl *funcDcl = call->getDirectCallee();
if (!funcDcl) {
return true;
}
FindAndReplace(funcDcl->getDeclName().getAsString(), llcompat::getBeginLoc(call), CUDA_DEVICE_FUNC_MAP, false);
}
return true;
}
bool HipifyAction::cudaSymbolFuncCall(const clang::ast_matchers::MatchFinder::MatchResult& Result) {
if (const clang::CallExpr * call = Result.Nodes.getNodeAs<clang::CallExpr>("cudaSymbolFuncCall")) {
if (!call->getNumArgs()) {
return true;
}
const clang::FunctionDecl* funcDcl = call->getDirectCallee();
if (!funcDcl) {
return true;
}
std::string sName = funcDcl->getDeclName().getAsString();
unsigned int argNum = 0;
if (DeviceSymbolFunctions0.find(sName) != DeviceSymbolFunctions0.end()) {
argNum = 0;
} else if (call->getNumArgs() > 1 && DeviceSymbolFunctions1.find(sName) != DeviceSymbolFunctions1.end()) {
argNum = 1;
} else {
return true;
}
clang::SmallString<40> XStr;
llvm::raw_svector_ostream OS(XStr);
clang::SourceRange sr = call->getArg(argNum)->getSourceRange();
clang::SourceManager* SM = Result.SourceManager;
const std::string sSymbol = "HIP_SYMBOL";
OS << sSymbol << "(" << readSourceText(*SM, sr) << ")";
clang::SourceRange replacementRange = getWriteRange(*SM, { sr.getBegin(), sr.getEnd() });
clang::SourceLocation s = replacementRange.getBegin();
clang::SourceLocation e = replacementRange.getEnd();
clang::LangOptions DefaultLangOptions;
size_t length = SM->getCharacterData(clang::Lexer::getLocForEndOfToken(e, 0, *SM, DefaultLangOptions)) - SM->getCharacterData(s);
ct::Replacement Rep(*SM, s, length, OS.str());
clang::FullSourceLoc fullSL(s, *SM);
insertReplacement(Rep, fullSL);
}
return true;
}
void HipifyAction::insertReplacement(const ct::Replacement& rep, const clang::FullSourceLoc& fullSL) {
llcompat::insertReplacement(*replacements, rep);
if (PrintStats) {
@@ -423,6 +487,24 @@ std::unique_ptr<clang::ASTConsumer> HipifyAction::CreateASTConsumer(clang::Compi
).bind("cudaSharedIncompleteArrayVar"),
this
);
Finder->addMatcher(
mat::callExpr(
mat::isExpansionInMainFile(),
mat::callee(
mat::functionDecl(
mat::hasAnyName(
sCudaGetSymbolAddress,
sCudaGetSymbolSize,
sCudaMemcpyFromSymbol,
sCudaMemcpyFromSymbolAsync,
sCudaMemcpyToSymbol,
sCudaMemcpyToSymbolAsync
)
)
)
).bind("cudaSymbolFuncCall"),
this
);
Finder->addMatcher(
mat::callExpr(
mat::isExpansionInMainFile(),
@@ -560,5 +642,6 @@ void HipifyAction::ExecuteAction() {
void HipifyAction::run(const clang::ast_matchers::MatchFinder::MatchResult& Result) {
if (cudaLaunchKernel(Result)) return;
if (cudaSharedIncompleteArrayVar(Result)) return;
if (cudaSymbolFuncCall(Result)) return;
if (cudaDeviceFuncCall(Result)) return;
}
@@ -71,6 +71,7 @@ public:
bool cudaLaunchKernel(const clang::ast_matchers::MatchFinder::MatchResult& Result);
bool cudaSharedIncompleteArrayVar(const clang::ast_matchers::MatchFinder::MatchResult& Result);
bool cudaDeviceFuncCall(const clang::ast_matchers::MatchFinder::MatchResult& Result);
bool cudaSymbolFuncCall(const clang::ast_matchers::MatchFinder::MatchResult& Result);
// Called by the preprocessor for each include directive during the non-raw lexing pass.
void InclusionDirective(clang::SourceLocation hash_loc,
const clang::Token &include_token,