Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc] Add a tool called WrapperGen.
This tool will be used to generate C wrappers for the C++ LLVM libc implementations. This change does not hook this tool up to anything yet. However, it can be useful for cases where one does not want to run the objcopy step (to insert the C symbol in the object file) but can make use of LTO to eliminate the cost of the additional wrapper call. This can be relevant for certain downstream platforms. If this tool can benefit other libc platforms in general, then it can be integrated into the build system with options to use or not use the wrappers. An example of such a platform is CUDA. Reviewed By: abrachet Differential Revision: https://reviews.llvm.org/D84848
- Loading branch information
Siva Chandra Reddy
committed
Jul 30, 2020
1 parent
8dfb5d7
commit a32af82
Showing
6 changed files
with
87 additions
and
2 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 @@ | ||
add_subdirectory(WrapperGen) |
This file contains 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,8 @@ | ||
set(LLVM_LINK_COMPONENTS Support) | ||
|
||
add_tablegen(libc-wrappergen llvm-libc | ||
Main.cpp | ||
) | ||
|
||
target_include_directories(libc-wrappergen PRIVATE ${LIBC_SOURCE_DIR}) | ||
target_link_libraries(libc-wrappergen PRIVATE LibcTableGenUtil) |
This file contains 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,72 @@ | ||
//===-- "main" function of libc-wrappergen --------------------------------===// | ||
// | ||
// 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 "utils/LibcTableGenUtil/APIIndexer.h" | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/Support/CommandLine.h" | ||
#include "llvm/TableGen/Error.h" | ||
#include "llvm/TableGen/Main.h" | ||
|
||
#include <sstream> | ||
#include <string> | ||
|
||
llvm::cl::opt<std::string> | ||
FunctionName("name", llvm::cl::desc("Name of the function to be wrapped."), | ||
llvm::cl::value_desc("<function name>"), llvm::cl::Required); | ||
|
||
static bool WrapperGenMain(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) { | ||
llvm_libc::APIIndexer Indexer(Records); | ||
auto Iter = Indexer.FunctionSpecMap.find(FunctionName); | ||
if (Iter == Indexer.FunctionSpecMap.end()) { | ||
llvm::PrintFatalError("Function '" + FunctionName + | ||
"' not found in any standard spec."); | ||
} | ||
|
||
// To avoid all confusion, we include the implementation header using the | ||
// full path (relative the libc directory.) | ||
std::string Header = Indexer.FunctionToHeaderMap[FunctionName]; | ||
auto RelPath = llvm::StringRef(Header).drop_back(2); // Drop the ".h" suffix. | ||
OS << "#include \"src/" << RelPath << "/" << FunctionName << ".h\"\n"; | ||
|
||
auto &NameSpecPair = *Iter; | ||
llvm::Record *FunctionSpec = NameSpecPair.second; | ||
llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return"); | ||
llvm::Record *ReturnType = RetValSpec->getValueAsDef("ReturnType"); | ||
OS << "extern \"C\" " << Indexer.getTypeAsString(ReturnType) << " " | ||
<< FunctionName << "("; | ||
|
||
auto ArgsList = FunctionSpec->getValueAsListOfDefs("Args"); | ||
std::stringstream CallArgs; | ||
std::string ArgPrefix("__arg"); | ||
for (size_t i = 0; i < ArgsList.size(); ++i) { | ||
llvm::Record *ArgType = ArgsList[i]->getValueAsDef("ArgType"); | ||
auto TypeName = Indexer.getTypeAsString(ArgType); | ||
OS << TypeName << " " << ArgPrefix << i; | ||
CallArgs << ArgPrefix << i; | ||
if (i < ArgsList.size() - 1) { | ||
OS << ", "; | ||
CallArgs << ", "; | ||
} | ||
} | ||
|
||
// TODO: Arg types of the C++ implementation functions need not | ||
// match the standard types. Either handle such differences here, or | ||
// avoid such a thing in the implementations. | ||
OS << ") {\n" | ||
<< " return __llvm_libc::" << FunctionName << "(" << CallArgs.str() | ||
<< ");\n" | ||
<< "}\n"; | ||
|
||
return false; | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
llvm::cl::ParseCommandLineOptions(argc, argv); | ||
return TableGenMain(argv[0], WrapperGenMain); | ||
} |