summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2017-02-11 21:26:52 +0000
committerMehdi Amini <mehdi.amini@apple.com>2017-02-11 21:26:52 +0000
commite0ae1eda9ceb406ff1171393b29701f3771dacac (patch)
treef9ce29d8f2140934e51a98f3d98cc94b7570c064 /examples
parentc0358c4bfefdd94a969751db53c5e85b6bc3b931 (diff)
Update Kaleidoscope tutorial and improve Windows support
Many quoted code blocks were not in sync with the actual toy.cpp files. Improve tutorial text slightly in several places. Added some step descriptions crucial to avoid crashes (like InitializeNativeTarget* calls). Solve/workaround problems with Windows (JIT'ed method not found, using custom and standard library functions from host process). Patch by: Moritz Kroll <moritz.kroll@gmx.de> Differential Revision: https://reviews.llvm.org/D29864 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294870 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'examples')
-rw-r--r--examples/Kaleidoscope/Chapter2/toy.cpp2
-rw-r--r--examples/Kaleidoscope/Chapter4/toy.cpp10
-rw-r--r--examples/Kaleidoscope/Chapter5/toy.cpp14
-rw-r--r--examples/Kaleidoscope/Chapter6/toy.cpp16
-rw-r--r--examples/Kaleidoscope/Chapter7/toy.cpp18
-rw-r--r--examples/Kaleidoscope/Chapter8/toy.cpp16
-rw-r--r--examples/Kaleidoscope/Chapter9/toy.cpp16
-rw-r--r--examples/Kaleidoscope/include/KaleidoscopeJIT.h25
8 files changed, 90 insertions, 27 deletions
diff --git a/examples/Kaleidoscope/Chapter2/toy.cpp b/examples/Kaleidoscope/Chapter2/toy.cpp
index 8357c5b63fb..4dc917e3f06 100644
--- a/examples/Kaleidoscope/Chapter2/toy.cpp
+++ b/examples/Kaleidoscope/Chapter2/toy.cpp
@@ -140,6 +140,8 @@ class PrototypeAST {
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
: Name(Name), Args(std::move(Args)) {}
+
+ const std::string &getName() const { return Name; }
};
/// FunctionAST - This class represents a function definition itself.
diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp
index 3bd077b6e38..cf7d6c2bee0 100644
--- a/examples/Kaleidoscope/Chapter4/toy.cpp
+++ b/examples/Kaleidoscope/Chapter4/toy.cpp
@@ -650,14 +650,20 @@ static void MainLoop() {
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
+#ifdef LLVM_ON_WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
/// putchard - putchar that takes a double and returns 0.
-extern "C" double putchard(double X) {
+extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C" double printd(double X) {
+extern "C" DLLEXPORT double printd(double X) {
fprintf(stderr, "%f\n", X);
return 0;
}
diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp
index 795f49c847e..6852973bae4 100644
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -622,7 +622,7 @@ Value *IfExprAST::codegen() {
if (!CondV)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
@@ -736,7 +736,7 @@ Value *ForExprAST::codegen() {
if (!EndCond)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
@@ -924,14 +924,20 @@ static void MainLoop() {
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
+#ifdef LLVM_ON_WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
/// putchard - putchar that takes a double and returns 0.
-extern "C" double putchard(double X) {
+extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C" double printd(double X) {
+extern "C" DLLEXPORT double printd(double X) {
fprintf(stderr, "%f\n", X);
return 0;
}
diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp
index 19e25d37dcd..1e0ddca29b6 100644
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -567,7 +567,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return LogErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedence: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -734,7 +734,7 @@ Value *IfExprAST::codegen() {
if (!CondV)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
@@ -848,7 +848,7 @@ Value *ForExprAST::codegen() {
if (!EndCond)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
@@ -1043,14 +1043,20 @@ static void MainLoop() {
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
+#ifdef LLVM_ON_WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
/// putchard - putchar that takes a double and returns 0.
-extern "C" double putchard(double X) {
+extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C" double printd(double X) {
+extern "C" DLLEXPORT double printd(double X) {
fprintf(stderr, "%f\n", X);
return 0;
}
diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp
index 7e723ba0397..2f8cb682a84 100644
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -639,7 +639,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return LogErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedence: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -840,7 +840,7 @@ Value *IfExprAST::codegen() {
if (!CondV)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
@@ -963,7 +963,7 @@ Value *ForExprAST::codegen() {
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
@@ -1115,6 +1115,8 @@ static void InitializeModuleAndPassManager() {
// Create a new pass manager attached to it.
TheFPM = llvm::make_unique<legacy::FunctionPassManager>(TheModule.get());
+ // Promote allocas to registers.
+ TheFPM->add(createPromoteMemoryToRegisterPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
TheFPM->add(createInstructionCombiningPass());
// Reassociate expressions.
@@ -1210,14 +1212,20 @@ static void MainLoop() {
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
+#ifdef LLVM_ON_WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
/// putchard - putchar that takes a double and returns 0.
-extern "C" double putchard(double X) {
+extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C" double printd(double X) {
+extern "C" DLLEXPORT double printd(double X) {
fprintf(stderr, "%f\n", X);
return 0;
}
diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp
index 354380adfc4..cdf650973b8 100644
--- a/examples/Kaleidoscope/Chapter8/toy.cpp
+++ b/examples/Kaleidoscope/Chapter8/toy.cpp
@@ -642,7 +642,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return LogErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedence: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -841,7 +841,7 @@ Value *IfExprAST::codegen() {
if (!CondV)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
@@ -964,7 +964,7 @@ Value *ForExprAST::codegen() {
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
@@ -1173,14 +1173,20 @@ static void MainLoop() {
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
+#ifdef LLVM_ON_WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
/// putchard - putchar that takes a double and returns 0.
-extern "C" double putchard(double X) {
+extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C" double printd(double X) {
+extern "C" DLLEXPORT double printd(double X) {
fprintf(stderr, "%f\n", X);
return 0;
}
diff --git a/examples/Kaleidoscope/Chapter9/toy.cpp b/examples/Kaleidoscope/Chapter9/toy.cpp
index aa609933fc9..1b13e45ec46 100644
--- a/examples/Kaleidoscope/Chapter9/toy.cpp
+++ b/examples/Kaleidoscope/Chapter9/toy.cpp
@@ -756,7 +756,7 @@ static std::unique_ptr<PrototypeAST> ParsePrototype() {
// Read the precedence if present.
if (CurTok == tok_number) {
if (NumVal < 1 || NumVal > 100)
- return LogErrorP("Invalid precedecnce: must be 1..100");
+ return LogErrorP("Invalid precedence: must be 1..100");
BinaryPrecedence = (unsigned)NumVal;
getNextToken();
}
@@ -1004,7 +1004,7 @@ Value *IfExprAST::codegen() {
if (!CondV)
return nullptr;
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
CondV = Builder.CreateFCmpONE(
CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
@@ -1129,7 +1129,7 @@ Value *ForExprAST::codegen() {
Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar");
Builder.CreateStore(NextVar, Alloca);
- // Convert condition to a bool by comparing equal to 0.0.
+ // Convert condition to a bool by comparing non-equal to 0.0.
EndCond = Builder.CreateFCmpONE(
EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
@@ -1379,14 +1379,20 @@ static void MainLoop() {
// "Library" functions that can be "extern'd" from user code.
//===----------------------------------------------------------------------===//
+#ifdef LLVM_ON_WIN32
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
/// putchard - putchar that takes a double and returns 0.
-extern "C" double putchard(double X) {
+extern "C" DLLEXPORT double putchard(double X) {
fputc((char)X, stderr);
return 0;
}
/// printd - printf that takes a double prints it as "%f\n", returning 0.
-extern "C" double printd(double X) {
+extern "C" DLLEXPORT double printd(double X) {
fprintf(stderr, "%f\n", X);
return 0;
}
diff --git a/examples/Kaleidoscope/include/KaleidoscopeJIT.h b/examples/Kaleidoscope/include/KaleidoscopeJIT.h
index 6130107bdd9..77e21bb4aeb 100644
--- a/examples/Kaleidoscope/include/KaleidoscopeJIT.h
+++ b/examples/Kaleidoscope/include/KaleidoscopeJIT.h
@@ -97,17 +97,40 @@ private:
}
JITSymbol findMangledSymbol(const std::string &Name) {
+#ifdef LLVM_ON_WIN32
+ // The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported
+ // flag to decide whether a symbol will be visible or not, when we call
+ // IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true.
+ //
+ // But for Windows COFF objects, this flag is currently never set.
+ // For a potential solution see: https://reviews.llvm.org/rL258665
+ // For now, we allow non-exported symbols on Windows as a workaround.
+ const bool ExportedSymbolsOnly = false;
+#else
+ const bool ExportedSymbolsOnly = true;
+#endif
+
// Search modules in reverse order: from last added to first added.
// This is the opposite of the usual search order for dlsym, but makes more
// sense in a REPL where we want to bind to the newest available definition.
for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend()))
- if (auto Sym = CompileLayer.findSymbolIn(H, Name, true))
+ if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))
return Sym;
// If we can't find the symbol in the JIT, try looking in the host process.
if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
+#ifdef LLVM_ON_WIN32
+ // For Windows retry without "_" at begining, as RTDyldMemoryManager uses
+ // GetProcAddress and standard libraries like msvcrt.dll use names
+ // with and without "_" (for example "_itoa" but "sin").
+ if (Name.length() > 2 && Name[0] == '_')
+ if (auto SymAddr =
+ RTDyldMemoryManager::getSymbolAddressInProcess(Name.substr(1)))
+ return JITSymbol(SymAddr, JITSymbolFlags::Exported);
+#endif
+
return nullptr;
}